0

我正在尝试通过玩 Atmega128 板来学习一点组装。当按下相应的按钮时,我试图让一组 8 个 LED 单独打开/关闭。

.INCLUDE "m128def.inc"
.CSEG
.ORG $0

initialize:
    ldi     r16, 1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<3 | 1<<2 | 1<<1 | 1<<0
    out     PORTB, r16          ; Pull up resistors
    ldi     r16, 1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<3 | 1<<2 | 1<<1 | 1<<0
    out     DDRD, r16           ; set all pins on PORTD to output

test:
    in      r16, PINB           ; input values of buttons
    swap    r16                 ; invert so button pressed makes value low
    out     PORTB, r16          ; output to led
end:
    rjmp    test

这行得通吗?我将 LED 连接到 PortD,将按钮连接到 Port/PinB。这基本上是我想用 C 编写的。(我对 C 的了解比在汇编中要好得多。)也许这可能会让它更清楚一点。

DDRD  = 0xFF; // set to output
DDRB  = 0; // set to input
PORTB = 255; // enable pull-up resistors
while (1)  {
    PORTD = ~PINB;
}
4

1 回答 1

1

PINA 和 PORTA 指的是相同的物理引脚。AVR 有两个名字来区分输入和输出。

上面的代码有一半的引脚(0 到 3)配置为输出,引脚 4 到 7 是带上拉的输入。

代码的下一部分不是那么清楚。您正在读取 0 到 3 作为输入,然后移位以写入引脚 4 到 7 以及引脚 1。这与引脚的初始设置不兼容。电流仍会流出输入引脚,但它的设计目的不是很好。

您是否将按钮和 LED 连接到相同的引脚?然后你应该在一个引脚上使用一个或另一个,并适当地设置 DDR 和上拉。确定按钮的接线方式。他们将输入拉低到地还是高到 Vcc?

我没有看到一种方法可以让一个引脚同时作为输入和输出与您正在使用的轮询代码。如果您想让按钮在 0 到 3 上,输出在 4 到 7 上,那么您需要稍微更改代码。

.INCLUDE "m128def.inc" 
.CSEG 
.ORG $0

initialize:
    ldi r16, 1<<3 | 1<<2 | 1<<1 | 1<<0         ; pullup inputs
    out PORTA, r16 
    ldi r16, 1<<7 | 1<<6 | 1<<5 | 1<<4         ; 4 to 7 are output
    out DDRA, r16
test:
    in r16, PINA
    lsr r16 
    lsr r16
    lsr r16
    lsr r16
    ori r16, 1<<3 | 1<<2 | 1<<1 | 1<<0         ; pullup 0 to 3, and output to 4 to 7
    out PORTA, r16
end:
    rjmp test
于 2013-09-18T13:55:28.980 回答