| ??? 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
|



