Docstoc

Tutorial AVR

Document Sample
Tutorial AVR Powered By Docstoc
					AVR Learning – Original from http://8051projects.net

CODE:
.include "8515def.inc"

This include the definition file for ATmega8515, so that we can directly address the registers with
their names.
All AVRs have 32 general purpose registers from R0 - R32.
R0-R15 registers have certain restrictions of use, i.e. they are not allowed to load immediate value.
e.g. LDI R15, $35
the above statement will give you an error, saying "Invalid Register"
Where as registers from R16-R32 can be used for this purpose i.e.
LDI R16,$35
is a valid statement.
You can move values from one register to other by using
MOV R15,R16

Not only the registers from R0 to R15 has restriction on LDI but also other commands where the use of
R0-R16 is not allowed. usually all commands having immediate operands are not allowed.
For the ease of programming, you can also give names to the register like
CODE:
.def myregister = R16


There are some special registers like X,Y and Z for 16-Bit operations. They are used to read and write
to XRAM. They are also used for reading from program memory like reading from a lookup table (we
will discuss about them when we use them). These special registers are actually combination of two 8-
bit General purpose registers. i.e. X is actually R26:R27, Y is R28:R29 and Z is R30:R31.
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 as ZH (R31) and the lower Byte is
ZL (R30). Similarly for X (XL and XH) and for Y (YL and YH). These names are defined in the
standard header file for the chips (which we include while writing program). Dividing these 16-bit-
pointer-names into two different bytes is done like follows:
CODE:
LDI YH,HIGH(LABEL) ; Set the MSB
LDI YL,LOW(LABEL) ; Set the LSB

where LABEL is address for any lookup table or any memory location.

Some important notes for using registers

    1. Define names for registers with the .DEF directive, never use them with their direct name Rx.
       This helps you making better use of registers and you will never confuse yourself while using
       them.
    2. If you need pointer access reserve R26 to R31 for that purpose.
    3. 16-bit-counter are best located R25:R24.
    4. If you need to read from the program memory, e.g. fixed tables, reserve Z (R31:R30) and R0 for
       that
       purpose.
    5. If you plan to have access to single bits within certain registers (e.g. for testing flags), use R16
       to
       R23 for that purpose


Now coming to ports, The information about a specific port of a certain type of AVR can be easily
obtained in the AVR Datasheet. Port names are defined in the include file of the CPU..
if you don't have an include file then you can define yourself as..
CODE:
.equ PORTA = $1B ;incase of ATmega8515

So if you are not able to find an include file you can use the .EQU directive to define ports and other
registers.
Making port as i/p or o/p is purely dependent on data direction register called DDRx (DDRA for port A
etc.) The DDxn bit in the DDRx Register selects the direction of this pin. If DDxn is written
logic one, Pxn is configured as an output pin. If DDxn is written logic zero, Pxn is configured
as an input pin.
for writing and reading data to Ports, PORTx registers are there. and to read from ports PINx registers
are there.
for example..
writing to port
CODE:
.def output = R16
LDI output, $FF
OUT DDRA, output ; making as o/p
LDI output, $00
OUT PORTA, output ; clear all PORTA pins

Reading from port
CODE:
.def input = R17
LDI input, $00
OUT DDRA,input
IN input, PINA



We are finished with the basics of AVR, lets try programming with simplest program. Blinking an
LED!
CODE:
.include "8515def.inc"                   ;Include file

         RJMP MAIN                                            ;Reset vector

MAIN:
         ldi   R16,low(RAMEND)            ;Load stack with
         out   SPL,R16                            ;RAMEND - highest value
         ldi   R16,high(RAMEND)   ;of internal SRAM
         out   SPH,R16
         SBI   DDRA,0                            ;Make PORTA Pin 0 as o/p

DO:
         SBI PORTA,0                             ;Set Pin 0 of PORTA
         RCALL DELAY                             ;Wait for some time
         CBI PORTA,0                             ;Cleare Pin 0 of PORTA
         RCALL DELAY                             ;Wait for some time
         RJMP DO                                 ;Forever loop!

DELAY:                                           ;The delay routine
         LDI R16,$20                             ;Load some delay value
LOOP1:
         SER R17                                 ;Make R17 as $FF
LOOP:
         DEC R17                                 ;Decrement R17
         BRNE LOOP                               ;Jump if not zero
         DEC R16                                 ;Decrement R16
         BRNE LOOP1                              ;Jump if not zero
         RET                                             ;Return

				
DOCUMENT INFO
Description: this is tutorial for AVR beginner,, i hope , it can make you learn easily