C 外部变量的行为不符合预期
scom.h scom.c 附录c 在app.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处使用断点后
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 i执行ISR后,在func()
中将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
}