View previous topic :: View next topic |
Author |
Message |
maritto
Joined: 13 Nov 2007 Posts: 11
|
Math operation |
Posted: Sun Nov 18, 2007 11:14 am |
|
|
Hi!
I've got a problem, I'm working with 12F series and I need to use a lot of variables.
In order to store temperature values like 25.5 (just with a decimal), an integer with a decimal, I use a "int16" not a "float" (because it uses 4bytes!).
So when I work with values like 250, 365, 379, those mean 25.0, 36.5 and 37.9
When I store those values in the internal EEPROM, I use this function:
void write_rom(){
write_eeprom(0,rom_p0);
write_eeprom(1,rom_p1);
read_rom();
}
void read_rom(){
rom_p0=read_eeprom(0);
rom_p1=read_eeprom(1);
temp_ref=(int16)(rom_p0*10) + rom_p1;
}
and I read it, to ensure, that the value has been stored.
So at position 0 I store (for example) "36", and at the position 1 I store "5", when I read it I get "36" and "5", so temp_ref=(36*10) + 5 = 365.
But I don't get that value!
If I put an arbitrary value in temp_ref like:
temp_ref=360;
it works, but if I try to read the value from the memory (once the value has been stored), It doesn't work!
Please somebody help me!
Thanks! |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Sun Nov 18, 2007 1:09 pm |
|
|
You didn't say which wrong value you got. However the compiler will scan the operands of an arithmetic operation to find the lowest precision operand and control intermediate results to that precision. This will impact the final result if it exceeds 255 even if it is cast correctly. The static value 10 may well be the issue try 10L and see if it makes a difference |
|
|
Storic
Joined: 03 Dec 2005 Posts: 182 Location: Australia SA
|
|
|
maritto
Joined: 13 Nov 2007 Posts: 11
|
|
Posted: Sun Nov 18, 2007 10:06 pm |
|
|
OK, thanks!
When I use 10L, the program size is reduced, I don't know why!
But the problem persists when I use values above 30.0 (30 and 0).
When I read the EEPROM, and send that values trought the RS232, I get nothing!
this is a pice of the program:
void read_RS232(){
char orden=0;
if(kbhit())
switch((ord=getch()))
{
case 'S':
while(!kbhit()){}
rom_p0=getch();
while(!kbhit()){}
rom_p1=getch();
if((rom_p0<40))
write_rom();
break;
case 'B':
printf(" %d ; %d ; %d\n\r",(int)(temp/10),rom_p0,(int)(temp_ref/10));
break;
}
when i try, for example:
Send 'S', send value 11, send value 05. (11.5), then 'B', to get the response, I get nothing!
Don't know what's wrong!
Thanks 4 helping! |
|
|
maritto
Joined: 13 Nov 2007 Posts: 11
|
|
Posted: Sun Nov 18, 2007 10:23 pm |
|
|
By the way, I always get 63 when the value is between 10 and 30 (the value of rom_p0 and rom_p1)
|
|
|
maritto
Joined: 13 Nov 2007 Posts: 11
|
|
Posted: Sun Nov 18, 2007 10:36 pm |
|
|
OK, the problem is that when I try to send a value between 10 and 30, the program sends 3F 3F.....> 63 63, I don't know why! I'm using Proteus to simulate it!
Thanks! |
|
|
SET
Joined: 15 Nov 2005 Posts: 161 Location: Glasgow, UK
|
|
Posted: Mon Nov 19, 2007 5:47 am |
|
|
Code: | temp_ref=(int16)(rom_p0*10) + rom_p1; |
Try: Code: | temp_ref=((int16)rom_p0)*10 + (int16)rom_p1; |
The compiler then knows to widen rom_p0 to 16 bits before multiplying by 10. The cast before rom_p1 shouldnt be needed, but does no harm. |
|
|
maritto
Joined: 13 Nov 2007 Posts: 11
|
|
Posted: Mon Nov 19, 2007 8:27 am |
|
|
OK!
Thanks a lot!
It is working! |
|
|
|