Postat: 5 november 2005, 22:24:45
bengt-re, helt rätt, CS hanteras separat från själva SPI överföringen, dock är det ingen bra idé att "stänga av" CS mitt i en överföring, vilket verkar vara det som Jimmy gör (eller gjorde
)...

Svenskt forum för elektroniksnack.
https://elektronikforumet.com/forum/
Kod: Markera allt
const CHIP_SELECT = 0
dim value as word
sub procedure Init
TRISA = 0 'TESTLED
PORTA.0 = 0 'TESTLED
PORTA.1 = 0 'TESTLED
PORTA.2 = 0 'TESTLED
PORTA.3 = 0 'TESTLED
TRISB = 0 ' LCD
TRISC.1 = 0 ' LCD
TRISC.2 = 0 ' LCD
PORTB = 0 ' LCD
PORTC.1 = 0 ' LCD
PORTC.2 = 0 ' LCD
ClearBit(TRISC,CHIP_SELECT) ' Utgång på ChipSelect (RC0)
TRISC.3=0 ' Utgång på SCK -Serial Clock- (RC3)
TRISC.5=0 ' Utgång på SDO -Data UT- (RC5)
' TRISC.4=0 ' Genom att göra SDI till en utgång så disablas ingången. (Sid 160 i databladet.)
'Initierar DAC-kretsen (TLV 5618A) --------------
SSPSTAT.SMP=0 ' Input data sampled at the middle of data output time.
SSPSTAT.CKE=1 ' Data tas emot on rising edge of SCK
SSPCON1.WCOL=0 ' Ingen WriteCollisionDetect
SSPCON1.SSPOV=0 ' Ingen ReceiveOverflowIndicator
SSPCON1.SSPEN=1 ' Enable serieport och SCK, SDo, SDI och SS
SSPCON1.CKP=0 ' CKP. Idle state for clock is a low level
SSPCON1.SSPM3=0 ' Master mode, clock = Fosc/4
SSPCON1.SSPM2=0 ' Master mode, clock = Fosc/4
SSPCON1.SSPM1=0 ' Master mode, clock = Fosc/4
SSPCON1.SSPM0=0 ' Master mode, clock = Fosc/4
end sub
sub procedure DAC_Output(dim value as word)
dim temp as byte
PORTA.3 = 1 'STATUS-LED 3
ClearBit(PORTC,CHIP_SELECT) ' Redo att skicka data...
temp = hi(value) ' Förbered bit 15-8
SSPBUF = temp ' Skicka bit 15-8
while SSPSTAT.BF = 0
PORTA.0 = 1 'STATUS-LED 0
wend
PORTA.1 = 1 'STATUS-LED 1
temp = lo(value) ' Förbered bit 7-0
SSPBUF = temp ' Skicka bit 7-0
while SSPSTAT.BF = 0
PORTA.2 = 1 'STATUS-LED 2
wend
SetBit(PORTC,CHIP_SELECT) ' Här ska överföringen vara klar...
delay_ms(300) 'För att hinna se lysdioderna tända, när allt är ok.
PORTA.0 = 0
PORTA.1 = 0
PORTA.2 = 0
PORTA.3 = 0
end sub
main:
init
while true
value = %1100000000000000
DAC_Output(value) 'Skickar
delay_ms(500)
value = %1100111111111111
DAC_Output(value) 'Skickar
delay_ms(500)
wend
end.
Kod: Markera allt
sub procedure DAC_Output(dim value as word)
dim temp as byte
dim read as byte
PORTA.3 = 1 'STATUS-LED 3
ClearBit(PORTC,CHIP_SELECT) ' Redo att skicka data...
read = SSPBUF ' Läs av innehållet. <---Är inte helt säker på att den raden behövs.
temp = hi(value) ' Förbered bit 15-8
SSPBUF = temp ' Skicka bit 15-8
while SSPSTAT.BF = 0 ' BF ska bli 1 när buffern fått temp-datan.
PORTA.0 = 1 'STATUS-LED 0
wend
PORTA.1 = 1 'STATUS-LED 1
read = SSPBUF ' Läs av innehållet. (Detta innehåll används inte.)
'Nu ska BF ha blivit noll igen och kan ta emot ny temp-data.
temp = lo(value) ' Förbered bit 7-0
SSPBUF = temp ' Skicka bit 7-0
while SSPSTAT.BF = 0 ' BF ska bli 1 när buffern fått temp-datan.
PORTA.2 = 1 'STATUS-LED 2
wend
read = SSPBUF ' Läs av innehållet. (Detta innehåll används inte.)
'Nu ska BF ha blivit noll igen och kan ta emot ny temp-data.
SetBit(PORTC,CHIP_SELECT) ' Skickat klart...
delay_ms(300) 'För att hinna se lysdioderna tända, när allt är ok.
PORTA.0 = 0
PORTA.1 = 0
PORTA.2 = 0
PORTA.3 = 0
end sub
Kod: Markera allt
asm
Ctr0 EQU 0x20 ; Counter variable - sent to SPI
Dly0 EQU 0x21 ; Delay Variable (low byte)
Dly1 EQU 0x22 ; Delay Variable (high byte)
#define CS 0x01 ; PORTC,1
Send_DT bcf PORTC,CS ; Enable Chip Select Output (low)
movf Ctr0,W ; Get Ctr (Counter Value) in W
movwf SSPBUF ; put in SSPBUF
BANKSEL SSPSTAT ; BANK 1
Char1 btfss SSPSTAT,BF ; Data transfer complete? (Buffer Full?)
goto Char1 ; if not, check again
BANKSEL SSPBUF ; BANK0
movf SSPBUF,W ; Get Data from SSPBUF
;
bsf PORTC,CS ; Disable Chip Select Output (high)
Update_Test_Counter
incf Ctr0,F ; Increment counter variable
Delay movlw 0x01 ; Simple Delay loop
movwf Dly1 ; |
movlw 0x0F ; |
movwf Dly0 ; |
DlyLoop decfsz Dly0,F ; |
goto DlyLoop ; |
decfsz Dly1,F ; |
goto DlyLoop ; |
; Done Delay ; \_/
DoAgain goto Send_DT ; Done, Send Next Byte.
end asm
Kod: Markera allt
spi_port EQU PORTC
tris_spi_port EQU TRISC
spi_sdo EQU 0x05
spi_sclk EQU 0x03
spi_cs EQU 0x01
init_spi:
movlw b'00000000' ;MSSP STATUS Register
movwf SSPSTAT
movlw b'00100001'
movwf SSPCON1
send_SPI:
bsf spi_port,spi_cs
movf dac_h,W
movwf SSPBUF
call delay100us
movf dac_l,W
movwf SSPBUF
bcf spi_port,spi_cs
call delay100us
Kod: Markera allt
btfss SSPSTAT,BF
goto $-2
movf SSPBUF,w
Kod: Markera allt
sub procedure DAC_Output(dim value as word)
dim spi_sdo as byte
dim spi_sclk as byte
dim spi_cs as byte
dim dac_h as byte
dim dac_l as byte
spi_sdo = $5
spi_sclk = $3
spi_cs = $1
dac_h = hi(value) ' Förbered bit 15-8
dac_l = lo(value) ' Förbered bit 7-0
asm
bsf spi_port,spi_cs
movf dac_h,W 'skickar bit 15-8
movwf SSPBUF
btfss SSPSTAT,BF
goto $-2
movf SSPBUF,w
movf dac_l,W
movwf SSPBUF 'skickar bit 7-0
bcf spi_port,spi_cs
btfss SSPSTAT,BF
goto $-2
movf SSPBUF,w
end asm
end sub
Kod: Markera allt
symbol spi_port = PORTC ' Dvs, man kan skriva 'spi_port' istället för 'PORTC'
symbol tris_spi_port = TRISC