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

Read/write float to ext eeprom

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







Read/write float to ext eeprom
PostPosted: Thu Feb 11, 2010 5:08 am     Reply with quote

Hi, I have a problem with read/write floats to an external ee-prom.
It seems that it will only work up to a "signed 16-bit float", or 32767.0
I'm using CCS ver 4.068, a PIC18F2525.
An M95256 eeprom, and bitbanging it. Everything else is working ok, 8-bits, 16-bits but not floats!
Code:
void write_ext_eeprom(EEPROM_ADDRESS address, BYTE data) {
   BYTE cmd[4];
   BYTE i;
   BYTE wren;
   wren=0x06;
   cmd[0]=data;
   cmd[1]=address;
   cmd[2]=(address>>8);
   cmd[3]=0x02;

   // Wait until the eeprom is done with a previous write
   while(!ext_eeprom_ready());

   oMEM_ON();
   for(i=0; i<8; ++i)
   {
      output_bit(EEPROM_DI, shift_left(&wren,1,0));
      output_high(EEPROM_CLK);
      output_low(EEPROM_CLK);
   }
   oMEM_OFF();
   oMEM_ON();
   for(i=0; i<32; ++i)
   {
      output_bit(EEPROM_DI, shift_left(cmd,4,0));
      output_high(EEPROM_CLK);
      output_low(EEPROM_CLK);
   }
   oMEM_OFF();
}

BYTE read_ext_eeprom(EEPROM_ADDRESS address) {
   BYTE cmd[3];
   BYTE i,data;
   cmd[0]=address;
   cmd[1]=(address>>8);
   cmd[2]=0x03;

   // Wait until the eeprom is done with a previous write
   while(!ext_eeprom_ready());

   oMEM_ON();
   for(i=0; i<24; ++i)
   {
      output_bit(EEPROM_DI, shift_left(cmd,3,0));
      output_high(EEPROM_CLK);
      output_low(EEPROM_CLK);
   }
   for(i=0; i<8; ++i)
   {
      shift_left(&data,1,input(EEPROM_DO));
      output_high(EEPROM_CLK);
      output_low(EEPROM_CLK);
   }
   oMEM_OFF();
   return(data);
}

////////////////////////////////////////////////////////////////////////
void WRITE_FLOAT_EXT_EEPROM(long int n, float data) {

   int i;

   for (i = 0; i < 4; i++)
     write_ext_eeprom(i + n, *((int8 *)(&data) + i) );
}

float READ_FLOAT_EXT_EEPROM(long int n) {

   int i;
   float data;

   for (i = 0; i < 4; i++)
     *((int8 *)(&data) + i)  = read_ext_eeprom(i + n);

   return(data);

}
//////////////////////////////////////////////////////////////////////////////

void WRITE_LONG_EXT_EEPROM(long n, long data)
 {

   int i;

   for (i = 0; i < 2; i++)
     write_ext_eeprom(i + n, *((int8 *)(&data) + i) );
 }
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 11, 2010 12:37 pm     Reply with quote

Post the test program that calls these routines. This program should
write a floating point value to the eeprom, and then read it back, and
display it in a terminal window on a PC. Post the floating point value
that you see in the terminal window.

The test program should be very short, and it must compile without
errors. (Verify that before you post it).

Also, is this test being done in real hardware, or is this a Proteus project ?
picit
Guest







PostPosted: Tue Feb 16, 2010 6:08 am     Reply with quote

just found out that 32767.001 dont work but 32767.01 do work!
So it seems that CCS floats only can handle 8 "signs" long floats??
It isnt in the eeprom, its in the program itself.
I managed to get around the problem by using less decimals..
Altough I cant understand why its so..
Ttelmah
Guest







PostPosted: Tue Feb 16, 2010 6:31 am     Reply with quote

Because of the size of a 'float'.
The single precision 'float' in a PC, or CCS, uses just four bytes. An 8 bit 'exponent' saying where the 'binary point' is. A sign bit, for the mantissa, and a 23bit mantissa. The mantissa, is treated as always having a leading '1', giving it effectively 24bits.
This gives just under 7 digits of useable decimal precision. Anyhing beyond this is 'luck'....
This is always specified for you, in 'float.h' on any C, which specifies the guaranteed precision (only 6 digits!....), and the sizes of the mantissa etc...

Switching to PCD, offers you a double precision 'foat' with 15digits of useable precision.

The 'overhead' of using float, is always that several bits of the binary number are 'lost' to the precision, to handle the exponent.

This is why scaled integers are 'better' for anything working in a limited part of the number line....

Best Wishes
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Feb 16, 2010 6:36 am     Reply with quote

Unfortunately, you didn't give a complete example code, so we can only guess, what's exactly not working in
your code. If you only mean, that 32767.001 isn't exactly reproduced, Ttelmah has given the complete answer.
If you observe other problems than a simple rounding error, you should clarify.
picit
Guest







PostPosted: Tue Feb 16, 2010 9:46 am     Reply with quote

Thanks Ttelmah, exactly the thing.
Its only possible to have a float number up to 32767.000
unless decreasing the precision. I have never thought about it earlier.
Thanks again.
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