Сборочный проект Atmega128

Я пытаюсь немного изучить сборку, играя с платой Atmega128. Я пытаюсь сделать так, чтобы набор из 8 светодиодов включался/выключался индивидуально при нажатии соответствующей кнопки.

.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

Это работает? У меня светодиоды подключены к 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;
}

person codedude    schedule 18.09.2013    source источник


Ответы (1)


PINA и PORTA относятся к одним и тем же физическим контактам. AVR имеет два имени для них, чтобы различать вход и выход.

В приведенном выше коде половина контактов (от 0 до 3) настроена как выход, а контакты с 4 по 7 являются входами с подтяжкой.

Следующая часть кода не так ясна. Вы читаете от 0 до 3 в качестве входных данных, а затем выполняете сдвиг для записи на контакты с 4 по 7, а также на контакт 1. Это несовместимо с начальной настройкой контактов. Ток по-прежнему будет вытекать из входного контакта, но он не предназначен для этого.

У вас есть кнопки и светодиоды, подключенные к одним и тем же контактам? Затем вы должны использовать один или другой на булавке и соответствующим образом установить DDR и pullup. Определите, как кнопки подключены. Подтягивают ли они низкий входной сигнал к земле или высокий к 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
person uncleO    schedule 18.09.2013
comment
Мое редактирование помогает прояснить ситуацию? Я понял, что у меня было несколько ошибок в моем вопросе, поэтому я очистил его. - person codedude; 18.09.2013
comment
@codedude Инструкция по обмену - это не то, что вам нужно. Он обменивает полубайты (4 бита) в байте регистра. Вместо этого вы можете захотеть NEG. Но это работает только в том случае, если кнопки привязывают контакт к земле. То есть вход обычно равен 1, но становится 0 при нажатии кнопки. Кроме того, константы в коде не обязательно должны быть такими длинными выражениями. Вы можете использовать 0xff, если хотите. Также безопасно загружать r16 дважды, как вы это делаете, но это не обязательно. Он по-прежнему содержит 0xff после первой команды out. - person uncleO; 18.09.2013