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

sending 2 adc values through spi

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



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

sending 2 adc values through spi
PostPosted: Sat Apr 19, 2008 4:52 am     Reply with quote

Hi everyone;
I am reading 2 adc values from 1 microcontroller(PIC16f877a) and want to send these both values to another microcontroller(PIC16f877a) through spi.i have written a code which send only 1 adc value.here is the code

code for slave
Code:

#define first(x, offset)\ 
*((int8 )&x +offset)  //function for breaking floating number into 4 bytes.


/*#define MakeDWord(x, b3, b2, b1, b0)  \
*(int8 *)&x = b0;      \
*((int8 *)&x +1) = b1; \
*((int8 *)&x +2) = b2; \
*((int8 *)&x +3) = b3*/

void main()
{
   
   float  value,adc1,adc2;
   int8 b0, b1, b2, b3;
   setup_adc_ports(ALL_ANALOG);
   setup_adc(ADC_CLOCK_INTERNAL );
   setup_psp(PSP_DISABLED);
   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);
   setup_spi(SPI_SLAVE | SPI_L_TO_H | SPI_CLK_DIV_4);
   
   while(1)
   {
    if(input(PIN_A5)==0)
      {
       set_adc_channel(0);
       delay_us(10);
       adc1=read_adc();
       adc2=(adc1*5)/1024;
       value =adc2;
       printf("first no is = %2.2f \n\r", value);
             
       // Break the float into 4 bytes.
       b0 = first(value, 0);
       b1 = first(value, 1);
       b2 = first(value, 2);
       b3 = first(value, 3);
             
       //send 4 bytes one by one through spi
       spi_write(b0);
       spi_write(b1);
       spi_write(b2);
       spi_write(b3);
      }
      else
      {
       delay_cycles(100);
      }
      }
}


code for master
Code:

#define MakeDWord(x, b3, b2, b1, b0)  \
*(int8 )&x = b0;      \
*((int8 )&x +1) = b1; \
*((int8 )&x +2) = b2; \
*((int8 )&x +3) = b3      //fuction for joining 4 bytes and give result in
                          //floating number.

float readnum(void);
void main()
{
   float num;
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   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!!
   output_high(PIN_A5);
   
   setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_4);
   
   while(1)
   {
    num=readnum();
    printf("no is:%2.2f \n\r",num);
    delay_ms(100);
    }
}

float readnum(void)
{
   int8 b0,b1,b2,b3;
   float result;
   
   output_low(PIN_A5);
   delay_us(100);
   b0=spi_read(0);
   b1=spi_read(0);
   b2=spi_read(0);
   b3=spi_read(0);
   MakeDWord(result, b3, b2, b1, b0);
   output_high(PIN_A5);
   return result;
}


Now the question is that how i send 2nd value(which is from channel 1) through spi and what will be the timings of sending and reciving of these 2 values.
Thankx in Advance.
ckielstra



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

View user's profile Send private message

PostPosted: Sat Apr 19, 2008 8:42 am     Reply with quote

Code:
setup_spi(SPI_SLAVE | SPI_L_TO_H | SPI_CLK_DIV_4);
An SPI slave never generates a clock signal, so using an SPI_CLK_DIV_x is a bug. You are lucky it works because SPI_CLK_DIV_4 is defined as zero and has no effect in your code. Remove this define to prevent difficult to find future errors.

Code:
#define first(x, offset)\
*((int8 )&x +offset)  //function for breaking floating number into 4 bytes.


/*#define MakeDWord(x, b3, b2, b1, b0)  \
*(int8 *)&x = b0;      \
*((int8 *)&x +1) = b1; \
*((int8 *)&x +2) = b2; \
*((int8 *)&x +3) = b3*/
For your info: The CCS compiler functions make8() and make32() do exactly the same thing but because they are internal to the compiler are way more efficient.

Code:
float  value,adc1,adc2;
...
adc1=read_adc();
You are wasting memory as the function read_adc() returns returns an 8- or 16-bit integer value (1 or 2 bytes, depending on settings) and a float takes 4 bytes.

A design tip: Do the conversion from the integer A/D-value to a float not in the slave but in the master. This way you have less data to transmit and a higher accuracy (because of rounding errors an integer is more accurate than a float). Do the conversion to float as late as possible, preferably only when showing the calculated result to the user.

Quote:
Now the question is that how i send 2nd value(which is from channel 1) through spi and what will be the timings of sending and receiving of these 2 values.
Communications between master and slave over SPI have been discussed many times on this forum, try searching this forum.

A universal system which is easy to extend for future expansions would be to implement some kind of message system where the master sends a command to the slave and the slave responds with an answer. For example:
    - Master says 'Give me the data of channel 1'
    - Slave keeps telling 'I'm busy, please wait'
    - When data is present the slave says 'Great master, here is your requested data'.
Adding new channels is easy and you will not get the timing problems you are afraid of.
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

PostPosted: Mon May 12, 2008 5:16 am     Reply with quote

Thanks ckielstra for lot of ur suggestions as i was busy in my other project that's why i am replying late.
i am using ccs compiler version 4.020
as u say that i can use make32 function instead of my own function.
when i use make32 function the floating value is converted into 32 bit integer and when i use make8 function the value is converted into an 8 bit integer but how i convert this value into float again.how i do this?
for example
i have an floating number that is 4.52.
now tell me that how i convert it into 32 bit and send it through spi
and again convert it into floating number.
thanks in advance.
Ttelmah
Guest







PostPosted: Mon May 12, 2008 7:46 am     Reply with quote

Personally even 'better', use a union:
Code:


union convert {
    int8 b[4];
    float fpval;
} val;


val.b[0] to val.b[3], are the four bytes making up the floating point value 'val.fpval'. You can use this to go both ways,and it generates similar code to the make8/make32 version.
You can (obviously) use the same 'trick' with make32, so:
Code:


union intfp {
   int32 word;
   float fpval;
} val2;


You then just put the result of the make32, into val2.word, and can read the float value as val2.fpval.

Best Wishes
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

PostPosted: Tue May 27, 2008 1:21 am     Reply with quote

Ttelmah thanks for ur reply.
But i am not getting the point that how i convert floating number into 32 bit int and again convert the 32 bit int into floating number using union method.Kindly give me a proper example so that i run the program and check its functionality.plz.
I am at a begineer level and not know much.
Thanks in advance.
Ttelmah
Guest







PostPosted: Tue May 27, 2008 3:26 am     Reply with quote

The 'point' about a union, is it allows multiple variables to 'share' the same memory area. So, if you have a union:
Code:

union demo {
    int32 32bitval;
    float fpval;
    int8 b[4];
} shared;


Then you have a floating point variable 'shared.fpval', and a int32 variable 'shared.32bitval', and also an array of four 8bit values 'shared.b[0]' to 'shared.b[3]', _all of which are stored in exactly the same memory locations_.
Now, you can take a floating point number, and put it into the floating variable, say:

shared.fpval=1.2345;

and then if you print the int32 number, with:

printf("%8x",shared.int32);

you will get the eight hex characters '19041E7F', corresponding to the four bytes used to represent the float in memory. You can also access the bytes individually using the byte array.
Think of it a bit like a tape measure, that has got both inches, and mm, written on it's face. You can move 'along' to 4", and just read off the other edge, that this is 101.6mm, or move along to 600mm, and read the other way, that this is 23.62". Just like with the tape measure, no actual 'maths' is involved, it just allows you to see the two different representations at the same time.
You can write or read in either direction (or three ways with the int8/int32/float example given above), and no actual 'work' is involved from the compiler, since it just 'looks' at the same data using the different representations selected. This makes the union fast, and a very powerful way of accessing the values stored in one form, using a different representation.

Best Wishes
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

PostPosted: Wed May 28, 2008 1:26 am     Reply with quote

Thanks again Ttelmah. I am doing the same thing as u said, but I got the result like that 0000007f but not '19041E7F'. What's wrong in my code ?

Code:

void main()
{
   while(1)
   {
   
   union demo
   {
   int32 bitval;
   float fpval;
   }
   val;
   
   val.fpval=1.2345;
   printf("%8x",val.bitval);
   delay_ms(500);
   }
}
Ttelmah
Guest







PostPosted: Wed May 28, 2008 2:32 am     Reply with quote

My error. I missed out the 'L', in the format specifier when I typed it. %8x, only treats the source as an integer (8bit). You need %8Lx to print the 32bit value.

Best Wishes
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

PostPosted: Wed May 28, 2008 3:47 am     Reply with quote

Thanks Ttelmah.It is working now.One more question can i send this int32 bit value through spi or first i have to break it into 4 8bit integer.

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