外部变量表现不尽如人意

时间:2015-05-21 07:41:45

标签: c embedded extern

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

在app.c中定义的一个函数中,我将i分配给j;

void fun(void)
{
    //some code
    j=i;
    //operations on j;
    j = j & 0x0F;
    k = j +0x30;
    lcd_puta(k);// displaying k on LCD
}

j的预期值为j = 0x07k = 0x37

j=i; j处使用断点后,本身是随机值。 为什么这样?我犯了什么错吗?

1 个答案:

答案 0 :(得分:0)

  1. 按原样保存 scom.h ,您的 app.c 应该有#include "scom.h"

  2. 确认类型i的变量byte被声明为volatile byte i;,并且在执行ISR之后和分配之前不会在任何其他代码段中更新j中的func()

  3. 在你的功能中

    void fun(void)
    {
       //some code
       j=i;
       //operations on j;
       j = j & 0x0F;
       k = j + 0x30;
       lcd_puta(k);// displaying k on LCD
    }
    

    i未在//some code本地声明,否则i将因块范围而在本地获取。你这么说,

      
        

    在j = i后使用断点; j本身的值是随机值。

      
  4. 如果在下一条指令指示之后 ,或者在{{1}处显示的行中,读取此内容并不清楚 如果是后一种情况那么,' j'还没有被指定为' i'的价值。而是在调试时在监视窗口中有i=j;

    这看起来不像你的情况,但是,我可以看到i是一个全局变量,它是j在别处编辑并被其他ISR修改而不是显示的那个在帖子里?
    对这部分代码视而不见(如果它在那里)我可以预测,有一个这样的ISR(如果它在那里)改变extern的值后,它被分配了j并且在打印之前。例如:

    i

    我假设 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 } 属于兼容数据类型,最好是k类型。

    虽然它不是一个非常严格的规则,你应该在ISR中声明一个变量吗?不,你不应该。假设子程序当然使用相同的寄存器库,Interrupts可能具有局部变量,就像普通函数一样。但是,编译器中更高级别的优化会将变量自动移入寄存器,从而在中断触发时保存它们。请勿在{{1​​}}中声明byte