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 using PIC16F877A

 
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 using PIC16F877A
PostPosted: Fri Aug 01, 2008 1:37 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 01, 2008 3:41 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 01, 2008 11:56 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Aug 02, 2008 1:18 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Aug 16, 2008 4:51 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Aug 16, 2008 7:35 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 29, 2008 1:40 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 29, 2008 4:57 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 29, 2008 6:26 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 29, 2008 7:51 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 29, 2008 10:35 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Aug 30, 2008 1:50 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Sep 01, 2008 3:38 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Sep 03, 2008 2:18 am     Reply with quote

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.
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