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?
