Here is the hello world program for the Tiny85.
All this does is turn on a single LED connected
to pin 5 (Port B bit 0)
Here is the code followed by a complete description
of every line.
Ok, firstly, anything following a ; is considered by
the assembler to be just a comment. So the entire
section
; ********************************************
; * Tiny85LEDON *
; * 07/17/2010 *
; ********************************************
is nothing but a comment and means nothing to
the assembler...this is stuff just for you the programmer
to read and use.
these lines cause a large file of definitions
and such to be loaded and processed by the
assembler.
.NOLIST
.INCLUDE "tn85def.inc"
.LIST
The include file named tn85def.inc is the important
thing here. The .NOLIST and .LIST are there just to
keep the AVR Studio IDE from displaying the huge
tn85def.inc file when it produces a list file. You don't
need to see all the stuff inside that file, it's mostly
boring and you need not think about it. Each AVR
model has its own def file that details stuff like the names
of the registers, amounts of memory..etc..etc If you
don't include this file you cannot use the simple names
for things like I/O registers and would have to enter
the addresses instead, that would suck because it would
make assembly programming much more tedious.
The line
.def temp =r16
defines the word temp to mean the same thing as r16.
Now you can just type temp and the assembler will
translate that to r16 (working register 16) there are 32
working registers that each hold one byte(8 bits). Registers
16-31 are more useful than the others especially 30 and 31
because this pair can hold a word (16 bit number)
This long list of interrupt vectors is not strictly
needed but we will include it for now since it will
help you to understand that the first several bytes
of memory are meant to hold these vectors.
rjmp Start ; Reset vector
reti ; Int vector 1
reti ; Int vector 2
reti ; Int vector 3
reti ; Int vector 4
reti ; Int vector 5
reti ; Int vector 6
reti ; Int vector 7
reti ; Int vector 8
reti ; Int vector 9
reti ; Int vector 10
reti ; Int vector 11
reti ; Int vector 12
reti ; Int vector 13
reti ; Int vector 14
The first one is memory location zero, this is the first
byte of code that runs when you power up an AVR.
Putting this line
rjmp Start ; Reset vector
In this spot is not required but is much recommended!
rjmp means relative jump and it sends the AVR down to
where your actual program starts at the label Start:
It thus jumps over all the other interrupt vector bytes
which are filled with the reti command. This is the
return from interrupt code and usually is found at the
very end of an interrupt service routine. It serves well
here as a sort of placeholder that will if ever called
just bounce your program out of any interrupt that jumps
to it.
Notice the ; in each of these short lines of code, it means
that the text on the line following the ; is just a comment.
Ok, this next line is called a label. This is just a name you
make up to tell the assembler where a particular place in
memory is.
Start:
Don't forget to put labels starting in the first column and
never ever forget the : at the end! Also don't use a name
reserved by the assembler for something else such as
PORTB: all hell would break loose if you tried it! :-)
Labels don't take up memory space in the AVR, they
are simply a way for the assembler to locate a place in
memory when it assembles your source code.
ser temp ;set temp (r16) to 0b11111111
ser means SEt Register
What it does is it moves 0b11111111 into a register
quickly. It is the fastest way to do this and you will
use this instruction often. Note that it only works on
working registers 16-31 !!!
0b11111111 is the proper way to write a binary value
for the assembler to understand. Hexadecimal is written
like this 0xFF or $FF these three numbers
0b11111111
0xFF
$FF
All equal decimal 255, you can use decimal in the assembler,
it is the default base and so you could simply write 255.
(you do know computer arithmetic? I hope so because I
am not planning on reviewing it here...there are many fine
tutorials already on the web)
out DDRB,temp ;copy temp to I/O register DDRB
;making port B pins all outputs
the out instruction copies the value in a working register
into an I/O register. You cannot move a number directly
into an I/O register, you must copy it over from a working
register!
Copying the value 0b11111111 into DDRB will make
all the pins of PortB outputs. If a bit is set to a 1 then
the corresponding pin is an output, if the bit is a 0 then
that pin is an input.
clr temp ;set temp to 0b00000000
The clr instruction sets a working register to 0b00000000
clr stands for CLear Register.
out PortB,temp ;set all port B pins low
This turns off all the I/O pins on PortB. They will thus
be at ground potential. If a bit in PortB holds a zero then
it's corresponding pin is low.
Ok, now we get to the line that actually will turn
our LED on!
sbi PortB,0 ;set PortB pin 0 high
sbi sets a bit in an I/O register to a one. This makes it
high (at vcc usually 5v) so this line sets pin 0 at 5v and
if an LED is connected from this pin to ground (through
a current limiting resistor) it will light up!
loop: rjmp loop ; loop 4ever
This is the last line in our small program. It just creates
an endless loop, you can never let the AVR just wonder
off when its program ends! You must put it into some
sort of loop, or put it to sleep :-)
If you run this in the AVR Studio IDE and look at the
simulator over on the right and click on PortB you will
see this
Notice that DDRB has been set to all ones by the code line
out DDRB,temp
Remember that temp held 0b11111111 when it's value was
copied to DDRB.
And notice that pin zero of PortB is indeed turned on,
it is at vcc (usually 5v)
I will try to actually build up a small circuit for the next
post so you can actually see this program running on a
Tiny85 and lighting up an LED.
After that perhaps we will alter this program and
let an interrupt service routine turn the LED on.
It is easy to blink the LED using a Timer interrupt
or you can use a button connected to an input pin
to turn it on when a pin change interrupt is triggered.
The dark purple text on black is nearly impossible to read.
ReplyDelete