Short and easy.......................................................................................................................................1
Fast and quick........................................................................................................................................1
Assembler is easy to learn.....................................................................................................................1
AT90Sxxxx are ideal for learning assembler........................................................................................1
Test it!....................................................................................................................................................1
Hardware for AVR-Assembler-Programming...........................................................................................2
The ISP-Interface of the AVR-processor family...................................................................................2
Programmer for the PC-Parallel-Port....................................................................................................2
Experimental board with a AT90S2313................................................................................................3
Ready-to-use commercial programming boards for the AVR-family...................................................4
Tools for AVR assembly programing........................................................................................................5
The editor..............................................................................................................................................5
The assembler........................................................................................................................................6
Programming the chips..........................................................................................................................7
Simulation in the studio.........................................................................................................................7
What is a Port?....................................................................................................................................12
Details of relevant ports in the AVR...................................................................................................13
The status register as the most used port.............................................................................................13
Port details...........................................................................................................................................14
Port details...........................................................................................................................................45
List of abbreviations............................................................................................................................53
Errors in previous versions..................................................................................................................54
Avr-Asm-Tutorial1http://www.avr-asm-tutorial.net
Why learning Assembler?
Assembler or other languages, that is the question. Why should I learn another language, if I already
learned other programming languages? The best argument: while you live in France you are able to get
through by speaking english, but you will never feel at home then, and life remains complicated. You can
get through with this, but it is rather inappropriate. If things need a hurry, you should use the country's
language.
Short and easy
Assembler commands translate one by one to executed machine commands. The processor needs only to
execute what you want it to do and what is necessary to perform the task. No extra loops and unnecessary
features blow up the generated code. If your program storage is short and limited and you have to optimize
your program to fit into memory, assembler is choice 1. Shorter programs are easier to debug, every step
makes sense.
Fast and quick
Because only necessary code steps are executed, assembly programs are as fast as possible. The
duration of every step is known. Time critical applications, like time measurements without a hardware
timer, that should perform excellent, must be written in assembler. If you have more time and don't mind if
your chip remains 99% in a wait state type of operation, you can choose any language you want.
Assembler is easy to learn
It is not true that assmbly language is more complicated or not as easy to understand than other
languages. Learning assembly language for whatever hardware type brings you to understand the basic
concepts of any other assembly language dialect. Adding other dialects later is easy. The first assembly
code does not look very attractive, with every 100 additional lines programmed it looks better. Perfect
programs require some thousand lines of code of exercise, and optimization requires lots of work. As
some features are hardware-dependant optimal code requires some familiarity with the hardware concept
and the dialect. The first steps are hard in any language. After some weeks of programming you will laugh
if you go through your first code. Some assembler commands need some monthes of experience.
AT90Sxxxx are ideal for learning assembler
Assembler programs are a little bit silly: the chip executes anything you tell it to do, and does not ask you if
you are sure overwriting this and that. All protections must be programmed by you, the chip does anything
like it is told. No window warns you, unless you programmed it before.
Basic design errors are as complicated to debug like in any other computer language. But: testing
programs on ATMEL chips is very easy. If it does not do what you expect it to do, you can easily add some
diagnostic lines to the code, reprogram the chip and test it. Bye, bye to you EPROM programmers, to the
UV lamps used to erase your test program, to you pins that don't fit into the socket after having them
removed some douzend times.
Changes are now programmed fast, compiled in no time, and either simulated in the studio or checked incircuit. No pin is removed, and no UV lamp gives up just in the moment when you had your excellent idea
about that bug.
Test it!
Be patient doing your first steps! If you are familiar with another (high-level) language: forget it for the first
time. Behind every assembler language there is a certain hardware concept. Most of the special features
of other computer languages don't make any sense in assembler.
The first five commands are not easy to learn, then your learning speed rises fast. After you had your first
lines: grab the instruction set list and lay back in the bathtub, wondering what all the other commands are
like.
Don't try to program a mega-machine to start with. This does not make sense in any computer language,
and just produces frustration.
Comment your subroutines and store them in a special directory, if debugged: you will need them again in
a short time.
Have success!
Avr-Asm-Tutorial2http://www.avr-asm-tutorial.net
Hardware for AVR-Assembler-Programming
Learning assembler requires some simple hardware equipment to test your programs, and see if it works
in practice.
This section shows two easy schematics that enable you to homebrew the required hardware and gives
you the necessary hints on the required background. This hardware really is easy to build. I know nothing
easier than that to test your first software steps. If you like to make more experiments, leave some more
space for future extensions on your experimental board.
If you don't like the smell of soldering, you can buy a ready-to-use board, too. The available boards are
characterised in this section below.
The ISP-Interface of the AVR-processor family
Before going into practice, we have to learn a few essentials on the serial programming mode of the AVR
family. No, you don't need three different voltages to program and read an AVR flash memory. No, you
don't need another microprocessor to program the AVRs. No, you don't need 10 I/O lines to tell the chip
what you like it to do. And you don't even have to remove the AVR from your experimental board, before
programming it. It's even easier than that.
All this is done by a build-in interface in the AVR chip, that enables you to write and read the content of the
program flash and the built-in-EEPROM. This interface works serially and needs three signal lines:
•SCK: A clock signal that shifts the bits to be written to the memory into an internal shift register, and
that shifts out the bits to be read from another internal shift register,
•MOSI: The data signal that sends the bits to be written to the AVR,
•MISO: The data signal that receives the bits read from the AVR.
These three signal pins are internally connected to the programming machine only if you change the
RESET (sometimes also called RST or restart) pin to zero. Otherwise, during normal operation of the AVR,
these pins are programmable I/O lines like all the others.
If you like to use these pins for other purposes during normal operation, and for insystem-programming, you'll have to take care, that these two purposes do not
conflict. Usually you then decouple these by resistors or by use of a multiplexer.
What is necessary in your case, depends from your use of the pins in the normal
operation mode. You're lucky, if you can use them for in- system-programming
exclusively.
Not necessary, but recommendable for in-system-programming is, that you supply
the programming hardware out of the supply voltage of your system. That makes it
easy, and requires two additional lines between the programmer and the AVR
board. GND is the common ground, VTG (target voltage) the supply voltage
(usually 5.0 volts). This adds up to 6 lines between the programmer and the AVR
board. The resulting ISP6 connection is, as defined by AMEL, is shown on the left.
Standards always have alternative standards, that were used earlier. This is the
technical basis that constitutes the adaptor industry. In our case the alternative
standard was designed as ISP10 and was used on the STK200 board. It's still a
very widespread standard, and even the STK500 is still equipped with it. ISP10
has an additional signal to drive a red LED. This LED signals that the programmer
is doing his job. A good idea. Just connect the LED to a resistor and clamp it the
positive supply voltage.
Programmer for the PC-Parallel-Port
Now, heat up your soldering iron and build up your programmer. It is a quite easy schematic and works
with standard parts from your well-sorted experiments box.
Yes, that's all you need to program an AVR. The 25-pin plug goes into the parallel port of your PC, the 10pin-ISP goes to your AVR experimental board. If your box doesn't have a 74LS245, you can also use a
74HC245 or a 74LS244/74HC244 (by changing some pins and signals). If you use HC, don't forget to tie
unused inputs either to GND or the supply voltage, otherwise the buffers might produce extra noise by
capacitive switching.
Avr-Asm-Tutorial3http://www.avr-asm-tutorial.net
The necessary program algorithm is done by the ISP software, that is available from ATMEL's software
download page.
Experimental board with a AT90S2313
For test purposes we use a AT90S2313 on an experimental board. The schematic shows
•a small voltage supply for connection to an AC transformer and a voltage regulator 5V/1A,
•a XTAL clock generator (here with a 10 Mcs/s, all other frequencies below the maximum for the 2313
will also work),
•the necessary parts for a safe reset during supply voltage switching,
•the ISP-Programming-Interface (here with a ISP10PIN-connector).
So that's what you need to start with. Connect other peripheral add-ons to the numerous free I/O pins of
the 2313.
The easiest output device can be a LED, connected via a resistor to the positive supply voltage. With that,
you can start writing your first assembler program switching the LED on and off.
Avr-Asm-Tutorial4http://www.avr-asm-tutorial.net
Ready-to-use commercial programming boards for the
AVR-family
If you do not like homebrewed hardware, and if have some extra money left that you don't know what to do
with, you can buy a commercial programming board. Easy to get is the STK500 (e.g. from ATMEL. It has
the following hardware:
•Sockets for programming most of the AVR types,
•serial und parallel programming,
•ISP6PIN- and ISP10PIN-connector for external In-System-Programming,
•programmable oscillator frequency and suplly voltages,
•plug-in switches and LEDs,
•a plugged RS232C-connector (UART),
•a serial Flash-EEPROM,
•access to all ports via a 10-pin connector.
Experiments can start with the also supplied AT90S8515. The board is connected to the PC using a serial
port (COMx) and is controlled by later versions of AVR studio, available from ATMEL's webpage. This
covers all hardware requirements that the beginner might have.
Avr-Asm-Tutorial5http://www.avr-asm-tutorial.net
Tools for AVR assembly programing
This section provides informations about the necessary tools that are used to program AVRs with the
STK200 board. Programming with the STK500 is very different and shown in more detail in the Studio
section. Note that the older software for the STK200 is not supported any more.
Four basic programs are necessary for assembly programming. These tools are:
Now we type in our directives and
assembly commands in the WAVRASM
editor window, together with some
comments (starting with ;). That should
look like this:
Now store the program text, named to something.asm into a dedicated directory, using the file menue. The
assembly program is complete now.
If you like editing a little more in a sophisticated manner you can use the excellent editor written by Tan
Silliksaar. This editor tools is designed for AVRs and available for free from Tan's webpage. In this editor
our program looks like this:
Avr-Asm-Tutorial6http://www.avr-asm-tutorial.net
The editor recognizes commands automatically and uses
different colors (syntax highlighting) to signal user constants
and typing errors in those
commands (in black). Storing
the code in an .asm file provides
nearly the same text file.
The assembler reports the complete
translation with no errors. If errors occur
these are notified. Assembling resulted in
one word of code which resulted from the
command we used. Assembling our single
asm-text file now has produced four other
files (not all apply here).
The first of these four new files,
TEST.EEP, holds the content that should
be written to the EEPROM of the AVR.
This is not very interesting in our case,
because we didn't program any content
for the EEPROM. The assembler has
therefore deleted this file when he
completed the assembly run.
The second file, TEST.HEX, is more relevant
because this file holds the commands later
programmed into the AVR chip. This file
looks like this.
The hex numbers are written in a special
ASCII form, together with adress informations
and a checksum for each line. This form is
called Intel-hex-format, and it is very old. The
form is well understood by the programing
software.
The third file, TEST.OBJ, will be
introduced later, this file is needed to
simulate an AVR. Its format is
hexadecimal and defined by ATMEL.
Using a hex-editor its content looks
like this. Attention: This file format is
not compatible with the programer software, don't use
this file to program the AVR (a very common error when
starting).
The fourth file, TEST.LST, is a text file. Display its
content with a simple editor. The following results.
The program with all its adresses, comands and error
messages are displayed in a readable form. You will
need that file in some cases to debug errors.
Avr-Asm-Tutorial7http://www.avr-asm-tutorial.net
Programming the chips
To program our hex code to the AVR ATMEL has written the ISP software package. (Not that this software
is not supported and distributed any more.) We start the ISP software and load the hex file that we just
generated (applying menue item LOAD PROGRAM). That looks like this:
Applying menue item
PROGRAM will burn our
code in the chip's program
store. There are a number
of preconditions necessary
for this step (the correct
parallel port has to be
selected, the programming
adaptermustbe
connected, the chip must
be on board the adapter,
the power supply must be
on, etc.).
Besides the ATMEL-ISP
and the programming
boards other programming
boards or adapters could
be used, together with the
appropriate programming software. Some of these alternatives are available on the internet.
Simulation in the studio
In some cases self-written assembly code, even assembled without errors, does not exactly do what it
should do when burned into the chip. Testing the software on the chip could be complicated, esp. if you
have a minimum hardware and no opportunity to display interim results or debugging signals. In these
cases the studio from ATMEL provides ideal opportunities for debugging. Testing the software or parts of it
is possible, the program could be tested step-by-step displaying results.
The studio is started and looks like
this.
First we open a file (menue item FILE
OPEN). We demonstrate this using
the tutorial file test1.asm, because
there are some more commands and
action that in our single-command
program above.
Open the file TEST1.OBJ that results
by assembling TEST1.asm. You are
asked which options you like to use (if
not, you can change these using the
menue item SIMULATOR OPTIONS).
The following options will be selected:
In the device selection section we
select the desired chip type. The
correct frequency should be selected
if you like to simulate correct timings.
In order to view the content of some registers and what the processor's status is we select VIEW
PROCESSOR and REGISTERS. The display should now look like this.
Avr-Asm-Tutorial8http://www.avr-asm-tutorial.net
The processor window displays all
values like the command counter, the
flags and the timing information (here:
1 MHz clock). The stop watch can be
used to measure the necessary time
for going through routines etc.
Now we start the program execution. We use the single step
opportunity (TRACE INTO or F11). Using GO would result in
continous exection and not much would be seen due to the high
speed of simulation. After the first executed step the processor
window should look like this.
The program counter is at step 1, the cycle counter at 2 (RJMP
needed two cycles). At 1 MHz clock two microseconds have
been wasted, the flags and pointer registers are not changed.
The source text window displays a pointer on the next command
that will be executed.
Pressing F11 again executes the next command, register mp
(=R16) will be set to 0xFF. Now the register window should
highlite this change.
Register R16's new
value is displayed in
red letters. We can
change the value of a
register at any time to
test what happens
then.
Now step 3 is
executed, output to the
direction register of Port B.
To display this we open a
new I/O view window and
select Port B. The display
should look like this.
The Data Direction
Register in the I/O-view
window of Port B now
shows the new value. The
values could be changed
manually, if desired, pin by
pin.
The next two steps
are simulated using
F11. They are not
displayed here.
Setting the output
ports to one with
the command LDI
mp,0xFF and OUT PORTB,mp results in the following picture in the I/O view. Now the output port bits are
all one, the I/O view shows this.
That is our short trip through the simulator software world. The simulator is capable to much more, so it
should be applied extensively in cases of design errors. Visit the different menue items, there is much
more than showed here.
Avr-Asm-Tutorial9http://www.avr-asm-tutorial.net
Register
What is a register?
Registers are special storages with 8 bits capacity and they look like this:
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
Note the numeration of these bits: the least significant bit starts with zero (20 = 1).
A register can either store numbers from 0 to 255 (positive number, no negative values), or numbers from
-128 to +127 (whole number with a sign bit in bit 7), or a value representing an ASCII-coded character
(e.g. 'A'), or just eight single bits that do not have something to do with each other (e.g. for eight single
flags used to signal eight different yes/no decisions).
The special character of registers, compared to other storage sites, is that
•they can be used directly in assembler commands,
•operations with their content require only a single command word,
•they are connected directly to the central processing unit called the accumulator,
•they are source and target for calculations.
There are 32 registers in an AVR. They are originally named R0 to R31, but you can choose to name them
to more meaningful names using an assembler directive. An example:
.DEF MyPreferredRegister = R16
Assembler directives always start with a dot in column 1 of the text. Instructions do NEVER start in column
1, they are always preceeded by a Tab- or blank character!
Note that assembler directives like this are only meaningful for the assembler but do not produce any code
that is executable in the AVR target chip. Instead of using the register name R16 we can now use our own
name MyPreferredRegister, if we want to use R16 within a command. So we write a little bit more text each
time we use this register, but we have an association what might be the content of this register.
Using the command line
LDIMyPreferredRegister, 150
which means: load the number 150 immediately to the register R16, LoaD Immediate. This loads a fixed
value or a constant to that register. Following the assembly or translation of this code the program storage
written to the AVR chip looks like this:
000000 E906
The load command code as well as the target register (R16) as well as the value of the constant (150) is
part of the hex value E906, even if you don't see this directly. Don't be afraid: you don't have to remember
this coding because the assembler knows how to translate all this to yield E906.
Within one command two different registers can play a role. The easiest command of this type is the copy
command MOV. It copies the content of one register to another register. Like this:
The first two lines of this monster program are directives that define the new names of the registers R16
and R15 for the assembler. Again, these lines do not produce any code for the AVR. The command lines
with LDI and MOV produce code:
000000 E906
000001 2F01
The commands write 150 into register R16 and copy its content to the target register R15. IMPORTANT
NOTE:
The first register is always the target register where the result is written to!
(This is unfortunately different from what one expects or from how we speak. It is a simple convention that
was once defined that way to confuse the beginners learning assembler. That is why assembler is that
complicated.)
Avr-Asm-Tutorial10http://www.avr-asm-tutorial.net
Different registers
The beginner might want to write the above commands like this:
.DEF AnotherRegister = R15
LDI AnotherRegister, 150
And: you lost. Only the registers from R16 to R31 load a constant immediately with the LDI command, R0
to R15 don't do that. This restriction is not very fine, but could not be avoided during construction of the
command set for the AVRs.
There is one exception from that rule: setting a register to Zero. This command
CLR MyPreferredRegister
is valid for all registers.
Besides the LDI command you will find this register class restriction with the following additional
commands:
•ANDI Rx,K ; Bit-And of register Rx with a constant value K,
•CBR Rx,M ; Clear all bits in register Rx that are set to one within the constant mask value M,
•CPI Rx,K ; Compare the content of the register Rx with a constant value K,
•SBCI Rx,K ; Subtract the constant K and the current value of the carry flag from the content of
register Rx and store the result in register Rx,
•SBR Rx,M ; Set all bits in register Rx to one, that are one in the constant mask M,
•SER Rx ; Set all bits in register Rx to one (equal to LDI Rx,255),
•SUBI Rx,K ; Subtract the constant K from the content of register Rx and store the result in register
Rx.
In all these commands the register must be between R16 and R31! If you plan to use these commands
you should select one of these registers for that operation. It is easier to program. This is an additional
reason why you should use the directive to define a register's name, because you can easier change the
registers location afterwards.
Pointer-register
A very special extra role is defined for the register pairs R26:R27, R28:R29 and R30:R31. The role is so
important that these pairs have extra names in AVR assembler: X, Y and Z. These pairs are 16-bit pointer
registers, able to point to adresses with max. 16-bit into SRAM locations (X, Y or Z) or into locations in
program memory (Z).
The lower byte of the 16-bit-adress is located in the lower register, the higher byte in the upper register.
Both parts have their own names, e.g. the higher byte of Z is named ZH (=R31), the lower Byte is ZL
(=R30). These names are defined in the standard header file for the chips. Dividing these 16-bit-pointernames into two different bytes is done like follows:
.EQU Adress = RAMEND ; RAMEND is the highest 16-bit adress in SRAM
LDI YH,HIGH(Adress) ; Set the MSB
LDI YL,LOW(Adress) ; Set the LSB
Accesses via pointers are programmed with specially designed commands. Read access is named LD
(LoaD), write access named ST (STore), e.g. with the X-pointer:
PointerSequenceExamples
XRead/Write from adress X, don't change the pointerLD R1,X or ST X,R1
X+Read/Write from/to adress X and increment the pointer afterwards by
LD R1,X+ or ST X+,R1
one
-XDecrement the pointer by one and read/write from/to the new adress
LD R1,-X or ST -X,R1
afterwards
Similiarly you can use Y and Z for that purpose.
There is only one command for the read access to the program storage. It is defined for the pointer pair Z
and it is named LPM (Load from Program Memory). The command copies the byte at adress Z in the
program memory to the register R0. As the program memory is organised word-wise (one command on
one adress consists of 16 bits or two bytes or one word) the least significant bit selects the lower or higher
byte (0=lower byte, 1= higher byte). Because of this the original adress must be multiplied by 2 and access
is limited to 15-bit or 32 kB program memory. Like this:
Avr-Asm-Tutorial11http://www.avr-asm-tutorial.net
LDI ZH,HIGH(2*Adress)
LDI ZL,LOW(2*Adress)
LPM
Following this command the adress must be incremented to point to the next byte in program memory. As
this is used very often a special pointer incrementation command has been defined to do this:
ADIW ZL,1
LPM
ADIW means ADd Immediate Word and a maximum of 63 can be added this way. Note that the assembler
expects the lower of the pointer register pair ZL as first parameter. This is somewhat confusing as addition
is done as 16-bit- operation.
The complement command, subtracting a constant value of between 0 and 63 from a 16-bit pointer
register is named SBIW, Subtract Immediate Word. (SuBtract Immediate Word). ADIW and SBIW are
possible for the pointer register pairs X, Y and Z and for the register pair R25:R24, that does not have an
extra name and does not allow access to SRAM or program memory locations. R25:R24 is ideal for
handling 16-bit values.
How to insert that table of values in the program memory? This is done with the assembler directives .DB
and .DW. With that you can insert bytewise or wordwise lists of values. Bytewise organised lists look like
this:
.DB 123,45,67,89 ; a list of four bytes
.DB "This is a text. " ; a list of byte characters
You should always place an even number of bytes on each single line. Otherwise the assembler will add a
zero byte at the end, which might be unwanted.
The similiar list of words looks like this:
.DW 12345,6789 ; a list of two words
Instead of constants you can also place labels (jump targets) on that list, like that:
Label1:
[ ... here are some commands ... ]
Label2:
[ ... here are some more commands ... ]
Table:
.DW Label1,Label2 ; a wordwise list of labels
Labels ALWAYS start in column 1!. Note that reading the labels with LPM first yields the lower byte of the
word.
A very special application for the pointer registers is the access to the registers themselves. The registers
are located in the first 32 bytes of the chip's adress space (at adress 0x0000 to 0x001F). This access is
only meaningful if you have to copy the register's content to SRAM or EEPROM or read these values from
there back into the registers. More common for the use of pointers is the access to tables with fixed values
in the program memory space. Here is, as an example, a table with 10 different 16-bit values, where the
fifth table value is read to R25:R24:
MyTable:
.DW 0x1234,0x2345,0x3456,0x4568,0x5678 ; The table values, wordwise
.DW 0x6789,0x789A,0x89AB,0x9ABC,0xABCD ; organised
Read5: LDI ZH,HIGH(MyTable*2) ; Adress of table to pointer Z
LDI ZL,LOW(MyTable*2) ; multiplied by 2 for bytewise access
ADIW ZL,10 ; Point to fifth value in table
LPM ; Read least significant byte from program memory
MOV R24,R0 ; Copy LSB to 16-bit register
ADIW ZL,1 ; Point to MSB in program memory
LPM ; Read MSB of table value
MOV R25,R0 ; Copy MSB to 16-bit register
This is only an example. You can calculate the table adress in Z from some input value, leading to the
respective table values. Tables can be organised byte- or character-wise, too.
Recommendation for the use of registers
•Define names for registers with the .DEF directive, never use them with their direct name Rx.
•If you need pointer access reserve R26 to R31 for that purpose.
•16-bit-counter are best located R25:R24.
•If you need to read from the program memory, e.g. fixed tables, reserve Z (R31:R30) and R0 for that
purpose.
•If you plan to have access to single bits within certain registers (e.g. for testing flags), use R16 to
R23 for that purpose.
Avr-Asm-Tutorial12http://www.avr-asm-tutorial.net
Ports
What is a Port?
Ports in the AVR are gates from the central processing unit to internal and external hard- and software
components. The CPU communicates with these components, reads from them or writes to them, e.g. to
the timers or the parallel ports. The most used port is the flag register, where results of previous operations
are written to and branch conditions are read from.
There are 64 different ports, which are not physically available in all different AVR types. Depending on the
storage space and other internal hardware the different ports are either available and accessable or not.
Which of these ports can be used is listed in the data sheets for the processor type.
Ports have a fixed address, over which the CPU communicates. The address is independent from the type
of AVR. So e.g. the port adress of port B is always 0x18 (0x stands for hexadecimal notation). You don't
have to remember these port adresses, they have convenient aliases. These names are defined in the
include files (header files) for the different AVR types, that are provided from the producer. The include
files have a line defining port B's address as follows:
.EQU PORTB, 0x18
So we just have to remember the name of port B, not its location in the I/O space of the chip. The include
file 8515def.inc is involved by the assembler directive
.INCLUDE "C:\Somewhere\8515def.inc"
and the registers of the 8515 are all defined then and easily accessable.
Ports usually are organised as 8-bit numbers, but can also hold up to 8 single bits that don't have much to
do with each other. If these single bits have a meaning they have their own name associated in the include
file, e.g. to enable manipulation of a single bit. Due to that name convention you don't have to remember
these bit positions. These names are defined in the data sheets and are given in the include file, too. They
are provided here in the port tables.
As an example the MCU General Control Register, called MCUCR, consists of a number of single control
bits that control the general property of the chip (see the description in MCUCR in detail). It is a port, fully
packed with 8 control bits with their own names (ISC00, ISC01, ...). Those who want to send their AVR to
a deep sleep need to know from the data sheet how to set the respective bits. Like this:
.DEF MyPreferredRegister = R16
LDI MyPreferredRegister, 0b00100000
OUT MCUCR, MyPreferredRegister
SLEEP
The Out command brings the content of my preferred register, a Sleep-Enable-Bit called SE, to the port
MCUCR and sets the AVR immediately to sleep, if there is a SLEEP instruction executed. As all the other
bits of MCUCR are also set by the above instructions and the Sleep Mode bit SM was set to zero, a mode
called half-sleep will result: no further command execution will be performed but the chip still reacts to
timer and other hardware interrupts. These external events interrupt the big sleep of the CPU if they feel
they should notify the CPU.
Reading a port's content is in most cases possible using the IN command. The following sequence
.DEF MyPreferredRegister = R16
IN MyPreferredRegister, MCUCR
reads the bits in port MCUCR to the register. As many ports have undefined and unused bits in certain
ports, these bits always read back as zeros.
More often than reading all 8 bits of a port one must react to a certain status of a port. In that case we don't
need to read the whole port and isolate the relevant bit. Certain commands provide an opportunity to
execute commands depending on the level of a certain bit (see the JUMP section). Setting or clearing
certain bits of a port is also possible without reading and writing the other bits in the port. The two
commands are SBI (Set Bit I/o) and CBI (Clear Bit I/o). Execution is like this:
.EQU ActiveBit=0 ; The bit that is to be changed
SBI PortB, ActiveBit ; The bit will be set to one
CBI PortB, Activebit ; The bit will be cleared to zero
These two instructions have a limitation: only ports with an adress smaller than 0x20 can be handled, ports
above cannot be accessed that way.
For the more exotic programmer: the ports can be accessed using SRAM access commands, e.g. ST and
LD. Just add 0x20 to the port's adress (the first 32 addresses are the registers!) and access the port that
way. Like demonstrated here:
.DEF MyPreferredRegister = R16
LDI ZH,HIGH(PORTB+32)
Avr-Asm-Tutorial13http://www.avr-asm-tutorial.net
LDI ZL,LOW(PORTB+32)
LD MyPreferredRegister,Z
That only makes sense in certain cases, but it is possible. It is the reason why the first address location of
the SRAM is always 0x60.
Details of relevant ports in the AVR
The following table holds the most used ports. Not all ports are listed here, some of the MEGA and
AT90S4434/8535 types are skipped. If in doubt see the original reference.
ComponentPortnamePort-Register
AccumulatorSREGStatus Register
StackSPL/SPHStackpointer
External SRAM/External Interrupt MCUCRMCU General Control Register
External InterruptGIMSKInterrupt Mask Register
GIFRInterrupt Flag Register
Timer InterruptTIMSKTimer Interrupt Mask Register
TIFRTimer Interrupt Flag Register
Timer 0TCCR0Timer/Counter 0 Control Register
TCNT0Timer/Counter 0
Timer 1TCCR1ATimer/Counter Control Register 1 A
TCCR1BTimer/Counter Control Register 1 B
TCNT1Timer/Counter 1
OCR1AOutput Compare Register 1 A
OCR1BOutput Compare Register 1 B
ICR1L/HInput Capture Register
Watchdog TimerWDTCRWatchdog Timer Control Register
EEPROMEEAREEPROM Adress Register
EEDREEPROM Data Register
EECREEPROM Control Register
SPISPCRSerial Peripheral Control Register
SPSRSerial Peripheral Status Register
SPDRSerial Peripheral Data Register
UARTUDRUART Data Register
USRUART Status Register
UCRUART Control Register
UBRRUART Baud Rate Register
Analog ComparatorACSRAnalog Comparator Control and Status Register
I/O-PortsPORTxPort Output Register
DDRxPort Direction Register
PINxPort Input Register
The status register as the most used port
By far the most often used port is the status register with its 8 bits. Usually access to this port is only by
automatic setting and clearing bits by the CPU or accumulator, some access is by reading or branching on
certain bits in that port, in a few cases it is possible to manipulate these bits directly (using the assembler
command SEx or CLx, where x is the bit abbreviation). Most of these bits are set or cleared by the
accumulator through bit-test, compare- or calculation-operations. The following list has all assembler
commands that set or clear status bits depending on the result of the execution.
Avr-Asm-Tutorial14http://www.avr-asm-tutorial.net
BitCalculationLogicCompareBitsShiftOther
ZADD, ADC, ADIW, DEC,
INC, SUB, SUBI, SBC,
SBCI, SBIW
CADD, ADC, ADIW, SUB,
SUBI, SBC, SBCI, SBIW
NADD, ADC, ADIW, DEC,
INC, SUB, SUBI, SBC,
SBCI, SBIW
VADD, ADC, ADIW, DEC,
INC, SUB, SUBI, SBC,
SBCI, SBIW
SSBIW--BCLR S,
HADD, ADC, SUB, SUBI,
SBC, SBCI
T---BCLR T,
AND, ANDI, OR,
ORI, EOR, COM,
NEG, SBR, CBR
COM, NEGCP, CPC,
AND, ANDI, OR,
ORI, EOR, COM,
NEG, SBR, CBR
AND, ANDI, OR,
ORI, EOR, COM,
NEG, SBR, CBR
NEGCP, CPC,
CP, CPC,
CPI
CPI
CP, CPC,
CPI
CP, CPC,
CPI
CPI
BCLR Z,
BSET Z, CLZ,
SEZ, TST
BCLR C,
BSET C,
CLC, SEC
BCLR N,
BSET N, CLN,
SEN, TST
BCLR V,
BSET V, CLV,
SEV, TST
BSET S, CLS,
SES
BCLR H,
BSET H, CLH,
SEH
BSET T, BST,
CLT, SET
ASR, LSL,
LSR, ROL,
ROR
ASR, LSL,
LSR, ROL,
ROR
ASR, LSL,
LSR, ROL,
ROR
ASR, LSL,
LSR, ROL,
ROR
--
--
--
CLR
-
CLR
CLR
I---BCLR I, BSET
I, CLI, SEI
Port details
Port details of the most common ports are shown in an extra table (see annex).
-RETI
Loading...
+ 40 hidden pages
You need points to download manuals.
1 point = 1 manual.
You can buy points or you can get point for every manual you upload.