Hello everyone,
I'm seeking help to print simple byte data from Arduino Uno to PIC16F877A via SPI interface. Here is the code mentioned below. I cannot get the output on serial monitor. kindly mention where I'm missing. If I'm hook-up Arduino to Arduino, it is working. Also If the PIC selected as master, and the Arduino is slave, still working. The only issue if I selected PIC as Slave mode and Arduino as master. I searched the help topics and the community but mostly the examples related to master mode and not slave mode.
#chip 16F877A, 4
#define USART_BAUD_RATE 9600
#define USART_TX_BLOCKING
dim dat as byte
dir PORTB.7 in 'SS
dir PORTC.5 out 'SDO/MOSI/COPI
dir PORTC.4 in 'SDI/MISO/CIPO
dir PORTC.3 in 'SCK
SPIMode Slave
do
SPITransfer 0,dat
HserPrint dat
HSerPrintCRLF
wait 1 s
loop
Your current code polls SPI transfers risks missed data. So, what is happening would be expectd.
You need an interrupt handler.
Why an Interrupt Handler Is Needed
In SPI slave mode, the PIC16F877A relies on the Arduino to drive the Slave Select (SS) and clock (SCK) pins. Polling (SPITransfer) can miss data if unsynchronised, as the PIC’s SPI slave mode triggers an interrupt when the buffer (SSPBUF) is full. An interrupt handler ensures immediate data processing, boosting reliability.
Modified PIC16F877A Code
This revised code ( untested) uses an interrupt handler for SPI slave mode
' Start SPI slave mode
SPIMode Slave
Dim spidataready, spidat as Byte
spidataready = false
' Enable interrupts
On Interrupt SSP1Ready Call SPI_ISR
' Main loop
do
wait 10 ms ' Space for other tasks
if spidataready then
HserPrint spidat ' Print to serial
HSerPrintCRLF
end if
loop
' Interrupt routine
sub SPI_ISR
spidat = SSPBUF ' Read SPI buffer
spidataready = true
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Venn,
I made the changes as you suggested. The ISR not being called during program execution. I added HserSend "." into ISR sub, not responding at serial monitor. I'm using Simulide software for simulation. I attached pin connection with this post, please inspect if I made any wrong. The complete code below. Thanks in advance!
#chip 16F877A, 4
#define USART_BAUD_RATE 9600
#define USART_TX_BLOCKING
dir PORTB.7 in 'SS
dir PORTC.5 out 'SDO
dir PORTC.4 in 'SDI
dir PORTC.3 in 'SCK
SPIMode Slave
dim spidat, spidataready as byte
spidataready = false
'Enable interrupts
On Interrupt SSP1Ready Call SPI_ISR
do
wait 10 ms
if spidataready then
HserPrint spidat
HSerPrintCRLF
spidataready = false
end if
loop
'Interrupt routine
sub SPI_ISR
spidat = SSPBUF 'Read SPI buffer
Hsersend "." 'Test
spidataready = true
end sub
So, this code... change the SPIMode.. a parameter 0. Test, then change to 1. Test do same for 3 and 4. See the Help why this may help.
I also changed the ISR but as you are not seeing the ISR active this is not the root cause issue.
Evan
#chip 16F877A, 4
#define USART_BAUD_RATE 9600
#define USART_TX_BLOCKING
dir PORTB.7 in 'SS
dir PORTC.5 out 'SDO
dir PORTC.4 in 'SDI
dir PORTC.3 in 'SCK
SPIMode Slave // [,0|1|2|3]
dim spidat, spidataready as byte
spidataready = false
'Enable interrupts
On Interrupt SSP1Ready Call SPI_ISR
do
wait 10 ms
if spidataready then
HserPrint spidat
HSerPrintCRLF
spidataready = false
end if
loop
'Interrupt routine
sub SPI_ISR
// Read SPI buffer
SPITransfer spidat, spidat
Hsersend "." 'Test
spidataready = true
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello everyone,
I'm seeking help to print simple byte data from Arduino Uno to PIC16F877A via SPI interface. Here is the code mentioned below. I cannot get the output on serial monitor. kindly mention where I'm missing. If I'm hook-up Arduino to Arduino, it is working. Also If the PIC selected as master, and the Arduino is slave, still working. The only issue if I selected PIC as Slave mode and Arduino as master. I searched the help topics and the community but mostly the examples related to master mode and not slave mode.
Hello,
Your current code polls SPI transfers risks missed data. So, what is happening would be expectd.
You need an interrupt handler.
Why an Interrupt Handler Is Needed
In SPI slave mode, the PIC16F877A relies on the Arduino to drive the Slave Select (SS) and clock (SCK) pins. Polling (
SPITransfer
) can miss data if unsynchronised, as the PIC’s SPI slave mode triggers an interrupt when the buffer (SSPBUF) is full. An interrupt handler ensures immediate data processing, boosting reliability.Modified PIC16F877A Code
This revised code ( untested) uses an interrupt handler for SPI slave mode
Hi Venn,
Thank you for the quick reply. I tried to figure out but I don't have luck. even the interrupt also not working in my case.
I would need to see your complete code.
Question. ISR being called? Add Hsersend "." to the ISR. Is the "." shown?
Also, change.
if spidataready then
HserPrint spidat ' Print to serial
HSerPrintCRLF
spidataready = false
end if
Hi Venn,
I made the changes as you suggested. The ISR not being called during program execution. I added HserSend "." into ISR sub, not responding at serial monitor. I'm using Simulide software for simulation. I attached pin connection with this post, please inspect if I made any wrong. The complete code below. Thanks in advance!
I cannot test, so you will have to. :-)
This is likely to be something very simple.
So, this code... change the SPIMode.. a parameter 0. Test, then change to 1. Test do same for 3 and 4. See the Help why this may help.
I also changed the ISR but as you are not seeing the ISR active this is not the root cause issue.
Evan