Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 外部变量的行为不符合预期_C_Embedded_Extern - Fatal编程技术网

C 外部变量的行为不符合预期

C 外部变量的行为不符合预期,c,embedded,extern,C,Embedded,Extern,scom.h scom.c 附录c 在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=0x07和k=0x37 在j=i处使用断点后

scom.h

scom.c

附录c

在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=0x07
k=0x37

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

  • 保持scom.h不变,你的app.c应该有
    #包括“scom.h”

  • 确认
    byte
    类型的变量
    i
    声明为
    volatile byte ifunc()
    中将ISR分配给
    j
    之前,代码>不会在任何其他代码段中更新

  • 在你的职责范围内

    void fun(void)
    {
       //some code
       j=i;
       //operations on j;
       j = j & 0x0F;
       k = j + 0x30;
       lcd_puta(k);// displaying k on LCD
    }
    
    i
    未在
    //某些代码中本地声明,否则由于块作用域的原因,
    i
    将在本地声明。你说的,

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

  • 读这篇文章并不能说明指令后面是否有断点,即在下一条指令处,或者在指令上写着
    i=j的那一行如果是后一种情况,则尚未为“j”分配值“i”。而是在调试时在监视窗口中设置
    i

    在您的案例中,这看起来不像是发生了什么,但是,我可以看到,
    j
    是一个全局变量,它是否被
    extern
    ed放在其他地方,并被其他ISR修改,而不是帖子中所示的ISR?
    由于对代码的这一部分(如果存在)视而不见,我可以预测,有一个这样的ISR(如果存在)可能会在分配了
    I
    之后和打印之前更改
    j
    的值。例如:

        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
    是兼容的数据类型,最好是
    byte
    类型


    虽然这不是一个非常严格的规则,但您应该在ISR中声明一个变量吗?不,你不应该。当然,假设子程序使用相同的寄存器组,中断可能与正常函数一样具有局部变量。但是,编译器中更高级别的优化将自动将变量移动到寄存器中,从而在中断触发时保存它们。请不要声明
    字节数据
    无效中断\u Rx(无效)

    但我无法对i/j进行操作。
    请详细说明您得到了什么结果?你期望得到什么样的结果?那么如何检查这些值呢?@SouravGhosh:j=j&0x0F;k=j+0x30,然后在LCD上显示k。请将此信息添加到问题中,而不是作为注释。否则大多数人不会读它。您可以单击链接编辑您的问题。@JoachimPileborg一些随机值。。最后,在执行j=i之后,我期望j为0x77;statement@Olaf:虽然我同意返回
    void
    ,但我确实有一个在ISR中声明变量的想法。出于优化目的,编译器将变量移动到寄存器中。1)不返回void;这是毫无疑问的;实际上“void”并不是一种类型,但——好吧——它确实是这么说的。你真的应该读一下这方面的标准。那么关于局部变量和编译器又有什么意义呢?请分享你的想法;使用局部寄存器的编译器会有什么问题(不知道“移入…”是什么意思)。在大多数RISC CPU(例如ARM)上,无论如何都必须使用寄存器,因为它们不支持内存操作数。
    void fun(void)
    {
        //some code
        j=i;
        //operations on j;
        j = j & 0x0F;
        k = j +0x30;
        lcd_puta(k);// displaying k on LCD
    }
    
    void fun(void)
    {
       //some code
       j=i;
       //operations on j;
       j = j & 0x0F;
       k = j + 0x30;
       lcd_puta(k);// displaying k on LCD
    }
    
        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
        }