Anda di halaman 1dari 7

En esta seccin se muestran unos ejemplos sencillos de programacin en ensamblador de AVRs de la casa ATMEL.

El cdigo utilizado es para el ATMEL AVR Assembler y si se desea utilizar estos mismos ejemplos para el AVR IAR Assembler debemos realizar algunas modificaciones en el cdigo. Estos cambios se comentan en el apartado Ensamblador para AVRs. Solo deberamos cambiar algunas directivas que tienen distinto formato ya que las instrucciones son las mismas para ambos programas. Estos ejemplos son muy tiles para la gente que est empezando a programar en ensamblador con los microcontroladores AVR. Podr encontrar ejemplos de utilizacin del Watchdog, de SRAM, EEPROM, Comparador Analgico, UART y del convertidor A/D. Las notas que acompaan a los programas le permitirn seguir de una manera sencilla paso a paso lo que se est realizando en cada momento.

ESTABLECIMIENTO Y CONTROL DEL WATCHDOG


DESCRIPCIN Esta aplicacin muestra como establecer y controlar el timer Watchdog para los dispositivosAT90S1300,AT90S2312 y AT90S8414. Se supone una frecuencia de CPU de 10MHz.

.include "2312def.inc" rjmp RESET ;Salto relativo a la subrutina RESET ;* ;* "delay" ;* ;* Esta subrutina genera una demora basada en el parmetro de entrada "del". ;* La demora resultante viene dada por: ;* ;* delay = del * 0.1 ms (aproximadamente) ;* ;* Nmero de words : 7 ;* Nmero de ciclos : 1026 * del + 4 ;* Registros bajos usados : 1(delcnt) ;* Registros altos usados : 1(del) ;* ;***** Variables de registro de la Subrutina .def del = r16 ;Tamao del bloque que se va a copiar .def delcnt = r0 ;Contador de "loop" ;***** Cdigo delay:

clr loop:

delcnt

;Inicio contador "loop" ;Decrementar delcnt ;No operar ;Desvo a loop si el flag Z de SREG es cero ;Decrementar del ;Desvo a loop si el flag Z de SREG es cero ;Retorno de subrutina

dec delcnt nop brne loop dec del brne loop ret

;* ;* Programa Principal ;* ;* Este programa empieza habilitando el watchdog con un periodo de timeout de 16 ;*ms. El programa entonces empieza un camino donde el watchdog se resetea en un ;*periodo aproximado de 10 ms. Cuando acaba este primer camino, el programa entra ;*en un segundo camino donde el watchdog se resetea cada 20 ms. Este camino nunca ;*funcionar porque el watchdog resetea la CPU 16 ms despus de la ltima ;*instruccin wdr. ;* ;***** Variables de registro del Programa Principal .def temp = r16 ;Variable de almacenamiento temporal .def counter = r17 ;Contador de "loop" ;***** Cdigo RESET: ldi temp,RAMTOP out SPL,temp ;Inicio del Stack Pointer ;* ;* Inicializar el timer Watchdog ;* ;* Este trozo de cdigo habilita el timer watchdog e introduce un periodo de 16 ms de ;* timeout ;* ;* Nmero de words: 3 ;* Nmero de ciclos: 3 ;* Registros bajos usados: 1(temp) ;* Registros altos usados: Ninguno ;* wdr ;Reset del timer watchdog antes de habilitarlo para ;prevenir los reset no deseados antes del wdr siguiente ldi temp,(1<<WDE) ;Habilitar el timer Watchdog y poner 16 ms de out WDTCR,temp timeout ;***** Rutina que llega hasta el final porque se produce un reset de watchdog cada ;***** 10 ms. ldi counter,5 ;Iniciar el contador de loop mloop1: wdr ;Reset de watchdog ldi del,100

rcall delay ;Generar un retardo de 10 ms dec counter brne mloop1 ;Volver a mloop1 si no acaba ldi counter,5 ;Iniciar el contador de loop ;***** Rutina que no llega nunca hasta el final porque el reset de watchdog se da ;***** despus de 20 ms. mloop2: wdr ;Reset de watchdog ldi del,200 rcall delay ;Genera un retardo de 20 ms ;------------------ CDIGO NO EJECUTABLE! -----------------dec counter brne mloop2 ;Volver a mloop2 forever:

rjmp

forever LECTURA Y ESCRITURA EN EEPROM

DESCRIPCIN Esta aplicacin muestra como leer y escribir datos en la EEPROM del AVR AT90S1200. Se listan las rutinas de acceso aleatorio y secuencial. Para el resto de dispositivos el bit de habilitacin de escritura maestro EEMWE debe ponerse a set previamente a poner a set el bit EEWE.

.include "1200def.inc" rjmp RESET ;Salto relativo a la subrutina RESET ;* ;* EEWrite ;* Esta subrutina espera hasta que la EEPROM est preparada para ser ;* programada, entonces programa la EEPROM con la variable de registro "EEdwr" ;* en la direccin "EEawr" ;* ;* ;* Nmero de words : 5 + return ;* Nmero de ciclos : 10 + return (si la EEPROM est disponible) ;* Registros bajos usados : Ninguno ;* Registros altos usados : 2 (EEdwr,EEawr) ;* ;***** Variables de registro de la Subrutina .def EEdwr =r16 ;Byte de dato a escribir en la EEPROM .def EEawr =r17 ;Direccin en la que escribir

;***** Cdigo EEWrite: sbic EECR,EEWE rjmp EEWrite out EEAR,EEawr out EEDR,EEdwr sbi EECR,EEWE

;Saltar la siguiente instruccin si EEWE est ;borrado ;Esperar ms si EEWE no est borrado ;Escribir la direccin de salida en EEAR ;Escribir el dato de salida ;Poner a 1 el bit EEWE ( EEPROM Write strobe ) ;Este bit habilita la escritura en EEPROM ;Esta instruccin necesita 4 ciclos de clock ya que ;detiene la CPU durante dos ciclos de clock

ret ;* ;* EERead ;* ;* Esta subrutina espera hasta que la EEPROM est preparada para ser ;* programada, entonces lee la variable de registro "EEdrd" desde la direccin ;* "EEard" ;* ;* Nmero de words : 6 + return ;* Nmero de ciclos : 12 + return (Si la EEPROM est disponible) ;* Registros bajos usados : 1 (EEdrd) ;* Registros altos usados : 1 (EEard) ;* ;***** Variables de registro de la Subrutina .def EEdrd = r0 ;Byte de dato resultado .def EEard = ;Direccin de la que leer r16 ;***** Cdigo EERead: sbic EECR,EEWE ;Saltar la siguiente instruccin si EEWE est ;borrado rjmp EERead ;Esperar ms si EEWE no est borrado out EEDR,EEard ;Escribir la direccin de salida sbi EECR,EERE ;Poner a 1 el bit EEWE ( EEPROM Read strobe ) ;Esta instruccin necesita 4 ciclos de clock ya que ;detiene la CPU durante dos ciclos de clock sbi EECR,EERE ;Poner a 1 el bit EEWE ( EEPROM Read strobe ;2nd time ) ;Esta instruccin necesita 4 ciclos de clock ya que ;detiene la CPU durante dos ciclos de clock ;Al poner a set EERE se detiene la CPU durante 4 ;ciclos de clock in EEdrd,EEDR ;Obtener el dato

ret ;* ;* EEWrite_seq ;* ;* Esta subrutina incrementa por uno la direccin de EEPROM y espera hasta que la ;* EEPROM est preparada para ser programada. Entonces programa la EEPROM ;* con la variable de registro "EEdwr_s". ;* ;* Nmero de words : 7 + return ;* Nmero de ciclos : 10 + return (si la EEPROM est disponible) ;* Registros bajos usados : 1 (EEWtmp) ;* Registros altos usados : 1 (EEdwr_s) ;* ;***** Variables de registro de la Subrutina .def EEwtmp = r0 ;Almacenamiento temporal de la direccin .def EEdwr_s = r16 ;Dato que se va a escribir ;***** Cdigo EEWrite_seq: sbic EECR,EEWE ;Saltar la siguiente instruccin si EEWE est ;borrado rjmp EEWrite_seq ;Esperar ms si EEWE no est borrado in EEwtmp,EEAR ;Obtener la direccin inc EEwtmp ;Incrementar la direccin out EEAR,EEwtmp ;Escribir la direccin de salida out EEDR,EEdwr_s ;Escribir el dato de salida sbi EECR,EEWE ;Poner a 1 el bit EEWE ( EEPROM Write strobe ) ;Este bit es el de habilitacin de escritura en ;EEPROM ;Esta instruccin necesita 4 ciclos de clock ya que ;detiene la CPU durante dos ciclos de clock ret ;* ;* EERead_seq ;* ;* Esta subrutina incrementa la direccin almacenada en EEAR y lee la EEPROM ;* en la variable de registro "EEdrd_s". ;* ;* Nmero de words : 6 + return ;* Nmero de ciclos : 12 + return (si la EEPROM est disponible) ;* Low Registers used : 2 (EErtmp,EEdrd_s) ;* High Registers used: : Ninguno ;* ;***** Variables de registro de la Subrutina .def EErtmp = r0 ;Almacenamiento temporal de la direccin .def EEdrd_s = r1 ;Byte de dato resultado

;***** Code EERead_seq: in EErtmp,EEAR inc EErtmp out EEAR,EErtmp sbi EECR,EERE

sbi

in ret

;Obtener la direccin ;Incrementar la direccin ;Escribir la direccin de salida ;Poner a 1 el bit EEWE ( EEPROM Read strobe ) ;Esta instruccin necesita 4 ciclos de clock ya que ;detiene la CPU durante dos ciclos de clock EECR,EERE ;Poner a 1 el bit EEWE ( EEPROM Read strobe ;2nd time ) ;Esta instruccin necesita 4 ciclos de clock ya que ;detiene la CPU durante dos ciclos de clock ;Al poner a set EERE se detiene la CPU durante 4 ;ciclos de clock EEdrd_s,EEDR ;Obtener el dato

;* ;* Programa de Test/Ejemplo ;* ;***** Variables de registro del Programa Principal .def counter = r18 .def temp = r19 ;***** Cdigo RESET: ;***** Programar una posicin aleatoria ldi EEdwr,$aa ldi EEawr,$10 rcall EEWrite ;Almacena $aa en la posicin $10 de EEPROM ;***** Leer desde unas posiciones aleatorias ldi EEard,$10 rcall EERead ;Leer la direccin $10 out PORTB,EEdrd ;Escribir el valor de salida en el Puerto B ;***** Rellenar la EEPROM con el patrn $55,$aa,$55,$aa,... ldi counter,64 ;Iniciar el contador de "loop" ser temp ;Pone TEMP a set ( $ff ) out EEAR,temp ;EEAR <- $ff (Direccin de comienzo - 1) loop1: ldi EEdwr_s,$55 rcall EEWrite_seq ;programar la EEPROM con $55 ldi EEdwr_s,$aa rcall EEWrite_seq ;Programar la EEPROM con $aa dec counter ;decrement counter brne loop1 ;saltar a loop1 si Z = 0, es decir Rd no igual que Rr ;***** Copiar los 10 primeros bytes de la EEPROM a los registros r2-r11 ldi temp,$ff out EEAR,temp ;EEAR <- $ff (Direccin de comienzo - 1)

ldi loop2: rcall st inc cpi brne forever: rjmp

ZL,2 EERead_seq Z,EEdrd_s ZL ZL,12 loop2 forever

;El puntero Z apunta al registro r2 ;Obtener el dato de la EEPROM ;Almacenar en la SRAM ;Comprueba si ha llegado al final ;saltar a loop2 si Z = 0, es decir Rd no igual que Rr ;Mantenimiento en "forever"

Anda mungkin juga menyukai