View previous topic :: View next topic |
Author |
Message |
hemnath
Joined: 03 Oct 2012 Posts: 241 Location: chennai
|
datatype problem |
Posted: Fri Dec 06, 2013 10:25 pm |
|
|
Hi,
I'm using PIC18F2520, CCS C Compiler, Version: 4.114, Oscillator: 2Mhz
Reading eeprom values, but the values are wrong. Why is it so?
reading a 16 bit number and saving it in float. It creates problem. Why is it?
sample program:
Code: | #include "18F2520.h"
#fuses INTRC_IO
#use delay(clock = 2000000)
#define LOW_CAL_ADC_ADDRESS 20
#define LOW_CAL_DISP_ADDRESS 30
#define HIGH_CAL_ADC_ADDRESS 40
#define HIGH_CAL_DISP_ADDRESS 50
float adc_span;
float disp_span;
float leastcount;
#define INT_EEPROM_ADDRESS int8
void write_int16_eeprom(INT_EEPROM_ADDRESS address, int16 data);
int16 read_int16_eeprom(INT_EEPROM_ADDRESS address);
// Purpose: Write a 16 bit number to internal eeprom
// Inputs: 1) An eeprom address
// 2) The 16 bit number to write to internal eeprom
// Outputs: None
void write_int16_eeprom(INT_EEPROM_ADDRESS address, int16 data)
{
int8 i;
for(i = 0; i < 2; ++i)
{
write_eeprom(address + i, *((int8 *)(&data) + i));
}
}
// Purpose: Read a 16 bit number from internal eeprom
// Inputs: An eeprom address
// Outputs: The 16 bit number read from internal eeprom
int16 read_int16_eeprom(INT_EEPROM_ADDRESS address)
{
int8 i;
int16 data;
for(i = 0; i < 2; ++i)
{
*((int8 *)(&data) + i) = read_eeprom(address + i);
}
return(data);
}
void main()
{
write_int16_eeprom(LOW_CAL_ADC_ADDRESS, 3000);
write_int16_eeprom(HIGH_CAL_ADC_ADDRESS, 23000);
write_int16_eeprom(LOW_CAL_DISP_ADDRESS, 9000);
write_int16_eeprom(HIGH_CAL_DISP_ADDRESS, 0);
adc_span = read_int16_eeprom(HIGH_CAL_ADC_ADDRESS) - read_int16_eeprom(LOW_CAL_ADC_ADDRESS);
disp_span = read_int16_eeprom(HIGH_CAL_DISP_ADDRESS) - read_int16_eeprom(LOW_CAL_DISP_ADDRESS);
leastcount = disp_span/adc_span;
while(1)
{
}
} |
Read the values in watch window using mplab,
values are,
adc_span = 20000.0000
disp_span = 56536.0000 // wrong value...
leastcount = 2.82680011 |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Dec 07, 2013 12:11 am |
|
|
Quote: | Reading eeprom values, but the values are wrong. Why is it so? |
Learn to trouble-shoot the problem. Use printf to display intermediate
results in the math formula.
Quote: | reading a 16 bit number and saving it in float. It creates problem. |
That's an assumption. Load the result into an int16 value and display
that result with printf. What do you get ? |
|
![](templates/subSilver/images/spacer.gif) |
hemnath
Joined: 03 Oct 2012 Posts: 241 Location: chennai
|
|
Posted: Sat Dec 07, 2013 12:21 am |
|
|
Quote: | Learn to trouble-shoot the problem |
changed the code to
Code: | disp_span = (float)read_int16_eeprom(HIGH_CAL_DISP_ADDRESS) - (float)read_int16_eeprom(LOW_CAL_DISP_ADDRESS); |
value on mplab, disp_span = -9000.
Looks good. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19360
|
|
Posted: Sat Dec 07, 2013 2:03 am |
|
|
It is worth understanding what was wrong.
An 'int' or 'int16', is an _unsigned_ value in CCS.
0-9000 is a _negative_ result. Impossible in an unsigned.
Since integer arithmetic 'wraps', 0-9000 will give 65536-9000 = 56536.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
|