View previous topic :: View next topic |
Author |
Message |
Sophi
Joined: 14 Jun 2005 Posts: 64
|
Global variable is passed incorrectly |
Posted: Tue Apr 25, 2006 9:45 pm |
|
|
Hi-
I want to pass ad12temp between main and an interrupt. When I interrupt, the value passed is incorrect. I know this because the wrong condition is returned. I thought it was because I am comparing a float to an int (float ad12temp to 65) but changing this to long int doesn't help.
I am not sure if this syntax is correct either
if(ad12temp >= 45 && ad12temp <= 75)
Thank you in advance-
SophE
The portion inside the main is
ad12temp = read_analog(1) >> 4; // get a/d value (channel 1) and shift
ad12temp = 0.035*ad12temp - 0.828; // convert to Fahrenheit
The code inside of the interrupt follows.
Code: |
float ad12temp; //define global variable
#INT_COMP
comp_isr(){
int reg_read;
int data;
int32 j;
output_float(PIN_C3); // init 24256 eeprom by setting pin high
output_float(PIN_C4);
delay_ms(25); // debounce
if (ad12temp >= 75) {
i2c_start();
i2c_write(0b10100011); // 1010 (r/w), eeprom address 100, 1 for read
printf(lcd_putc,"\fAbove 65 ");
for(j=0; j <= 18600; j++){
data = i2c_read();
portb = data;
delay_us(8);
}
}
if(ad12temp >= 45 && ad12temp <= 75){
i2c_start();
i2c_write(0b10100001); // Sequential read
printf(lcd_putc,"\fBetween 45 and 65 ");
for(j=0; j <= 19000; j++){
data = i2c_read();
portb = data;
delay_us(8);
}
}
if (ad12temp < 45) { // hot
i2c_start();
i2c_write(0b10100101); // Sequential read
printf(lcd_putc,"\fBelow 65 ");
for(j=0; j <= 29000; j++){
data = i2c_read();
portb = data;
delay_us(8);
}
} |
[/code] |
|
|
kypec
Joined: 20 Sep 2003 Posts: 54
|
|
Posted: Tue Apr 25, 2006 11:40 pm |
|
|
I'm not sure whether I'm right but what I see as potential cause of your problems is that the ad12temp is a FLOAT variable, which means it occupies 4 bytes in RAM memory. When your main routine modifies that variable via Code: | ad12temp = read_analog(1) >> 4; // get a/d value (channel 1) and shift
ad12temp = 0.035*ad12temp - 0.828; // convert to Fahrenheit | and the interrupt occurs just in the middle of execution of these statements then the ad12temp would contain only partially processed value, for instance 1st byte is already properly loaded with new result of mathematical operation whereas the other 3 bytes still retain some old values. This condition renders the whole ad12temp content invalid for your evaluations inside ISR.
The workaround could be disabling interrupts in main routine before you start modifying the variable and re-enabling it once you have done all your calculations. |
|
|
Guest
|
|
Posted: Wed Apr 26, 2006 6:32 am |
|
|
kypec-
thank you for the suggestion- I am going to try that later tonight. I should have disabled interrupts anyway before performing a passed variable calculation! sigh- that's how to learn.....
Sophi |
|
|
JoTrait Guest
|
|
Posted: Thu Apr 27, 2006 11:38 am |
|
|
I would also change
Code: |
if(ad12temp >= 45 && ad12temp <= 75)
|
to:
Code: |
if((ad12temp >= 45) && (ad12temp <= 75))
|
I don't know if the first expression evaluates correctly to begin with, but its better to make sure.
Just my two cents.... |
|
|
|