|
|
View previous topic :: View next topic |
Author |
Message |
jaos699
Joined: 06 Jul 2015 Posts: 6
|
PIC 16f877A SPI Connection 1 Master multi slaves |
Posted: Mon Jul 06, 2015 12:41 pm |
|
|
Hey,
I am trying to build a spi connection between 3 pic's 16f877A. I have 1 master device and 2 slaves atm but I would like to add more in the future. I have 1 wire of working as the chip select line for all slaves. Im trying to pass first an address for all slaves and then get an answer from the slave selected by the address ... The problem is that my master device is not reading correctly the answer from the slave and I have no idea why ... Does anyone have any idea what is happening? The slave devices are receiving and writing correctly but the master only reads the last value that it has sent to the slaves.
*MASTER Code*
Code: | #include <16f877A.h>
#fuses HS,NOLVP,NOWDT
#use delay (clock=20000000)
#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7)
#byte SSPBUF = getenv("SFR:SSPBUF")
#include <stdlib.h>
#include <input.c>
#define PUSH_BUTTON PIN_A4
// Master
void OnLed()
{
output_high(PIN_B5);
delay_ms(100);
output_low(PIN_B5);
delay_ms(1000);
output_high(PIN_B5);
output_high(PIN_B4);
delay_ms(100);
output_low(PIN_B4);
delay_ms(100);
output_high(PIN_B4);
output_high(PIN_A5);
delay_ms(100);
output_low(PIN_A5);
delay_ms(100);
output_high(PIN_A5);
}
void Flash(int pin)
{
output_high(pin);
delay_ms(100);
output_low(pin);
delay_ms(100);
output_high(pin);
}
int CheckButton()
{
int8 val;
if (input(PIN_A4)== 0)
{
val = 20;
}
else
{
val = 30;
}
return val;
}
void main()
{
OnLed();
output_high(PIN_A5);
delay_us(100);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
delay_us(100);
while (true)
{
Flash(PIN_B4);
output_low(PIN_A5);
spi_write(CheckButton());
output_high(PIN_A5);
delay_us(250);
int8 read;
output_low(PIN_A5);
while(!spi_data_is_in());
read = spi_read(0x00);
output_high(PIN_A5);
delay_ms(200);
printf("\r\n Read: %d",read);
}
} |
*SLAVES*
Code: |
#include <16f877A.h>
#fuses HS,NOLVP,NOWDT
#use delay (clock=20000000)
#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7)
#include <stdlib.h>
#include <input.c>
#byte SSPBUF = getenv("SFR:SSPBUF")
void OnLed()
{
output_high(PIN_B5);
delay_ms(100);
output_low(PIN_B5);
delay_ms(100);
output_high(PIN_B5);
output_high(PIN_B4);
delay_ms(100);
output_low(PIN_B4);
delay_ms(100);
output_high(PIN_B4);
output_high(PIN_A5);
delay_ms(100);
output_low(PIN_A5);
delay_ms(100);
output_high(PIN_A5);
}
void Flash(int pin)
{
output_high(pin);
delay_ms(100);
output_low(pin);
delay_ms(100);
output_high(pin);
}
void main(void)
{
OnLed();
setup_spi(SPI_SLAVE | SPI_L_TO_H);
while(true)
{
int8 address,Ans;
Ans = 0;
while(!spi_data_is_in());
address = SSPBUF;
if (address == 20)
{
Ans = 21;
SSPBUF = Ans;
}
printf("\r\n Address: %d",address);
printf("\r\n Ans: %d",Ans);
}
}
|
The code for both slaves is the same, the difference is that one receives 20 and writes 21 and the second one receives 30 and writes 31. All slaves are printing correctly the variables.
My only problem is the master device that is printing "read" as 20 or 30 when it should read 21 or 31.
Thanks
*Edit: I have already read almost all topics about SPI connection and couldnt figure out what is wrong ... Could be something with my eletronics but I believe it is something related to the code (Nuclear engineering student here trying to understand something about eletronics lol) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Jul 06, 2015 1:15 pm |
|
|
Problem is that the slaves will all be driving their SDO lines.
This can be disabled using the SS line, which then tri-states this line when the device is not selected, but without this or an equivalent, you will always have multiple devices all trying to drive this line at the same time.
This is why multiple SPI slaves normally implies multiple CS lines from the master...
Honestly, if you are limited on lines, you either need to switch to I2C, or add a extra IC, which monitors the SPI transmission, looks for the 'address', and then operates the CS line for the device required. |
|
|
jaos699
Joined: 06 Jul 2015 Posts: 6
|
|
Posted: Mon Jul 06, 2015 5:48 pm |
|
|
Yeah, I am limited to 4 wires (I,O,CLK,SS). Thank you for the answer, I will be changing to I2C |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|