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

How stored a float variable in the eeprom of pic

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



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

How stored a float variable in the eeprom of pic
PostPosted: Fri Sep 25, 2009 4:33 pm     Reply with quote

Hi need to store float variable (Valor_ADC0) in the eeprom of pic, how I can do it??

Here is my code:
Code:

#include <18F452.h>
#DEVICE ADC=8
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)// RS232 Estándar

void main() {

   int32 Buffer_ADC0;
   float Valor_ADC0;   

   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_DIV_32);
   set_adc_channel(0);
   delay_us(10);
   
while (TRUE){

    set_adc_channel(0);
   delay_us(4);
    Buffer_ADC0 = read_adc();
    delay_us(10);
    Valor_ADC0 =  (float)Buffer_ADC0 *(0.0529);
    printf("%4.2f \r\n", Valor_ADC0);
   
     }   
  }
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 25, 2009 4:36 pm     Reply with quote

Look in this file for routines to do this:
Quote:
c:\program files\picc\drivers\internal_eeprom.c


Or look at this FAQ article:
http://www.ccsinfo.com/faq.php?page=write_eeprom_not_byte
Ttelmah
Guest







PostPosted: Sat Sep 26, 2009 3:04 am     Reply with quote

Also though, look at the write life limitations of the EEPROM.

The code shown, will probably kill the EEPROM, in a couple of hours, and 'worst case' (maximum operating temperature, and a bad chip example), could do it in under ten seconds....

The EEPROM, is _not_ designed to hold values that are changing fast/frequently. You need to rethink the approach, if you want to store a value being read fast. Either use RAM, and store it to the EEPROM, only when power goes off, or use an external memory without the limitations (FRAM).

Best Wishes
Guest








PostPosted: Sat Sep 26, 2009 6:16 am     Reply with quote

Another option, if you're always sending it to a PC ( the print line..), is to have the PC store the data for you.

Jay
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

PostPosted: Mon Sep 28, 2009 8:49 am     Reply with quote

Hi, I tried using the examples that you refer me but I can not write or read the float data correctly in eeprom, someone could tell me what my mistake?.
The maximum value of the ADC input is 5V equivalent to 13.45.

Code:
#include <18F452.h>
#DEVICE ADC=8
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)// RS232 Estándar

int j;
float data;

void Write_Float_Eeprom(address, float data)
{
   int8 i;
   for(i = 0; i < 16; ++i){
     write_eeprom(address + i, *((int8 *)(&data) + i));
   }
}

float Read_Float_Eeprom( address)
{
   int8 i;
   float data;
   for(i = 0; i < 16; ++i)
   {
     *((int8 *)(&data) + i) = read_eeprom(address + i);
   }
   return data;
}


void Init_EEprom(){
   for(j = 0; j < 16; ++j){
        write_eeprom(j,0xff);
   }
}

void main() {

   int32 Buffer_ADC0;
   float Valor_ADC0;   

   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_DIV_32);
   set_adc_channel(0);
   delay_us(10);

   Init_EEprom();
   
   set_adc_channel(0);
   delay_us(4);
   Buffer_ADC0 = read_adc();
   delay_us(10);
   Valor_ADC0 =  (float)Buffer_ADC0 *(0.0529);
   printf("%4.2f \r\n", Valor_ADC0);

   Write_Float_Eeprom(0,Valor_ADC0);
   delay_us(200);
   Read_Float_Eeprom(0);
   printf("%4.2f \r\n", data);


while (TRUE);   
  }
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Sep 28, 2009 9:30 am     Reply with quote

Are there any indications of float occupying 16 bytes with CCS C? It doesn't, you're definitely writing out of bounds.

Also Read_Float_Eeprom() goes to nowhere in your code.
Ttelmah
Guest







PostPosted: Mon Sep 28, 2009 9:44 am     Reply with quote

Let's explain what Fvm is saying about read_float_eeprom.
You have a global variable called 'data'. You don't write to this anywhere.
You have a local variable called 'data'. You write to this, and then to twelve more bytes in memory, 'beyond' this, potentially destroying other variables.
You then return a value in this, and don't store the return anywhere.

Not surprising if you don't see what you expect...

Best Wishes
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

PostPosted: Mon Sep 28, 2009 9:48 am     Reply with quote

Quote:
Are there any indications of float occupying 16 bytes with CCS C? It doesn't, you're definitely writing out of bounds


Quote:
How do I write variables to EEPROM that are not a byte?
The following is an example of how to read and write a floating point number from/to EEPROM. The same concept may be used for structures, arrays or any other type.

n is an offset into the eeprom.
For example if the first float is at 0 the second
For floats you must increment it by 4.
one should be at 4 and the third at 8.

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);
}


Sad I'm lost, I do not understand ???
Ttelmah
Guest







PostPosted: Mon Sep 28, 2009 9:58 am     Reply with quote

Look, the example shows exactly what you need. Four bytes, not 16.
Then if a function _returns_ a value, you need to retrieve this in your program. So:

your_variable=READ_FLOAT_EXT_EEPROM(0);

not just calling the function...

Then, key change that needs to be made. The example, uses the functions to talk to an _external_ eepom, you need to use the functions for the internal eeprom instead.

The functions you have written, are correct, _except_ for trying to use 16bytes, instead of 4, and you are not reading the returned value.

Best Wishes
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

PostPosted: Mon Sep 28, 2009 10:18 am     Reply with quote

Very Happy hi Ttelmah, thank you, now it is working....
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

PostPosted: Mon Sep 28, 2009 10:55 am     Reply with quote

Sorry by my insistence, but now I need to convert this float value to a string Valor. I tried to use the itoa but I can not get the correct value. Which is my mistake?
Code:
 
char Valor[6];
.
.
.
Write_Float_Eeprom(0,Valor_ADC0);
delay_us(200);
buffer = Read_Float_Eeprom(0);

itoa(buffer,10, Valor);
Ttelmah
Guest







PostPosted: Mon Sep 28, 2009 12:25 pm     Reply with quote

The 'i', in 'itoa', is for _integer_....

You can sprintf to a string, or for a fixed precision (faster), multiply your float by (say) 100, and convert this to integer, then just add a decimal point (for sprintf, look at %w).

Best Wishes
pilar



Joined: 30 Jan 2008
Posts: 197

View user's profile Send private message

PostPosted: Mon Sep 28, 2009 2:27 pm     Reply with quote

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