I tried to configure two PIC16F877As as SPI master and SPI slave. Pls refer to schematic shown in figures in attachment. Master will send a '?' to acknowledge the slave. Then, the slave will reply with a '!'. Once master receives '!', it will start to receive data from slave, which is a '5' character. The charater will then be displayed on the LCD.
The SPI communication between the master/slave did not work. Pin B0 of master is connected to A5/SS of slave. Pls advise if you find mistakes in the schematic as well as the source code.
For your information, I'm using PicBasic Pro 2.47 compiler.
Source Code (MASTER)
Code:
' PicBasic program to demonstrate operation of an LCD in 4-bit mode
'
' LCD should be connected as follows:
'-------------------------------------
' LCD PIC
'-------------------------------------
' DB4 PortD.4
' DB5 PortD.5
' DB6 PortD.6
' DB7 PortD.7
' RS PortD.2
' E PortD.3
' RW Ground
' Vdd 5 volts
' Vss Ground
' Vo 10K potentiometer (or ground)
'
' PicBasic Pro program to read and write to SPI slave
' using the synchronous serial port
'
' Connect SDI(master) to SDO(slave), SDO(master) to
' SDI(slave), AND SCK(master) to SCK(slave).
' Common Ground is required.
'
' Sends ascii "?" to request data, waits for a "!" to
' begin receiving data. Expect to receive "5" (without quotes)
' from slave and display it LCD.
DEFINE LCD_LINES 4 'number of LCD lines
DEFINE LCD_DREG PORTD
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTD
DEFINE LCD_EBIT 3
DEFINE LCD_BITS 4
DEFINE LCD_RSBIT 2
DEFINE LCD_EREG PORTD
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 40
SSPEN VAR SSPCON.5 'SSP Enable bit
CKP VAR SSPCON.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
a VAR BYTE
TRISC = 0 'set PORTC I/O
TRISB = %11111110 'set PORTB.0 as output
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
LOW PORTB.0
loop:
GoSub getdata 'initiate conversion and receive data
LCDOut $fe, 1,
LCDOut #a
Pause 1000
GoTo loop 'do it forever
getdata:
HIGH PORTB.0 'enable ss pin
SSPBUF = "?" 'send ? to start conversion
GoSub letclear 'wait for buffer to clear
IF SSPBUF<>"!" Then getdata 'wait for reply (!)
SSPBUF = 0 'write to SSPBUF to start clock
GoSub letclear 'wait for receipt
a = SSPBUF 'store received character in array
LOW PORTB.0
Return
letclear:
IF SSPIF = 0 Then letclear 'wait for SPI interupt flag
PauseUs 25 '25uS fudge factor
SSPIF = 0 'reset flag
Return
Source Code (SLAVE)
Code:
' PicBasic Pro SPI slave program (see SPImast.bas for connections)
dataout VAR WORD
SSPEN VAR SSPCON.5 'SSP Enable bit
CKP VAR SSPCON.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
TRISC = %11011111 'set PORTC I/O
TRISA = %11011111 'set PORTA.5 as input.
SSPCON = %00000100 'configure SPI slave, enable SS pin
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
dataout[0] = "5"
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
GoSub senddata 'send "!" and string of data
GoTo loop 'do it forever
senddata:
GoSub letclear 'wait until buffer ready
SSPBUF = "!" 'send reply
GoSub letclear 'wait until buffer ready
SSPBUF = dataout[0] 'send variable
Return
letclear:
IF SSPIF = 0 Then letclear 'wait for interrupt flag
SSPIF = 0 'reset flag
Return
Bookmarks