本帖最后由 iyumi 于 2018-8-31 10:09 编辑
问题已经解决了,见12楼,麻烦懂的大神解释一下原因
iar的优化选项里选的“NONE”,函数前我也加了个#pragma optimize=none(编号1),但是感觉这个可能不是优化的问题
问题:图中打红大括号的代码(编号5)在汇编窗口没有对应的代码,1237行过后就直接是1261行了(编号4),把1239和1243两处的if语句注释掉以后就正常,单步执行时,执行完1236行,中间观察窗口addr_h变量的Value列对应的值没有显示出来(编号2),把鼠标放到addr_h上可以看到有值(编号3),1237行执行完后直接跳到1261行,我觉得应该是addr_h和data_h这两个变量的问题,addr_h和data_h这两个变量之前是局部变量,改成全局变量还是有这样。大神帮忙看看这个是什么原因?先谢谢了
ir_revdata的值是:0x00FF10EF
1237行的代码是:addr_h = (u8)(ir_revdata>>16);
红外键值判断的函数代码:两个按键,每个按键分单击,双击,长按
如果可以的话,大神下载下来用IAR for STM8编译一下,看有我上面说的问题没?
- void IR_GetKeyVal(u8 *LastKeyCode, u8 *ClickCnt, //{{{获取红外遥控器的键值
- u8 *KeyNum, u8 *KeyVal) //LastKeyCode:上次按键编码值
- //ClikcCnt:单击次数
- //KeyNum:按键号
- //KeyVal:按键值
- {
- u8 addr_h, addr_l, data_h, data_l;
- *KeyNum = 0;
- *KeyVal = 0;
- if(ir_bitcnt>=32)
- {
- ir_bitcnt = 0;
- addr_l = (u8)(ir_revdata>>24);
- addr_h = (u8)(ir_revdata>>16);
- //if(addr_l==(~data_h)&&addr_l==EQ_ID)//EQ_ID,设备ID
- if(addr_l==(~addr_h))
- {
- data_l = (u8)(ir_revdata>>8);
- data_h = (u8)ir_revdata;
- if(data_l==(~data_h))
- {
- if(*LastKeyCode!=data_l)
- {
- *ClickCnt = 0; //本次按键和上次按键值不同,ClickCnt清0
- }
- if(data_l==0x94||data_l==0x95)
- {
- *LastKeyCode = data_l;
- (*ClickCnt)++;
- }
- else
- {
- *LastKeyCode = 0;
- }
- }
- }
- }
- if(ir_keycomplete==1)
- {
- ir_keycomplete = 0;
- if(*LastKeyCode == 0x94)
- {
- *KeyNum = 1;
- }
- else if(*LastKeyCode == 0x95)
- {
- *KeyNum = 2;
- }
- else
- {
- *KeyNum = 0;
- }
- if(ir_repcnt<18)
- {
- if(*ClickCnt==1)
- {
- *KeyVal = KEY_SHORT_CLICK;
- }
- else if(*ClickCnt>=2)
- {
- *KeyVal = KEY_DOUBLE_CLICK;
- }
- }
- else
- {
- *KeyVal = KEY_LONG_CLICK;
- }
- }
- }//}}}
复制代码
|
代码不全,无法分析原因
单步就是直接跳到编号4指向的C和汇编代码行啊
非常感谢,CALL是STM8的指令,不过我的汇编看起来好奇怪,怎么里边还有问号呢
那就说明这段代码应该没什么问题哦,我再找找原因吧
ir_revdata确认改变了,我按了两个红外按键,得到了不同的值
编号5当然要条件满足才能进入
不满足条件的话if语句还是要走的啊,另外可以从观察看到ir_revdata=0x00FF10EF,这个条件是满足的
if(addr_l==(~addr_h))
仔细看了下写法
C语言语法,这句话,应该永远不成立,所以编译器自动过滤了无效的代码段
大神,牛逼啊!!我刚把这个问题解决了,准备上来结贴,就看到你给出正确答案了,确实是这样的,我现在改成这样了:
addr_l = (u8)(ir_revdata>>24);
addr_h = ~(u8)(ir_revdata>>16);
//if(addr_l==(~data_h)&&addr_l==EQ_ID)//EQ_ID,设备ID
if(addr_l==addr_h)
{
data_l = (u8)(ir_revdata>>8);
data_h = ~(u8)ir_revdata;
if(data_l==data_h)
{
...
}
}
把取反的操作放到前边去,if条件里不取反,这样就没有问题
大神,再具体说一下,这个条件有什么问题吗,为什么永远不成立?