External variable does not behave as expected
scom.h
extern byte i;
scom.c
byte i;
void interrupt_Rx(void)
{
byte data;
data = SCI0DRL; // data taken from SCI0
i = SCI0DRL;
// code ( in this code, variable i is not used)
}
app.c
#include "Scom.h"
extern byte i;
byte j; // global variable
In one of the functions defined in app.c, I assign i
to j
;
void fun(void)
{
//some code
j=i;
//operations on j;
j = j & 0x0F;
k = j +0x30;
lcd_puta(k);// displaying k on LCD
}
The expected value for j
is j = 0x07
and fork = 0x37
after using a breakpoint when the j=i;
value is j
itself a random value. Why is that? I made a mistake?
source to share
-
Keeping scom.h as it is, your app.c should have
#include "scom.h"
-
Confirm that the
i
type variable isbyte
declared asvolatile byte i;
and is not updated anywhere else in the code after the ISR is executed and before it is assignedj
infunc()
. -
In your function
void fun(void) { //some code j=i; //operations on j; j = j & 0x0F; k = j + 0x30; lcd_puta(k);// displaying k on LCD }
i
is not declared locally in//some code
, otherwise iti
will execute locally due to block scope. you said, thatafter using a breakpoint at j = i; the value of j itself is a random value.
The reading of this is not elaborated if you have a breakpoint after the command, i.e. on the next command or on the line that says i=j;
If the latter case, then, 'j' has not yet been assigned with a value from 'i'. Instead, in the viewport while debugging.
This doesn't look like what's happening in your case, but I can see what j
is a global variable, is it extern
changed elsewhere and changed by some other ISR than the one shown in the post?
By being blind to this piece of code (if any), I can predict that there is a chance that one such ISR (if any) will change the value j
after it is assigned with i
and before printing. For example:
ISR(TIMER_0)
{
//Clear and disable interrupt
j += 1; //can be anything that modifies j.
//Enable interrupt
}
void fun(void)
{
//some code
j=i;
//operations on j;
j = j & 0x0F; // Interrupt received here Or
k = j + 0x30; // Interrupt received here
//Here value of `k` is different than what is expected, obviously
lcd_puta(k);// displaying k on LCD
}
I am assuming it k
has a compatible data type, preferably type byte
.
While this is not a very strict rule, should you declare a variable in the ISR? No, not worth it. Assuming the routines share the same bank of registers, Interruptts can have local variables just like normal functions. But higher levels of optimization in the compiler will automatically move variables into registers, thereby preserving them when an interrupt is triggered. Do not specify byte data;
in void interrupt_Rx(void)
.
source to share