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 support@ccsinfo.com

SPI help, data not transmitting correctly between 2 PICS

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



Joined: 06 Oct 2006
Posts: 44

View user's profile Send private message

SPI help, data not transmitting correctly between 2 PICS
PostPosted: Sun Nov 18, 2007 4:32 pm     Reply with quote

I am trying to get a Master/Slave communication between PICS. The code below basically takes an input over RS232, sends the data to the slave, and the slave sends a value back. I have it right now so that I can send multiple values back, but I am using just sending one 8 bit int.

Here is the output from the Master over RS232 below. I first inserted the value '1', but the display says I 49! Am I casting the values wrong??? Then the received value is 255, when I am trying to send the value '28'. This received value seems to change each time around also, when I am keeping it constant.

BOOT
Please Insert a Number: 49
The Number has Changed, Time to send over SPI.
Data sent/received
Value received = 255
Waiting for Input...
Waiting for Input...
Waiting for Input...
Please Insert a New Number: 50
The Number has Changed, Time to send over SPI.
Data sent/received
Value received = 0
Waiting for Input...
Waiting for Input...
Waiting for Input...
Waiting for Input...
Please Insert a New Number: 51
The Number has Changed, Time to send over SPI.
Data sent/received
Value received = 50
Waiting for Input...

MASTER CODE
Code:

//Master SPI Code

#include <18F452.h>
#use delay(clock=20000000)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#FUSES HS,NOWDT,NOPROTECT,NOLVP

#DEFINE   SLAVE_CS        PIN_D3
#DEFINE   NUMBEROFBYTES   1
#DEFINE   LED             PIN_C2

void setup( void );
int8 *use_SPI( int8 , int );

void main()
{
   int i;
   int8 a,b;
   int8 received_values[NUMBEROFBYTES];

   setup();

   output_high(SLAVE_CS);         //Turn CS High so that it is OFF!

   printf("\n\rPlease Insert a Number: ");
   a = (int8) getc();
   printf("%u\n\r", a);

   while(1)
   {
      if( kbhit() )
      {
         b = getc();            //Don't use Last Keypress for New Number
         printf("Please Insert a New Number: ");
         b = (int8) getc();
         printf("%u\n\r", b);
      }

      if( b!=a )
      {
         a = b;
         output_high(LED);
         printf("The Number has Changed, Time to send over SPI.\n\r");
         *received_values = use_SPI( b, NUMBEROFBYTES );       //Get received values and begin communications
         printf("Data sent/received\n\r");
         for( i=0; i<NUMBEROFBYTES; i++ )
         {
            printf("Value received = %u\n\r", received_values[i]);
         }
         output_low(LED);
      }

      else
      {
         Printf("Waiting for Input...\n\r");
         delay_ms(1000);
      }
   }
}

void setup( void )
{
   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
}

int8 *use_SPI( int8 b, int bytes)
{
   int i;
   int8 received_values[NUMBEROFBYTES];

   output_low(SLAVE_CS);        //Turn CS Low so that it is ON!
   spi_write(b);                //Send b, expect nothing in return
   delay_us(50);                //Pause for write to occur
   for( i=0; i<bytes; i++ )
   {
      received_values[i] = spi_read(0);   //Read data from slaves spi_read(data) command;
      delay_us(50);

   }
   output_high(SLAVE_CS);        //Turn CS high so that it is OFF!
   return *received_values;
}


SLAVE CODE
Code:

//Slave SPI Code

#include <18F452.h>
#use delay(clock=20000000)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#fuses HS,NOWDT,NOPROTECT,NOLVP

#DEFINE   SLAVE_CS        PIN_D3
#DEFINE   NUMBEROFBYTES   1
#DEFINE   LED             PIN_C2

void setup( void );
void use_SPI( int8 *, int );

void main()
{
   int8 sent_data[NUMBEROFBYTES] = {28};
   
   setup();

   while(1)
   {
      if( spi_data_is_in() && !input(SLAVE_CS) )
      {
         use_SPI( sent_data, NUMBEROFBYTES );   //Send Data
      }
      else
      {
         printf("\n\rWaiting for data...");
      }
   }
}

void setup( void )
{
   //enable_interrupts(INT_SSP);
   //enable_interrupts(GLOBAL);
   setup_spi(SPI_SLAVE|SPI_L_TO_H);
}

void use_SPI( int8 *sent_data, int bytes)
{
   int i;

   output_high(LED);

   printf("\n\rValue received from Master initiation conversation: %u\n\r", (int8) spi_read());
   for( i=0; i<bytes; i++ )
   {
      spi_write( sent_data[i] );   //Write data to buffer, wait for Masters clock to send
      delay_us(50);                //Wait for Masters clock.
   }
   output_low(LED);
}


I have my pins for the SPI as follow:

MASTER SLAVE
SDO (RC5) ----> SDI (RC4)
SDI (RC4) ----> SDO (RC5)
CLK (RC3) ----> CLK (RC3)
CS (RD3) ----> CS (RD3)[/u]

Am I doing something wrong? Please help, I am stumped, thanks!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Nov 18, 2007 5:07 pm     Reply with quote

Quote:
I first inserted the value '1', but the display says I 49!

The character '1' has a hex value of 0x31, which is a decimal value of 49.

For printf(), the format specifier of %x will display a hex value, and %u
will display an unsigned decimal value.
scaven92



Joined: 06 Oct 2006
Posts: 44

View user's profile Send private message

PostPosted: Sun Nov 18, 2007 5:18 pm     Reply with quote

OK, that makes sense. I have that fixed now, by changing this part of the code:

Code:
a = ( (int8) getc() ) - 48;


This will work perfect for my values 0-9. Now, do you see any errors in my transferring of data over SPI?

Another thing I just noticed since I have updates the char to int conversion is that after the first sent value, the Master receives the same value which I sent. Here is the output from the Master side:

BOOT
Please Insert a Number: 9
The Number has Changed, Time to send over SPI.
Data sent/received
Value received = 0
Waiting for Input...
Please Insert a New Number: 8
The Number has Changed, Time to send over SPI.
Data sent/received
Value received = 8
Waiting for Input...
Please Insert a New Number: 7
The Number has Changed, Time to send over SPI.
Data sent/received
Value received = 7
Waiting for Input...
Please Insert a New Number: 6
The Number has Changed, Time to send over SPI.
Data sent/received
Value received = 6
Waiting for Input...

As you can see, the value that should be received is the value of 28! Also shouldnt the first received value not be zero? It seems like it is receiving zero because nothing is in the output buffer. The first write request from the Master expects nothing in return, and following that clock cycle is a write from the slave, which loads the bufffer with my sent_data = 28. Then on the next spi_read command from the master the clock will generate and that 28 from the buffer should be sent out. Am I right or am I confusing myself?

I don't see how it is acting like a loopback connection.
alfonsol
Guest







PostPosted: Sun Nov 18, 2007 7:18 pm     Reply with quote

when you receive, or send over rs-232 you send the ascii code, not the number itself.

example, if you send 10, you will receive the ascii code for 1, and then the ascii code for 0.

you need to store these characters in a string, and then convert it to int, to do that you must use the instruction atoi

example:
char string[10];

int x;



strcpy(string,"123"); // this stores the ascii codes of this numbers in a string

x = atoi(string);

// x is now 123
scaven92



Joined: 06 Oct 2006
Posts: 44

View user's profile Send private message

PostPosted: Sun Nov 18, 2007 8:50 pm     Reply with quote

I have added a function using your suggestions, with no error checking, which converts my char's from the rs232 to int8. Now I just need to know why the values arent being exchanged properly over SPI! Any ideas?!?! Thanks for the help.

Quote:

int8 getInt( void )
{
char *string;
gets(string);
return atoi(string);
}


I call this function whenever I need input from from RS-232 for numbers. Of course for my case I only can input an 8 bit number so I should be error checking for anything greater then 255, but its not something I am concered with as SPI is the main idea.
meereck



Joined: 09 Nov 2006
Posts: 173

View user's profile Send private message

PostPosted: Mon Nov 19, 2007 3:30 am     Reply with quote

I am not much familiar with pointers, but char *string; seems to be incorrect to me.
Because it is just a pointer, not space in memory.
try to use char string[10];
Am I right?
good luck
SET



Joined: 15 Nov 2005
Posts: 161
Location: Glasgow, UK

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

PostPosted: Mon Nov 19, 2007 5:14 am     Reply with quote

Code:
int8 *use_SPI( int8 b, int bytes)
{
   int i;
   int8 received_values[NUMBEROFBYTES];

   output_low(SLAVE_CS);        //Turn CS Low so that it is ON!
   spi_write(b);                //Send b, expect nothing in return
   delay_us(50);                //Pause for write to occur
   for( i=0; i<bytes; i++ )
   {
      received_values[i] = spi_read(0);   //Read data from slaves spi_read(data) command;
      delay_us(50);

   }
   output_high(SLAVE_CS);        //Turn CS high so that it is OFF!
   return *received_values;
}


This will give you problems - 'received_values' will only exist within the function so the returned pointer will be invalid. Declare the array as a global or 'static'
scaven92



Joined: 06 Oct 2006
Posts: 44

View user's profile Send private message

PostPosted: Mon Nov 19, 2007 1:13 pm     Reply with quote

Your absolutely right, I either need a global one or pass the memory space to the function. I will fix that and check it.

As for the char *string, I think I can do that, although I am not specifiying how large. I think your right and its not a good idea and I will fix that.


Ok I check it and it is still outputing the same thing as before, as if it is looping the same data back. Here is my updated code.

MASTER CODE
Code:

//Master SPI Code

#include <18F452.h>
#include <stdlib.h>

#use delay(clock=20000000)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#FUSES HS,NOWDT,NOPROTECT,NOLVP

#DEFINE   SLAVE_CS        PIN_D3
#DEFINE   NUMBEROFBYTES   1
#DEFINE   LED             PIN_C2

void setup( void );
void use_SPI( int8 , int );
int8 getInt( void );

int8 received_values[NUMBEROFBYTES];

void main()
{
   int i;
   int8 a,b = 0;
   //int8 received_values[NUMBEROFBYTES];

   setup();

   output_high(SLAVE_CS);         //Turn CS High so that it is OFF!

   printf("\n\rPlease Insert a Number: ");
   a = getInt();
   printf("%u\n\r", a);

   while(1)
   {
      if( kbhit() )
      {
         b = getc();            //Don't use Last Keypress for New Number
         printf("Please Insert a New Number: ");
         b = getInt();
         printf("%u\n\r", b);
      }

      if( b!=a )
      {
         a = b;
         output_high(LED);
         printf("The Number has Changed, Time to send over SPI.\n\r");
         use_SPI( b, NUMBEROFBYTES );
         printf("Data sent/received\n\r");
         for( i=0; i<NUMBEROFBYTES; i++ )
         {
            printf("Value received = %u\n\r", received_values[i]);
         }
         output_low(LED);
      }

      else
      {
         Printf("Waiting for Input...\n\r");
         delay_ms(1000);
      }
   }
}

void setup( void )
{
   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
}

void use_SPI( int8 b, int bytes)
{
   int i;

   output_low(SLAVE_CS);        //Turn CS Low so that it is ON!
   spi_write(b);                //Send b, expect nothing in return
   delay_us(50);                //Pause for write to occur
   for( i=0; i<bytes; i++ )
   {
      received_values[i] = spi_read(0);   //Read data from slaves spi_read(data) command;
      delay_us(50);

   }
   output_high(SLAVE_CS);        //Turn CS high so that it is OFF!
}

int8 getInt( void )
{
   char string[4];    //Only allowed to insert a number of length 3.
   gets(string);
   return atoi(string);
 }
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