PDA

View Full Version : 16-bit SPI problem



shaiqbashir
- 19th June 2008, 14:38
Hi guys!

i have setup a circuit that involves two PICs. both are PIC18f452. One pic (SPI SLAVE) has a sensor on its analog input, it senses the value and sends it through SPI to SPI Master PIC. The SPI master pic then sends it to labview through serial port, now so far i was using this define statement in my program:

define adc_bits 8

but since i require more accuracy, so i made it

define adc_bits 10

and then i changed the associated variables type from byte to word to hold such a big amount of data. Now the prb is that SPI communication is not transferring the right value. this probably is due to the fact that the SSPBUF register is of 8-bits and im transferring a 16-bit value. So please look at my coding and suggest me a way how to make it possible to transfer a 16-bit data through spi. here is my coding for the SPI master



Include "Modedefs.Bas"
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 24h
DEFINE HSER_BAUD 9600
DEFINE HSER_SPBRG 25
define OSC 4


DEFINE ADC_BITS 8 ' Set number of bits in result
DEFINE ADC_CLOCK 2 ' Set clock source (rc = 3)
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in microseconds

' Set LCD Data port
DEFINE LCD_DREG PORTD
' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_DBIT 0
' Set LCD Register Select port
DEFINE LCD_RSREG PORTC
' Set LCD Register Select bit
DEFINE LCD_RSBIT 0
' Set LCD Enable port
DEFINE LCD_EREG PORTC
' Set LCD Enable bit
DEFINE LCD_EBIT 1
' Set LCD bus size (4 or 8 bits)
DEFINE LCD_BITS 8
' Set number of lines on LCD
DEFINE LCD_LINES 2
' Set command delay time in us
DEFINE LCD_COMMANDUS 2000
' Set data delay time in us
DEFINE LCD_DATAUS 50

SSPEN VAR SSPCON1.5 'SSP Enable bit
CKP VAR SSPCON1.4 'Clock Polarity Select
SMP VAR SSPSTAT.7 'Data input sample phase
CKE VAR SSPSTAT.6 'Clock Edge Select bit
SSPIF VAR PIR1.3 'SPI interrupt flag

i VAR BYTE 'loop counter
a VAR byte[6] 'Holds 6 characters read from slave


ADCON1 = 7 'Set PORTA and PORTE to digital
Low PORTE.2 'LCD R/W line low (W)
Pause 100 'Wait for LCD to start up

TRISC = %00010000 'set PORTC I/O

SSPEN = 1 'enable SPI pins
CKP = 0 'clock idle low
CKE = 0 'transmit on idle to active transition
SSPIF = 0 'clear buffer full status
SMP = 0 'sample in middle of data
SSPCON1.0 = 0
SSPCON1.1 = 0
SSPCON1.2 = 0
SSPCON1.3 = 0

loop:
GoSub getdata 'initiate conversion and receive data


'LCDOut $fe, 1, STR a\5, DEC a[5] 'display received string
Pause 10
hserout [dec a[5],13,10]
'hserout [dec a[5]]
pause 10
GoTo loop 'do it forever


getdata:

SSPBUF = "?" 'send ? to start conversion
GoSub letclear 'wait for buffer to clear
IF SSPBUF<>"!" Then getdata 'wait for reply (!)

For i = 0 to 5 'loop for 6 characters
SSPBUF = 0 'write to SSPBUF to start clock
GoSub letclear 'wait for receipt
a[i] = SSPBUF 'store received character in array
Next i 'get next character

Return


letclear:

IF SSPIF = 0 Then letclear 'wait for SPI interupt flag
PauseUs 25 '25uS fudge factor
SSPIF = 0 'reset flag
Return



and then following is the program for SPI slave



Include "Modedefs.Bas"
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 24h
DEFINE HSER_BAUD 9600
DEFINE HSER_SPBRG 25
' Allocate RAM
define osc 4

DEFINE ADC_BITS 8 ' Set number of bits in result
DEFINE ADC_CLOCK 8 ' Set clock source (rc = 3)
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in microseconds

dataout VAR byte[8] 'Data out array

SSPEN VAR SSPCON1.5 'SSP Enable bit
CKP VAR SSPCON1.4 'Clock Polarity Select
SMP VAR SSPSTAT.7 'Data input sample phase
CKE VAR SSPSTAT.6 'Clock Edge Select bit
SSPIF VAR PIR1.3 'interrupt flag - last bit set

i VAR BYTE 'loop counter

TRISC = %10011111 'set PORTC I/O
SSPCON1 = %00000101 'configure SPI slave, no SS

CKP = 0 'clock idle low
CKE = 0 'transmit on idle to active transition
SSPIF = 0 'clear SPI interrupt
SMP = 0 'sample in middle of data

'ADCON0 = %10000000
ADCON1 = $00 'PORTA.0 analog, rest PORTA and PORTE pins to digital

dataout[0] = "A" 'Preset output data to "ADC= "
dataout[1] = "D"
dataout[2] = "C"
dataout[3] = "="
dataout[4] = " "

loop: SSPEN = 0 'disable/enable SSP to reset port
SSPEN = 1
GoSub letclear 'wait for byte received
IF (SSPBUF <> "?") Then loop 'wait for ? to start conversion

ADCIN 0, dataout[5] 'Read ADC channel 0, store in 6th position of string
PAUSE 50
GoSub senddata 'send "!" and string of data


GoTo loop 'do it forever


senddata:
GoSub letclear 'wait until buffer ready
SSPBUF = "!" 'send reply

For i = 0 to 5 'loop for 6 array locations
GoSub letclear 'wait until buffer ready
SSPBUF = dataout[i] 'send array variable
pause 10
Next i 'next location

Return


letclear:
IF SSPIF = 0 Then letclear 'wait for interrupt flag
SSPIF = 0 'reset flag

Return


PLease remember that this configuration is working well as the PIC is configured as an 8-bit adc. when i make it 10-bit, the only thing that doesnt work is SPI communication. Please tell me how to make it possible

regards,

skimask
- 19th June 2008, 14:44
So please look at my coding and suggest me a way how to make it possible to transfer a 16-bit data through spi.................................
PLease remember that this configuration is working well as the PIC is configured as an 8-bit adc. when i make it 10-bit, the only thing that doesnt work is SPI communication. Please tell me how to make it possible

Send 2 8-bit bytes...
Receive 2 8-bit bytes...

T.Jackson
- 19th June 2008, 15:12
I tell ya -- I reckon when they named the "byte" and the "nibble" they must have been eating something, or at the very least thinking about "food" :)

T.Jackson
- 19th June 2008, 15:42
Nobody ever says or does anything in this world without reasoning.