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 Communication problem (Between 16F877A and 16F873A)

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



Joined: 16 Nov 2008
Posts: 22
Location: Sri Lanka

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

SPI Communication problem (Between 16F877A and 16F873A)
PostPosted: Sun Dec 21, 2008 10:42 am     Reply with quote

Hi all,

Currently I'm developing a code for an wireless sensor network application. Here I need to interconnect 16F877A and 16F873A. As the initial step I have written a sample code to simulate SPI communication in between these two micro controllers. Here 16F877A is the master and 16F873A is the slave.

I have correctly interconnected pins of two micro controllers;
SDO to SDI of the other
and SCK of master to the SCK of slave.
Both micro controllers are powered by same power supply.
My compiler version is the CCS PCM C Compiler, Version 4.057, 36748

As the first step I need to light up LED for 5 sec at the slave end. Here I send a byte to the slave after each 10sec. If the slave receives that byte it should light up the LED for 5 sec.

But once this is implemented it doesn't give any feedback. I couldn't figure out the errors in my code. I have posted the code bellow.

Please anyone be kind enough to correct me and show me the right path. Any help regarding my matters are highly appreciated.

Thanks you all in advance.
Kushan


Master code
Code:

#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES WRT_50%                  //Lower half of Program Memory is Write Protected

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#include <stdio.h>
#include <stdlibm.h>
#include <string.h>

#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)   //    low       leading edge
#define SPI_MODE_1  (SPI_L_TO_H)                     //    low       trailing edge
#define SPI_MODE_2  (SPI_H_TO_L)                     //    high      leading edge
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)   //    high      trailing edge

void main()
{
   long pwmDuty = 50;
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_MASTER|SPI_MODE_0|SPI_CLK_DIV_4);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_1,24,1);
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(pwmDuty);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   // TODO: USER CODE!!
   
   while(true){
      delay_ms(10000);            //wait 10 sec before transmit data to the slave
      spi_write(0xAA);
      delay_us(100);
   }
}


Slave code
Code:

#include <16F873A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES WRT_50%                  //Lower half of Program Memory is Write Protected

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#include <stdio.h>
#include <stdlibm.h>
#include <string.h>

#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)   //    low       leading edge
#define SPI_MODE_1  (SPI_L_TO_H)                     //    low       trailing edge
#define SPI_MODE_2  (SPI_H_TO_L)                     //    high      leading edge
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)   //    high      trailing edge

int1 spiDataAvail = false;
long rcv_data;

#int_SSP              //SPI activity interrupt
void  SSP_isr(void){
   rcv_data = spi_read();
   spiDataAvail = true;

}

void main()
{
   long pwmDuty = 50;
   
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SLAVE|SPI_MODE_0|SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_1,24,1);
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(pwmDuty);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);

   // TODO: USER CODE!!
   while(true){
      if(spiDataAvail){
         spiDataAvail = false;
         if(rcv_data==0xAA){
            output_high(PIN_B2);
            delay_ms(5000);        //LED is on for 5 sec then off until data comes again
            output_low(PIN_B2);
            rcv_data = 0x00;      //set to some diiferrent value
         }
      }
   }
}

_________________
Kushan Sharma
mlkushan@gmail.com
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: SPI Communication problem (Between 16F877A and 16F873A)
PostPosted: Sun Dec 21, 2008 2:06 pm     Reply with quote

mlkushan wrote:
...But once this is implemented it doesn't give any feedback....


What sort of feedback are you expecting?
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
mlkushan



Joined: 16 Nov 2008
Posts: 22
Location: Sri Lanka

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Sun Dec 21, 2008 9:44 pm     Reply with quote

First thank you for your help,

Feedback in the sense, once a slave micro controller receives a byte from master through the SPI bus, a LED should light up for five sec. This LED is light up by the bellow code segment;

Code:

..................
..................
output_high(PIN_B2);
delay_ms(5000);        //LED is on for 5 sec then off until data comes again
output_low(PIN_B2);
..................
..................


But unfortunately it doesn't light up. So I can't figure out the exact reason for this.
So any help regarding my matters is highly appreciated...!

Thanks in advance
kushan
_________________
Kushan Sharma
mlkushan@gmail.com
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Dec 22, 2008 12:06 am     Reply with quote

Post a list of the connections between the two PICs, and post the pin
numbers. Look at the actual wires (or tracks) on the board and count
down the pin numbers on the I.C. In other words, I want to absolutely
verify that the physical connections are correct.

Also post if the PICs are on different boards, or the same board.
Is there a ground connection between the two boards (or PICs) ?
mlkushan



Joined: 16 Nov 2008
Posts: 22
Location: Sri Lanka

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Mon Dec 22, 2008 12:39 am     Reply with quote

Thank you for your help,

16F873A
PIN_C4 – (pin 15) SDI data input
PIN_C5 – (pin 16) SDO data output
PIN_C3 – (pin 14) SCK Clock

16F877A
PIN_C4 – (pin 23) SDI data input
PIN_C5 – (pin 24) SDO data output
PIN_C3 – (pin 18) SCK Clock

PIN_C3 of 16F877A is connected to PIN_C3 of 16F873A
PIN_C4 of 16F877A is connected to PIN_C5 of 16F873A
PIN_C5 of 16F877A is connected to PIN_C4 of 16F873A

Both PICs are mounted on the same board.
Both of them are powered by the same power supply.
PIN_B2 of the slave micro controller is connected to the LED.

Actually all the physical connections are correct according to the data sheet of the micro controllers.

Once again thanks for your help.
Kushan
_________________
Kushan Sharma
mlkushan@gmail.com
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Dec 22, 2008 1:07 am     Reply with quote

I would add the Slave Select signal.

1. Choose a general purpose i/o pin on the master PIC to use for it.
Connect that pin to the \SS pin on the slave PIC.

2. Add lines of code to the master PIC, to surround the spi_write() line
with statements that set \SS low, and then high again when the operation
is done.

3. Add a line of code in the Master PIC to initialize the Slave Select pin
to a high level at the start of main().

4. Edit the setup_spi() statement in the slave to delete the parameter
that disables Slave Select.

5. Re-compile the code for both master and slave, and re-program
both PICS with the revised code.
Ttelmah
Guest







PostPosted: Mon Dec 22, 2008 3:47 am     Reply with quote

There is a general problem, when using SPI, with initial synchronisation.
In your case, if one chip 'wakes' fractionally before the other, or there is noise on the SCK line as the chips wake up, the two chips will never get synchronised, so the second will never see '0xAA'
Now, two solutions exist for this:
1) Use the SS line. This is what it is for.
2) Have a 'sync' strategy.
Now, in your case, the 'idle' level of the clock line, will be low. So, a 'workable' strategy would be:
Add a pull-up resistor to the SCK line - perhaps 100KR. Just enough to ensure that the line will float _high_ if not driven.
Have the master, pause for a moment, then setup the SPI, then pause again. So, something like:
Code:

   delay_us(100); //This ensures the slave has time to wake before master
   setup_spi(SPI_MASTER|SPI_MODE_0|SPI_CLK_DIV_4);
   delay_us(100);


Then have the slave, wait for the line to go _low_ before setting up it's SPI.

Code:

   while (input(PIN_C3)) ; //This will wait for the line to be driven
   setup_spi(SPI_SLAVE|SPI_MODE_0|SPI_SS_DISABLED);


Ideally, there are even more complex strategies to ensure that sync is reacquired if lost, but this should get it going, if you don't want to use another pin.

Best Wishes
mlkushan



Joined: 16 Nov 2008
Posts: 22
Location: Sri Lanka

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Mon Dec 22, 2008 3:53 am     Reply with quote

Thanks for your help,
I made required changes as bellow.
But unfortunately once it is implemented, the master pic get drastically overheated.

At the Master
Code:

.............
   output_high(PIN_A5);           //slave select pin is high at the start.
   
   while(true){
      delay_ms(10000);            //wait 10 sec before transmit data to the slave
     
      output_low(PIN_A5);         //set \SS low, and then high again when the operation is done.
      spi_write(0xAA);
      delay_us(100);
      output_high(PIN_A5);
   }
........


At the slave
Code:

.........
setup_spi(SPI_SLAVE|SPI_MODE_0);
.........


Once again thanks a lot.
Kushan
_________________
Kushan Sharma
mlkushan@gmail.com
Ttelmah
Guest







PostPosted: Mon Dec 22, 2008 6:31 am     Reply with quote

What is A5 connected to?.
If the chip is getting hot, it is almost certainly tied high or low, and when you drive it, the chip is driving into a short circuit....
Check your wiring.

Best Wishes
mlkushan



Joined: 16 Nov 2008
Posts: 22
Location: Sri Lanka

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Mon Dec 22, 2008 7:16 am     Reply with quote

Thanks for helping me,

PIN_A5 of 16F877A is connected to the PIN_A5 of 16F873A as the slave selection pin. At the initial stage i did testings by disabling the slave selection. Since it didn't work. I moved on to the second method with the slave selection enabled (that method was suggested here by PCM programmer).

Now i have permanently mounted the cct. So now it does not heat up. Now i am sure about the wiring and that there can't be any errors. But still the LED doesn't light up.

Thanks you all and highly appreciated all your helps
Kushan
_________________
Kushan Sharma
mlkushan@gmail.com
Ttelmah
Guest







PostPosted: Mon Dec 22, 2008 8:06 am     Reply with quote

Permanently mounting should have nothing to do with the chip heating. The chip heating, when a pin is driven, more than it does when the pin isn't driven, if the pin is only switched at a slow rate, _implies_ the line is driving a significant load. Check it with a voltmeter. Does it go high when you drive it high, and low when you drive it low?. What happens to the board current when you drive it?. Seriously, this is probably why it didn't work in the first place....

Best Wishes
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