我正在用 C 编写一个回调函数。它旨在初始化 I2C 传感器,并在每个(分阶段)配置步骤结束时调用;在第 9 次通话后,该设备几乎可以使用了。
该函数的基本思想是这样的:
void callback(void)
{
static uint8_t calls = 0;
if (++calls == 9) {
// Finalise device setup (literally a single line of code)
}
}
我的问题是上面的 if 语句从未被输入,尽管该函数被调用了 9 次。
我的函数的(反)汇编代码看起来很正常(除了增加的subi . 0xFF
技巧,尽管包含了一条inc
指令):
00000a4c <callback>:
a4c: 80 91 9e 02 lds r24, 0x029E
a50: 8f 5f subi r24, 0xFF ; 255
a52: 80 93 9e 02 sts 0x029E, r24
a56: 89 30 cpi r24, 0x09 ; 9
a58: 09 f0 breq .+2 ; 0xa5c <callback+0x10>
a5a: 08 95 ret
a5c: 2e e1 ldi r18, 0x1E ; 30
a5e: 35 e0 ldi r19, 0x05 ; 5
a60: 41 e0 ldi r20, 0x01 ; 1
a62: 60 e0 ldi r22, 0x00 ; 0
a64: 84 e7 ldi r24, 0x74 ; 116
a66: 0c 94 c7 02 jmp 0x58e ; 0x58e <twi_set_register>
我正在为 Atmel AVR 芯片编写代码,因此使用 avr-gcc 进行编译。我没有有意义的代码调试能力(我没有 JTAG 程序员,而且该功能在任何情况下都是异步/分相的;USART 打印太慢了)。
但是,我可以使用逻辑分析器,并且能够通过while (1) ;
在代码中放置语句来确定许多事情:
- 该函数被调用- 如果我在函数的开头放置一个无限循环,微控制器就会挂起
- 该函数应该被调用 9 次- 该函数的触发器是 I2C 通信,在上一步中它在第一次通信后立即挂起;我可以观察到 9 个完整有效的 I2C 通信
- 调用在函数内递增- 如果我在递增
if (calls == 0) { while (1) ; }
之后添加,它不会挂起 - 在函数开始时调用永远不会非零- 如果我在增量
if (calls) { while(1) ; }
之前添加,它不会挂起
我完全没有想法。
有人对可能导致这种情况的原因有什么建议,甚至对我可以采取的新调试步骤有什么建议吗?