I have been trying to learn AVR assembly for the past few weeks. Things are coming along, but it is tough to remember all of the 3 and 4 letter instructions and which registers they can work with. Here is part of an example project, which was really a series of exercises that I worked on through out the chapter. I’ve been reading a book from 2002 called AVR: An Introductory Course. While the reviews for this book haven’t been great, I’ve found it to be a reasonable book for learning. I’m sure it is outdated but I think much of it still applies.
Here is what I came up with for the first part of the Counter project from chapter 2.
/* * Counter.asm * * Created: 12/25/2013 12:23:58 PM * Author: jjveleber */ .device ATMEGA328P .nolist .include "m328pdef.inc"; Import atmega328p file .list ;============== ; Declarations: .def tmp = r16 ; rename working register .def counter = r17 ; rename counter register ;============== ; Start of program: rjmp Setup Setup: clr counter ; clear counter ldi tmp, 0b00000000 ; Set I/O on PortB out DDRB, tmp ; ldi tmp, 0b00000001 ; Set I/O on PortD out DDRD, tmp ; ldi tmp, 0b00000000 ; Set Pullups on PortB out PortB, tmp ; ldi tmp, 0b00000001 ; Set Pullups on PortD out PortD, tmp ; ; Setup 7 segment codes ; ABCDEFG ldi r20, 0b01111110 ; 0 ldi r21, 0b00110000 ; 1 ldi r22, 0b01101101 ; 2 ldi r23, 0b01111001 ; 3 ldi r24, 0b00110011 ; 4 ldi r25, 0b01011011 ; 5 ldi r26, 0b01011111 ; 6 ldi r27, 0b01110000 ; 7 ldi r28, 0b01111111 ; 8 ldi r29, 0b01110011 ; 9 Loop: sbic PinD, 0 ; read push button on/off rjmp Loop ; branch for retry if not pressed inc counter ; increment button press counter cpi counter, 0xA ; is counter == 10 brne PC+2 ; skip reset if counter != 10 clr counter ; reset counter clr ZH ; Set address of Z ldi ZL, 20 ; add ZL, counter ; Set address offset in 7 segment codes ld tmp, Z ; read out 7 segment code out PortB, tmp ; display counter rjmp Loop ; loop forever
Be warned: I am just learning so some of this may be incorrect. It is fun to learn new things. Don’t you think?