【问题标题】:Arduino Uno [Using Assembly] - toggling LED Module using joystickArduino Uno [使用组件] - 使用操纵杆切换 LED 模块
【发布时间】:2020-01-22 02:36:19
【问题描述】:

刚接触 Arduino 并尝试编写一个程序来切换连接到 PORTB 引脚 5,4 和 3(板上的 13,12 和 11)的 LED 模块。

操纵杆有一个接地连接和一个连接,从 SW 到 PORTD 的引脚 7(板上的 7)。

这个想法是使用汇编编程来做到这一点。这是我到目前为止制作的程序(我正在学习中可能非常错误)

更新

我已经调整了我的代码并修复了一些问题。当我删除 apploop 部分时,设置部分运行并打开蓝色 LED。但是,当我切换操纵杆时,apploop 组件不起作用并且红色 LED 未触发。已尝试查看其他示例,但到目前为止无法修复它

任何指针将不胜感激!

   #include "m328pdef.inc"
.global main
.EQU Red_Pin, 17
.EQU Green_Pin, 16
.EQU Blue_Pin, 15
.EQU Led_Port, PORTB
.EQU Switch_Pin, 11
.EQU Switch_Port, PORTD
main:
appSetup:
; Init the 3 output RGB LED's
; in
in r16, Led_Port
; sbr
sbr r16, 0b11111111
; out
out DDRB, r16


; Init the input switch, configure with internal pull up resistor

; in
in r24, DDRD
; cbr
cbr r24, 0b10000000
; out
out DDRD,r24

; in 
in r24, Switch_Port

; sbr
sbr r24, 0b11111111

; out
out Switch_Port,r24


; Turn on the Blue Led to indicate Init is done!

; sbi

sbi Led_Port,3

appLoop:

; Switch pressed = Red Led on

; sbis
sbis Switch_Port, 7

; sbi
sbi Led_Port, 3
; Switch not pressed = Red Led off
; sbic
sbic Switch_Port, 7

; cbi
cbi Led_Port,3

; rjmp appLoop ; keep doing this indefinitely

rjmp appLoop

【问题讨论】:

  • sbi 将端口号(非注册)作为第一个参数。
  • 曾经看过编译器是如何完成这项工作的吗? (看看avr-objdump 能为你做什么)。您可以从普通的 avr-gcc 开始并忽略 arduino 层。并删除该标签:)

标签: assembly arduino atmega


【解决方案1】:
in r16, Led_Port  // <-- should be in r16, DDRB
; sbr
sbr r16, 0b11111111
; out
out DDRB, r16

从 PORTB 读取,写入 DDRB。可疑的。如果只使用 3 个作为输出,为什么所有位都设置?

in r24, DDRD
cbr r24, 0b10000000
out DDRD,r24

顺便说一句,要更改寄存器 0...31 中的单个位(ATmega328P 中的所有 PINx、DDRx、PORTx 都在此范围内),您可以使用 sbicbi 指令。例如:

cbi DDRB, 7 // clear 7th bit of DDRB 
; in 
in r24, Switch_Port
; sbr
sbr r24, 0b11111111
; out
out Switch_Port,r24

同样,如果你只需要一个,为什么要设置所有 8 位?

; Turn on the Blue Led to indicate Init is done!
sbi Led_Port,3

...

; Switch pressed = Red Led on
sbi Led_Port, 3

所以,Led_Port (PORTB) 的第 3 位是红色的?还是蓝色?

您的代码有问题。命名常量与立即值混合。如果您使用一些命名常量。示例:

.EQU LED_RED_pinno, 5
.EQU LED_BLUE_pinno, 3
...

; Turn on the Blue Led to indicate Init is done!
sbi Led_Port, LED_BLUE_pinno

...

; Switch pressed = Red Led on
sbi Led_Port, LED_RED_pinno

还有:

; sbis
sbis Switch_Port, 7
; sbi
sbi Led_Port, 3

sbis 跳过下一条指令,如果 Switch_Port 中的第 7 位被设置。 Switch_Port 等于 PORTB,并且它的第 7 位始终被清除(除非您向其写入 1)。

要检查输入端口的状态,您需要读取PINx(不是PORTx!)寄存器。在这种情况下,它应该是:

; Switch pressed = Red Led on
sbis PINB, 7  // (sic!)
sbi Led_Port, 3

; Switch not pressed = Red Led off
sbic PINB, 7 // (sic!)
cbi Led_Port,3

【讨论】:

    猜你喜欢
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 2019-12-03
    • 2011-07-06
    • 1970-01-01
    相关资源
    最近更新 更多