CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC 16f877A SPI Connection 1 Master multi slaves

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jaos699



Joined: 06 Jul 2015
Posts: 6

View user's profile Send private message

PIC 16f877A SPI Connection 1 Master multi slaves
PostPosted: Mon Jul 06, 2015 12:41 pm     Reply with quote

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 Smile

*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

View user's profile Send private message

PostPosted: Mon Jul 06, 2015 1:15 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jul 06, 2015 5:48 pm     Reply with quote

Yeah, I am limited to 4 wires (I,O,CLK,SS). Thank you for the answer, I will be changing to I2C Smile
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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