Documente Academic
Documente Profesional
Documente Cultură
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.
.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
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)
;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"