32位ARM汇编wiringPi程序故障:按键无法触发LED闪烁循环的修复
问题排查与修正方案
核心错误点分析
- 按键引脚配置传参错误:
pinMode函数的第一个参数(引脚号)需要放在r0寄存器,但原代码把按键引脚号放到了r2,导致按键引脚根本没被正确设为输入模式。 - 按键状态读取逻辑错误:ARM函数调用约定里,
digitalRead的返回值存在r0,但原代码误以为返回值会存入r2,等于根本没拿到正确的按键状态。 - 条件跳转指令用错:原代码写的
bleq blnkr是无效的条件组合(ARM条件后缀是单个码,beq才是“相等时跳转”),导致按键为HIGH时无法触发闪烁循环。 - 闪烁循环逻辑完全反转:
blnkr里写的是“按键为HIGH就跳回主循环”,和需求完全相反,而且没实时更新按键状态,一旦进循环就没法响应按键松开的动作。
修正后的完整代码
// to compile: g++ redLed.s -lwiringPi -g -o redLed // Program will blink LED when button is pressed, and turn off LED when button is released .equ INPUT, 0 .equ OUTPUT, 1 .equ LOW, 0 .equ HIGH, 1 .equ LED, 29 // wiringPi 29 (bcm 21 / physical 40) .equ BTN, 28 // wiringPi 28 (bcm 20) .text .global main main: push {lr} bl wiringPiSetup // 初始化wiringPi库 // 设置LED引脚为输出 mov r0, #LED mov r1, #OUTPUT bl pinMode // 设置按键引脚为输入(修正传参错误) mov r0, #BTN mov r1, #INPUT bl pinMode do_while: // 按键未按下时,LED保持熄灭 mov r0, #LED mov r1, #LOW bl digitalWrite // 读取按键状态(修正返回值处理) mov r0, #BTN bl digitalRead mov r2, r0 // 将返回值存入r2保存 // 按键为HIGH时进入闪烁循环(修正跳转指令) cmp r2, #HIGH beq blnkr b do_while blnkr: // 重新读取当前按键状态,判断是否松开 mov r0, #BTN bl digitalRead mov r2, r0 // 按键松开(LOW)时返回主循环 cmp r2, #LOW beq do_while // LED亮 mov r0, #LED mov r1, #HIGH bl digitalWrite ldr r0, =#350 bl delay // LED灭 mov r0, #LED mov r1, #LOW bl digitalWrite ldr r0, =#350 bl delay b blnkr // 程序退出(实际不会执行到这里,主循环是无限的) mov r0, #0 pop {pc}
关键修正说明
- 按键引脚配置:把
mov r2, #BTN改成mov r0, #BTN,符合pinMode的参数传递规则(第一个参数引脚号存r0)。 - 按键状态读取:调用
digitalRead后,把r0里的返回值存到r2,确保拿到正确的按键状态。 - 跳转指令修正:用
beq blnkr替换bleq blnkr,实现按键为HIGH时正确进入闪烁循环。 - 闪烁循环逻辑:每次迭代都重新读取按键状态,判断为LOW(松开)时返回主循环,同时反转了原有的错误判断条件,确保按住按键时持续闪烁。
内容的提问来源于stack exchange,提问作者BeefCake
相关产品推荐
相关产品推荐

