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

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



Joined: 10 Apr 2008
Posts: 2

View user's profile Send private message

SPI
PostPosted: Thu Apr 10, 2008 2:49 am     Reply with quote

How can I interface two 16F877A through SPI?
Matro
Guest







PostPosted: Thu Apr 10, 2008 3:12 am     Reply with quote

Connect SCK of both together, and SDI of each with SDO of the other.
Choose which part is the master and which one is the slave.

That's done.

Matro.
Guest








PostPosted: Thu Apr 10, 2008 7:48 am     Reply with quote

I'm doing exactly the same, making a bidirectional link and have made these connections.

Is it then a case of simply using spi_read() and spi_write()? Are there any good intro websites to SPI that apply to CCS c code?
Matro
Guest







PostPosted: Thu Apr 10, 2008 8:07 am     Reply with quote

Basically, just a correct and appropriate use of spi_write() and spi_read() is enough to make both PIC communicate.
No idea for a website...

Matro.
ckielstra



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

View user's profile Send private message

PostPosted: Thu Apr 10, 2008 8:14 am     Reply with quote

Also have a look at the CCS provided example files:
Quote:
EX_SPI.C
Communicates with a serial EEPROM using the H/W SPI module

EX_SPI_SLAVE.C
How to use the PIC's MSSP peripheral as a SPI slave. This example will talk to the ex_spi.c
example.
Hanzala Hussain



Joined: 10 Apr 2008
Posts: 2

View user's profile Send private message

PostPosted: Thu Apr 10, 2008 9:16 am     Reply with quote

This is the code I am trying but not getting the desired result on both ends(both on master and slave) Crying or Very sad

Code:


// I ma using
//RC6 = clock
//RC5 = Data out
//RC4 = Data in
//for both master as well as slave.

//  Master Program

#include <16F877A.h>
#fuses NOWDT,NOPROTECT,XT,NOLVP,PUT
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)



int8 data = 0;


void main()
{

setup_spi( SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16 );

while(1)
{

spi_write(0x01);
If(!spi_data_is_in());
data = spi_read();
printf("\n\rdata = %u",data);

}
}




//SLAVE program

#include <16F877A.h>
#fuses NOWDT,NOPROTECT,XT,NOLVP,PUT
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)


int8 value = 0;

void main( )
{

setup_spi( SPI_SLAVE | SPI_L_TO_H | SPI_SS_DISABLED );





output_high( PIN_C4 );

while( 1 )
{
if (!spi_data_is_in());

value = spi_read( );
spi_write(0x55);



printf( "\n\r data = %u", value );
}



}

Help me Confused
Guest








PostPosted: Thu Apr 10, 2008 9:30 am     Reply with quote

Yep, that's what I came up with, and mine doesn't work either!

Do we need to toggle a CS pin and poll for that change?



The reciever (master)

while(true)
{
printf("\tWaiting for data .. \n\r");
delay_ms(1000);

if(spi_data_is_in())
{
printf("\tData here!\n\r");
data_in = spi_read();
printf("%c\n\r", data_in);
}
}




And the transmitter (slave)


while(true)
{
printf("\tEnter character:\n\r");

while(flag == 0)
{
delay_us(1); //wait for user
}

printf("\t%c\n\r", data_in);
printf("\tWriting .. \n\r");
spi_write(data_in);
printf("\tDONE!\n\r");
delay_ms(20);
flag = 0;

}


}


#INT_EXT
void RS232_receive(void)
{
data_in = getc();
flag = 1;
}
Matro
Guest







PostPosted: Thu Apr 10, 2008 9:48 am     Reply with quote

You especially need a "#use spi" line to configure your SPI.

Add this line with correct parameters (report to help or reference manual) and it should be definitely better.

Matro.
ckielstra



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

View user's profile Send private message

PostPosted: Thu Apr 10, 2008 11:02 am     Reply with quote

Matro wrote:
You especially need a "#use spi" line to configure your SPI.

Add this line with correct parameters (report to help or reference manual) and it should be definitely better.
#use spi is new in the v4 compilers. In the code above the older function setup_spi() is called which is less versatile but will do the job.

In the above code the main problem is in the master. Remember that in SPI data is being sent and received at the same time. So when the master sends a byte it will receive a byte at the same time, that's why calling the function spi_data_is_in() on the master makes no sense; after every transmission this function will return TRUE.

Another gotcha is that on the master you can call the spi_read() function in two different ways:
- With parameter: the passed value will be clocked out and the data received will be returned.
- Without parameter: returns the last received value. Note that no clock generated and it doesn't wait for a slave response !!
If you want to receive data from the slave but the master has nothing to send, then pass a dummy 0 value.

On a slave calling spi_read() without parameter will wait until a character is received.

The master code could then look something like:
Code:
while(1)
{
   spi_write(0x01);         // Send command to slave
   delay_ms(1);             // Allow slave time to process the command
   data = spi_read(0);      // Get slave response. Note the dummy 0 parameter to generate the clock signal
   printf("\n\rdata = %u",data);

   delay_ms(1000);
}


One remaining problem is that there is no mechanism present to detect synchronization problems. What will happen if the slave misses a byte? How to get it back in sync?
The easiest solution here is to implement a Chip Select signal which goes active at the start of communication and inactive when finished. The slave hardware does have this input. On the master you can choose any output pin and toggle it from software.
ckielstra



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

View user's profile Send private message

PostPosted: Thu Apr 10, 2008 11:08 am     Reply with quote

Another problem: Make sure the master and slave use the same SPI mode configuration. Now the master uses SPI_H_TO_L and the slave SPI_L_TO_H.
Guest








PostPosted: Fri Apr 11, 2008 2:34 am     Reply with quote

Thanks, will try today.

I'm used to assembly programming for the PIC, is there any way to know which registers are being set by CCS c-compiler function? The Microchip datahseets are excellent for an assembly programmer, I don't see the same detail for the compiler - it makes things less certain.
Matro
Guest







PostPosted: Fri Apr 11, 2008 2:37 am     Reply with quote

Look at the .lst file that is generated at compilation.
That is the ASM code produced by the compiler.

Matro.
Guest








PostPosted: Fri Apr 11, 2008 2:45 am     Reply with quote

Yep, just found it. Thanks!
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