我想在AVR组件中创建一个程序,它将轮询瞬时按钮开关的状态,并在按下开关时切换LED的状态。我正在使用带有ATMega328P芯片的Arduino Duemilanove。我有一个连接在数字引脚0和地之间的按钮开关,以及一个连接数字引脚8和+ 5V之间的330欧姆电阻的LED。这是我到目前为止的代码:在AVR组件中创建一个拨动开关
;==============
; Declarations:
.def temp = r16
.org 0x0000
rjmp Reset
;==============
Reset:
ser temp
out DDRB, temp ; set all pins on Port B to OUTPUT mode
ldi temp, 0b11111110 ; set pin 0 on Port D to INPUT mode
out DDRD, temp
clr temp
out PORTB, temp ; clear temp and set all pins on Port B to LOW state
ldi temp, 0b00000001 ; set pin 0 on Port D to HIGH state
out PORTD, temp
;==============
; Main Program:
switch:
in temp, PIND ; get state of pins on Port D
cpi temp, 0 ; compare result to 0 (pushbutton is pressed)
brne PC+3 ; if != 0, go check again
ldi temp, (1<<PB0) ; otherwise, write logic 1 to pin 0 of Port B
out PINB, temp ; which toggles the state of the pin
rjmp switch
不幸的是这一切确实是光LED和保持它无论按键多少次推。我将这个代码从一个发现here的程序中解脱出来,只要按下按钮就可以打开上的LED。我只是想延长这一点,使LED保持当前状态,直到再次按下按钮。有什么建议么?
切换它你应该使用口罩不是整个'PIND'仅比较'PIND0'到'0'。特别是如果您的端口悬空(二极管上的照明可能会改变浮动引脚的电平并使'cpi temp,0'始终错误)。 此外,您可以使用'SBI'指令来更改'PINB'中的单个位。 不确定这会工作,但目前我没有看到其他问题。 – Julien
按钮弹跳。这在示例代码中无关紧要,但在您的情况下,即使在@ Julien的提示之后,您也会收到随机结果。 – datafiddler
我试图围绕如何使用'sbi'来写入逻辑1到PB0,但我似乎无法使其工作。使用'sbi PORTB0,1'不会给出预期的结果。我看到你对按钮反弹的观点。也许在主循环中的某个延迟子例程会使开关脱落? –