View previous topic :: View next topic |
Author |
Message |
attabros
Joined: 28 Jul 2008 Posts: 35
|
SPI slave problem |
Posted: Fri Sep 05, 2008 5:19 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
RLScott
Joined: 10 Jul 2007 Posts: 465
|
Re: SPI slave problem |
Posted: Fri Sep 05, 2008 5:49 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Sep 05, 2008 6:14 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
attabros
Joined: 28 Jul 2008 Posts: 35
|
Re: SPI slave problem |
Posted: Fri Sep 05, 2008 11:04 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
attabros
Joined: 28 Jul 2008 Posts: 35
|
|
Posted: Fri Sep 05, 2008 11:11 pm |
|
|
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.
|
|
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Sep 06, 2008 7:34 am |
|
|
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);
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
attabros
Joined: 28 Jul 2008 Posts: 35
|
|
Posted: Sun Sep 07, 2008 11:39 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Sep 08, 2008 1:56 pm |
|
|
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? |
|
![](templates/subSilver/images/spacer.gif) |
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Mon Sep 08, 2008 4:14 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
attabros
Joined: 28 Jul 2008 Posts: 35
|
|
Posted: Mon Sep 08, 2008 10:36 pm |
|
|
Thanks i got it |
|
![](templates/subSilver/images/spacer.gif) |
|