简体   繁体   中英

Atmega128 Assembly Project

I'm trying to learn a little Assembly by playing around with the Atmega128 board. I'm attempting to make a set of 8 LED's individually turn on/off when their appropriate button is pressed.

.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

Does this work? I have the LED's conected to PortD and the buttons to Port/PinB. This is basically what I want to do written in C. (I'm much better versed in C than in Assembly.) Perhaps this might make it a little clearer.

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

PINA and PORTA refer to the same physical pins. AVR has two names for them to distinguish between input and output.

The code above has half of the pins (0 to 3) configured as output, and the pins 4 to 7 are inputs with pullups.

The next part of the code is not that clear. You are reading 0 to 3 as inputs, then shifting so as to write to pins 4 to 7, as well as pin 1. This is not compatible with the initial set up of the pins. Current will still flow out an input pin, but it is not designed to do it well.

Do you have buttons and leds attached to the same pins? Then you should use one or the other on a pin, and set the DDR and pullup appropriately. Determine how the buttons are wired. Do they pull the input low to ground or high to Vcc?

I don't see a way to have a pin be both an input and an output at the same time with the polling code you are using. If you want to have the buttons on 0 to 3 and the outputs on 4 to 7, then you need to change the code slightly.

.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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM