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

SPI slave problem

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



Joined: 28 Jul 2008
Posts: 35

View user's profile Send private message

SPI slave problem
PostPosted: Fri Sep 05, 2008 5:19 am     Reply with quote

I m sending binary 3 bit data from master to slave using SPI but the problem i m facing is on the slave side the compiler compiles the code
but it does not shows the results on demo board.

Below is the code for both master & slave.

Code:


Master:


void main()
{
int i;

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   // TODO: USER CODE!!

While(TRUE)

{
output_low(PIN_A5);

for(i=0;i<9;i++)
{
spi_write(i);
if(output_high(PIN_C5))
{
output_D(i);
}
delay_ms(1000);
}

}}


SLAVE:


void main()
{
int a,i;

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SLAVE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   // TODO: USER CODE!!
   
while(TRUE)

{

a=spi_read(i);


if (a==i)

{
output_B(i);
delay_ms(1000);
}


}
}



Have a look.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: SPI slave problem
PostPosted: Fri Sep 05, 2008 5:49 am     Reply with quote

1. You are sending 4, not 3 bits of binary data from master to slave because your for() loop in the Master code goes from 0 to 8. That's 9 different values.

2. In the Slave code, your first use of the variable 'i' is to pass it as a parameter to spi_read(). What value do you think it is passing? 'i' has not yet been set.

3. When you pass variable 'i' to spi_read(), that value is placed into the SSPBUF register and will be transferred to the Master on the next SPI transaction. This is at the same time the Master sending the value that eventually gets returned and set as 'a' in your code. Why would you expect that a==i ?
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Sep 05, 2008 6:14 am     Reply with quote

I don't understand what you want to do with the variable 'i' in the slave. It never gets a start value and is never assigned a new value. Now it is holding a random value and results of the 'a==i' compare will be random.

The SPI setup in the slave must have the same mode as in the master. And when not using a chip select line it is best to disable the slave's chip select feature. Change to:
Code:
setup_spi(SPI_SLAVE | SPI_L_TO_H | SPI_SS_DISABLED);


Code:
if(output_high(PIN_C5))
The output function does not return a value so it is impossible to execute an if-statement here. The compiler should have issued a warning.
attabros



Joined: 28 Jul 2008
Posts: 35

View user's profile Send private message

Re: SPI slave problem
PostPosted: Fri Sep 05, 2008 11:04 pm     Reply with quote

RLScott wrote:
1. You are sending 4, not 3 bits of binary data from master to slave because your for() loop in the Master code goes from 0 to 8. That's 9 different values.

2. In the Slave code, your first use of the variable 'i' is to pass it as a parameter to spi_read(). What value do you think it is passing? 'i' has not yet been set.

3. When you pass variable 'i' to spi_read(), that value is placed into the SSPBUF register and will be transferred to the Master on the next SPI transaction. This is at the same time the Master sending the value that eventually gets returned and set as 'a' in your code. Why would you expect that a==i ?


what i got from your points i have to load some values to SSPBUF
in the slave code, 'i' itself cannot be read by the spi_read.
Can you tell me how to load SSPBUF i have gone through the
SPI slave example but not got it exactly.
THANKS
attabros



Joined: 28 Jul 2008
Posts: 35

View user's profile Send private message

PostPosted: Fri Sep 05, 2008 11:11 pm     Reply with quote

ckielstra wrote:
I don't understand what you want to do with the variable 'i' in the slave. It never gets a start value and is never assigned a new value. Now it is holding a random value and results of the 'a==i' compare will be random.

The SPI setup in the slave must have the same mode as in the master. And when not using a chip select line it is best to disable the slave's chip select feature. Change to:
Code:
setup_spi(SPI_SLAVE | SPI_L_TO_H | SPI_SS_DISABLED);


Code:
if(output_high(PIN_C5))
The output function does not return a value so it is impossible to execute an if-statement here. The compiler should have issued a warning.



This is for loop check that the data is going to the slave properly
Code:
if(output_high(PIN_C5))


As pin C5 is serial data out pin.
as far as SS is concerned im using it as PIN_A5 which i mentioned in master code.

KINDLY Explain in detail this or by writing some
sample code

Quote:

I don't understand what you want to do with the variable 'i' in the slave. It never gets a start value and is never assigned a new value. Now it is holding a random value and results of the 'a==i' compare will be random.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat Sep 06, 2008 7:34 am     Reply with quote

Dilemma....
I can help you very fast by posting an example program but ... then you will learn very little. Even after me and RLScott pointed out several errors you don't understand why these are bugs.
I guess we'll have to take the long route.

First a few general remarks:
    - For future postings in this forum always mention your PIC processor type number and compiler version.
    - Post complete programs, including #fuses line, #include, etc. So we can copy paste the code into our compiler and are sure to have the same settings you use.
    - Describe hardware connections if applicable. For example you didn't mention PIN_A5 of the master being connected to the SS input of the slave.


Quote:
This is for loop check that the data is going to the slave properly
Code:
if(output_high(PIN_C5))
The output_high() is a function for setting the output pin high. You can not use it for testing the current output level, if that is what you want then use the function input_state().
But even then it is not going to work. The SPI output is sending out a fast bit stream you never know when it is going to be high or low so the test result will be random and useless.
Forget about this. The test is never going to work the way you want.

My suggestion for the SPI slave setup was wrong as I assumed you were not using the Slave Select line. Still, you have to make sure both the master and slave are transmitting the data in the same SPI mode. Configure the SPI in the slave as:
Code:
setup_spi(SPI_SLAVE | SPI_L_TO_H);


Code:
a=spi_read(i);


if (a==i)
What do you want to do with variable 'i' here? It doesn't make sense.
For your understanding: when calling spi_read(i) the slave will wait for the master to send a byte and at the same time the slave will send the value in 'i' to the master. You have never given a value to 'i' so this is filled with a random garbage value.
If you don't want to send data to the master than just call spi_read with a parameter 0 or no parameter at all.


Code:
#include <16F877A.h>
#device *=16
#fuses HS, NOWDT, NOLVP, NOPROTECT
#use delay(clock=16000000)

// MASTER

void main()
{
  int i;

  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  setup_psp(PSP_DISABLED);
  setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_4);
  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  setup_comparator(NC_NC_NC_NC);
  setup_vref(FALSE);
 
  while(TRUE)
  {
    for(i=0; i<8; i++)
    {
      output_low(PIN_A5);   // Select slave
      spi_write(i);
      output_high(PIN_A5);   // Deselect slave

      output_D(i);
      delay_ms(1000);
    }
  }
}


// SLAVE:


void main()
{
  int a;

  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  setup_psp(PSP_DISABLED);
  setup_spi(SPI_SLAVE | SPI_L_TO_H);
  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  setup_timer_1(T1_DISABLED);
  setup_timer_2(T2_DISABLED,0,1);
  setup_comparator(NC_NC_NC_NC);
  setup_vref(FALSE);

  while(TRUE)
  {
    a=spi_read(0);   // Will wait until the master has send a byte.

    output_b(a);
  }
}
attabros



Joined: 28 Jul 2008
Posts: 35

View user's profile Send private message

PostPosted: Sun Sep 07, 2008 11:39 pm     Reply with quote

Thanks,
This works fine i got your points.

Kindly tell me if first i want to save the whole byte in RAM
or SSPBUF how will i load it.

Secondly ,
what other tasks can i perform using the same hardware using SPI.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Sep 08, 2008 1:56 pm     Reply with quote

Quote:
Kindly tell me if first i want to save the whole byte in RAM
or SSPBUF how will i load it.
Sorry, I don't understand what you want to say. Using the CCS functions you don't have to access the SSPBUF register.

Quote:
Secondly ,
what other tasks can i perform using the same hardware using SPI.
SPI is one of the many possible communication methods, it is not a goal in itself. Normally you start with a problem first and then you continue thinking about 'how' to solve it, you want to do it the other way around?
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Mon Sep 08, 2008 4:14 pm     Reply with quote

ckielstra wrote:
...Using the CCS functions you don't have to access the SSPBUF register....

But you can always to this:
Code:

#byte SSPBUF=0x13

SSPBUF = SomeVal;

_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
attabros



Joined: 28 Jul 2008
Posts: 35

View user's profile Send private message

PostPosted: Mon Sep 08, 2008 10:36 pm     Reply with quote

Thanks i got it
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