??? 01/30/07 17:39 Modified: 01/30/07 17:45 Read: times |
#131719 - Interfacing AT89C51ED2 to MAX6957 via SPI |
Hi folks
I'm just starting to take my first steps with SPI, and to be honest I'm struggling. I think I have all the interface issues clear in my head, but there's one thing I'm a little unsure about. The MAX6957 port expander needs 2 bytes to be transferred via SPI. One byte for the register to be changed, and one byte data. The datasheet specifies that 16 bits are shifted in, and then CS is taken high to load the 16 bits into a 16 bit latch. The AT89C51ED2 datasheet and sample code talks about a mov into SPDAT transferring 8 bits across the SPI interface. So I figured if I did 2 movs and then took CS high that would transfer 16 bits then load all 16 bits into the latch (see code below). I can see that the interrupt occurs, and that all the code is processed (using a debugging bit) but it still doesn't seem to set port 22 high. Any suggestions, or does anyone have experience of multi-byte transfers on the Atmel? I'm using a AT89STK-08 dev board (thanks Ian!) so I'm fairly confident that the hardware's sound. ; ; Starting with ATMEL 89C51ED2 and SPI ; ; ; ; ; ; $NOMOD $TITLE(BYTE SPI_TEST) $DEBUG $OBJECT $NOPAGING ;Variable declarations $include(C:\asm51\89C51ED2.inc) SS EQU P1.1 rec_data DATA 08H trans_completed bit 00h org 0000H ljmp MAIN org 4Bh ljmp SPI_INT org 100h MAIN: orl spcon, #10h ;SPI Master setb SS orl spcon, #82h ;Speed xtal/128 anl spcon, #0F7h ;cpol = 1 orl spcon, #04h ;cpha = 1 orl spcon, #20h ;SS disabled orl ien1, #04h ;SPI Interrupt enabled orl spcon, #40h ;run SPI clr trans_completed setb ea ;/////////////////////////////////////////////////////////////// ; ; Set up MAX6957 registers ; clr SS mov SPDAT,#04h ; config register jnb trans_completed,$ ; /* wait end of transmission */ clr trans_completed ; /* clear software transfer flag */ mov SPDAT,#01h ; disable shutdown, global current control, trans det disabled jnb trans_completed,$ ; /* wait end of transmission */ clr trans_completed ; /* clear software transfer flag */ setb SS ; read 2 bytes into SPI slave nop nop nop ; min CS pulse is 19 ns so at 12 MHz one nop should do it clr SS mov SPDAT,#0Dh ; ports 20, 21, 22, 23 config register jnb trans_completed,$ ; /* wait end of transmission */ clr trans_completed ; /* clear software transfer flag */ mov SPDAT,#9Ch ; set port 22 to output jnb trans_completed,$ ; /* wait end of transmission */ clr trans_completed ; /* clear software transfer flag */ setb SS ; read 2 bytes into SPI slave nop nop nop ; min CS pulse is 19 ns so at 12 MHz one nop should do it clr SS ;///////////////////////////////////////////////////////////// ; ; Set port 22 on ; mov SPDAT,#36h ; port 22 jnb trans_completed,$ ; /* wait end of transmission */ clr trans_completed ; /* clear software transfer flag */ mov SPDAT,#01h ; on jnb trans_completed,$ ; /* wait end of transmission */ clr trans_completed ; /* clear software transfer flag */ setb SS clr p2.0 ; Debugging jmp $ ; sit and stay SPI_INT: ; /* interrupt address is 0x004B */ mov R7,SPSTA mov ACC,R7 jnb ACC.7,BREAK1 ;case 0x80: data transfer complete mov rec_data,SPDAT ; /* read receive data */ setb trans_completed ; /* set software flag */ BREAK1: jnb ACC.4,BREAK2 ;case 0x10: Mode fault ; /* put here for mode fault tasking */ BREAK2: jnb ACC.6,BREAK3 ;case 0x40: Write Collision ; /* put here for overrun tasking */ BREAK3: RETI END |