View previous topic :: View next topic |
Author |
Message |
attabros
Joined: 28 Jul 2008 Posts: 35
|
SPI using PIC16F877A |
Posted: Fri Aug 01, 2008 1:37 am |
|
|
Hi!
I want to send data from one microcontroller to another or master to slave using SPI technique. I'm using 16f877A both as master & slave.
What should be the basic hardware design as well as code for this task ?
As I'm new to microcontroller, as I'm a beginner can anyone help me how should i start this task ?
Thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 01, 2008 3:41 pm |
|
|
This post shows master transimitting bytes to the SPI slave:
http://www.ccsinfo.com/forum/viewtopic.php?t=26888
(It does not show the master reading bytes from the SPI slave).
This demo program is done on one board (with one PIC), so the
master uses software SPI. The slave uses hardware SPI.
Hopefully this code will be enough to demonstrate how to do it. |
|
|
attabros
Joined: 28 Jul 2008 Posts: 35
|
|
Posted: Fri Aug 01, 2008 11:56 pm |
|
|
Actually i want to start like to send a signal from master & on the slave side just to glow 1 led first so that i can get an idea how the SPI features are working. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Aug 02, 2008 1:18 am |
|
|
That code would do it. Just send a certain character to the slave and
in the slave code, check for it, and if it arrives then turn on the LED. |
|
|
attabros
Joined: 28 Jul 2008 Posts: 35
|
|
Posted: Sat Aug 16, 2008 4:51 am |
|
|
I have made the code for master & slave using hardware SPI
but its not working correctly i guess there is some problem with my slave code.
Here is the code below.
MASTER:
void main()
{
int x;
output_low(PIN_A5);
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_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)
{
{
x= 0; // value to be sent to spi
spi_write(x);
delay_us(1000);
}
{
x=1;
spi_write(x);
delay_us(1000);
}
output_high(PIN_A5);
}}
SLAVE:
void main()
{
int a,x;
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)
{
( !spi_data_is_in() && input(PIN_A5));
if(spi_data_is_in())
{
a = spi_read(x); //reads the data from spi
delay_us(1000);
output_high(PIN_B0);
}}}
i want to make led on off through SPI
on slave.
Kindly have a look & suggest
Thanks . |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Aug 16, 2008 7:35 am |
|
|
Next time when posting program code please use the 'code' buttons to preserve the layout of your program. It makes for much easier reading.
The main problem in your slave is that you have code present for setting PIN_B0 high but there is no code for setting it low again. The LED is switched on but never off again....
Another possible problem in the slave is the delay_us(1000). You don't need a delay here as the slave uses the function spi_dat_is_in() to see if new data is present. With the extra delay it is possible you are too slow and may miss data sent by the master. Just remove the delay.
Change the code inside the while-loop to:
Code: | while (TRUE)
{
if( spi_data_is_in() )
{
a = spi_read(x); //reads the data from spi
if (a == 0)
output_low(PIN_B0);
else if (a == 1)
output_high(PIN_B0);
}
} |
|
|
|
attabros
Joined: 28 Jul 2008 Posts: 35
|
|
Posted: Fri Aug 29, 2008 1:40 am |
|
|
I have tried the code you provided for slave but it does not
showing any result on the output |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Aug 29, 2008 4:57 am |
|
|
Code: | setup_spi(SPI_SLAVE); | You have not specified the SPI-mode. Always set it the same as in the master.
There are four possible combinations so you have a 25% chance the CCS compiler's default is correct for your slave.
Set to: Code: | setup_spi(SPI_SLAVE | SPI_L_TO_H); |
Double check your hardware connections, in particular:
- SDO of master is connected to SDI of slave, and vice versa. (a cross connection).
- Both PICs are running on the same power supply? If not, then a ground wire must be present between both PICs.
What is your compiler version number? (it is a number like 3.249 or 4.077 and can be found at the top of the *.lst file). |
|
|
attabros
Joined: 28 Jul 2008 Posts: 35
|
|
Posted: Fri Aug 29, 2008 6:26 am |
|
|
still not giving any response,
the compiler version is
CCS PCM C Compiler, Version 4.020, 36938
i made the following changes like,
Slave SS pin connect with ground.
but still not working |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Aug 29, 2008 7:51 am |
|
|
Strange it's not working. There must be a more basic problem in your system. Have you tried a simple program blinking a LED and is that working?
The first v4 compiler releases were so bad you couldn't even compile the most simple program. Things started to get to the same level as the old v3 compiler at about release v4.030. For the new v4 features it took a bit longer to work, let's say release 4.050.
Your program is very basic and probably you can make it work on your compiler version but it won't take long until you run into one of the compiler bugs and you'll waste a lot of time. Please upgrade to one of the latest versions or downgrade to the stable v3.249 that was available for download at the time you bought your compiler. |
|
|
attabros
Joined: 28 Jul 2008 Posts: 35
|
|
Posted: Fri Aug 29, 2008 10:35 pm |
|
|
Yes I have done many simple programs like led on/off with push button
as well as binary counter they work fine.
Posting the code one more time plz have a look.
Code: |
Master:
void main()
{
int x;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
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)
{
output_low(PIN_A5);
{
x=1; // value to be sent to spi
spi_write(x);
delay_us(10000);
x=0;
spi_write(x);
delay_us(10000);
}
output_high(PIN_A5);
}}
SLAVE:
void main()
{
int a; // to be read from spi
set_tris_B(0);
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);
// TODO: USER CODE!!
while (TRUE)
{
if(spi_data_is_in())
{
a = spi_read();
if(a==1)
output_high(PIN_B0);
else if(a==0)
output_low(PIN_B0);
} }} |
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Aug 30, 2008 1:50 pm |
|
|
Compiler version 4.020 is broken. Don't use it.
Either downgrade to the previous stable version v3.249 or upgrade to one of the latest releases, v4.070 and higher seem to be stable as well.
Whenever I see someone with an old v4 compiler of before v4.030 I refuse to give support. Even if we can solve your current problem in v4.020 you'll be back tomorrow with another compiler bug. |
|
|
attabros
Joined: 28 Jul 2008 Posts: 35
|
|
Posted: Mon Sep 01, 2008 3:38 am |
|
|
I dont think the compiler version is broken one there is something wrong with the coding,
anyways thanks for your help. |
|
|
attabros
Joined: 28 Jul 2008 Posts: 35
|
|
Posted: Wed Sep 03, 2008 2:18 am |
|
|
I have made some modification in the above code for master & slave communication its working perfect have a look.
Code: |
Master:
void main()
{
int x;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
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)
{
output_low(PIN_A5); //activate slave select
{
x=1; // value to be sent to spi
spi_write(x);
if(output_high(PIN_C5)) //check for data sent
{
output_toggle(PIN_D0); //loop check
}
delay_ms(1000);
x=0;
spi_write(x);
if(output_high(PIN_C5)) //check for data sent
{
output_toggle(PIN_D1); //loop check
}
delay_ms(1000);
}
output_high(PIN_A5); //deactivate slave select
}}
SLAVE:
void main()
{
int a,x; // to be read from spi
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(); //spi read function
if(a==1) //if the value recieved by slave
{
output_high(PIN_B7); //output will be high
}
else
{
output_low(PIN_B7);
}
if(a==0)
{
output_high(PIN_B6);
}
else
{
output_low(PIN_B6);
}
} }}
|
the above code is perfect for SPI beginner to start
SPI communication between two PICs. |
|
|
|