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?

+3


source to share


1 answer


  • Keeping scom.h as it is, your app.c should have #include "scom.h"

  • Confirm that the i

    type variable is byte

    declared as volatile byte i;

    and is not updated anywhere else in the code after the ISR is executed and before it is assigned j

    in func()

    .

  • 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 it i

    will execute locally due to block scope. you said, that

    after 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)

.

0


source







All Articles