树莓派GPIO汇编程序未按按钮时digitalRead返回HIGH的问题解决
此问题为重发,因原问题存在上下文与格式问题,故重新发布
程序功能
本程序实现按下三个按钮中的任意一个时,通过循环控制LED闪烁:
- 当
BTN_LEFT输入读取为HIGH时,程序跳转到BLNKR_LEFT循环,使LED_LEFT闪烁,直到BTN_LEFT读取为LOW; - 当
BTN_HZRD读取为HIGH时,程序跳转到BLNKR_HZRD循环,使LED_LEFT和LED_RIGHT闪烁,直到BTN_HZRD读取为LOW; - 当
BTN_RIGHT输入读取为HIGH时,程序跳转到BLNKR_RIGHT循环,使LED_RIGHT闪烁,直到BTN_RIGHT读取为LOW。
在这三个BLNKR循环中,当对应按钮输入返回LOW时,程序跳回INPUT循环,继续监听三个按钮的输入。
// to compile: g++ redLed.s -lwiringPi -g -o redLed // Program will power an LED when button is pressed, and when button is not pressed, LED will remain off .equ INPUT, 0 .equ OUTPUT, 1 .equ LOW, 0 .equ HIGH, 1 .equ LED_LEFT, 29 // wiringPi 29 (bcm 21) .equ LED_RIGHT, 28 // wiringPi 28 (bcm 20) .equ BTN_LEFT, 23 // wiringPi 23 (bcm 13) .equ BTN_HZRD, 22 // wiringPi 22 (bcm 6) .equ BTN_RIGHT, 21 // wiringPi 21 (bcm 5) .text .global main main: // int main() push {lr} // { bl wiringPiSetup // wiringPiSetup(); // initialize the wiringPi library // Initialize our WPI inputs and outputs mov r0, #LED_LEFT // pinMode(29,OUTPUT); // set the wpi 29 pin for output mov r1, #OUTPUT bl pinMode mov r0, #LED_RIGHT // pinMode(28,OUTPUT); // set the wpi 28 pin for output mov r1, #OUTPUT bl pinMode mov r0, #BTN_LEFT // pinMode(23,INPUT); // set the wpi 23 pin for input mov r1, #INPUT bl pinMode mov r0, #BTN_HZRD // pinMode(22,INPUT); // set the wpi 22 pin for input mov r1, #INPUT bl pinMode mov r0, #BTN_RIGHT // pinMode(21,INPUT); // set the wpi 21 pin for input mov r1, #INPUT bl pinMode // Searches for an input from any button, if there is no input, then the program will keep looping INPUT: // Set both LEDs to LOW mov r0, #LED_LEFT mov r1, #LOW bl digitalWrite mov r0, #LED_RIGHT mov r1, #LOW bl digitalWrite // Read for input from BTN_LEFT, BTN_RIGHT, or BTN_HZRD mov r0, #BTN_LEFT bl digitalRead // digitalRead(BTN_LEFT); mov r1, #HIGH cmp r0, r1 bleq BLNKR_LEFT // Read for input from BTN_HZRD mov r0, #BTN_HZRD bl digitalRead mov r1, #HIGH cmp r0, r1 bleq BLNKR_HZRD // Read for input from BTN_RIGHT mov r0, #BTN_RIGHT bl digitalRead mov r1, #HIGH cmp r0, r1 bleq BLNKR_RIGHT b INPUT BLNKR_LEFT: // If BTN_LEFT is not being pressed then the program will return to INPUT mov r0, #BTN_LEFT bl digitalRead mov r1, #LOW cmp r0, r1 bleq INPUT mov r0, #LED_LEFT // digitalWrite(29,HIGH); // write high volt signal to pin 29 mov r1, #HIGH bl digitalWrite ldr r0, =#350 // delay(350); // Delay for 350 milliseconds bl delay mov r0, #LED_LEFT // digitalWrite(29,LOW); // write low voltage to wpi 29 to turn off the led mov r1, #LOW bl digitalWrite ldr r0, =#350 bl delay b BLNKR_LEFT BLNKR_HZRD: // If BTN_HZRD isnt being pressed then the program will branch back to INPUT mov r0, #BTN_HZRD bl digitalRead mov r1, #LOW cmp r0, r1 bleq INPUT // Turn on both LED_LEFT and LED_RIGHT mov r0, #LED_LEFT mov r1, #HIGH bl digitalWrite mov r0, #LED_RIGHT mov r1, #HIGH bl digitalWrite // delay for 350 milliseconds ldr r0, =#350 bl delay // Turn off both LED_LEFT and LED_RIGHT mov r0, #LED_LEFT mov r1, #LOW bl digitalWrite mov r0,#LED_RIGHT mov r1, #LOW bl digitalWrite // Delay for 350 milliseconds ldr r0, =#350 bl delay b BLNKR_HZRD BLNKR_RIGHT: // If BTN_RIGHT isnt being pressed then the program will branch back to INPUT mov r0, #BTN_RIGHT bl digitalRead cmp r0, #LOW bleq INPUT // Turn on LED_RIGHT mov r0, #LED_RIGHT mov r1, #HIGH bl digitalWrite // delay for 350 milliseconds ldr r0, =#350 bl delay // Turn off LED_RIGHT mov r0,#LED_RIGHT mov r1, #LOW bl digitalWrite // Delay for 350 milliseconds ldr r0, =#350 bl delay b BLNKR_RIGHT mov r0, #0 // return 0; pop {pc} // }
问题描述
运行程序时,BLNKR_LEFT或BLNKR_HZRD循环会在未按下任何物理按钮的情况下自动启动,具体取决于哪个cmp指令先执行。
执行BTN_LEFT或BTN_HZRD的digitalRead时,r0寄存器会存储HIGH值,但实际未按下按钮;而BTN_RIGHT的digitalRead能根据是否按下按钮正确返回HIGH或LOW。
尝试更换不同按钮开关后,BTN_LEFT和BTN_HZRD返回HIGH的问题仍未解决,推测问题可能出在面包板接线。
解决方案
经排查,连接按钮的BCM 5和BCM 6引脚默认电平为HIGH,仅BCM 13默认电平为LOW且工作正常。因此将BTN_LEFT和BTN_HZRD分别重新连接到BCM 13和BCM 19,BTN_RIGHT连接到BCM 26。这三个BCM引脚通过gpio readall查看默认电平为LOW,程序现已正常运行。
通过gpio readall可见,BCM引脚5和6显示电压为1,BCM引脚13、19和26显示电压为0。此前曾尝试使用PUD_DOWN内部电阻解决浮空引脚问题。
内容的提问来源于stack exchange,提问作者BeefCake
相关产品推荐
相关产品推荐

