En esta sección se muestran unos ejemplos sencillos de programación en ensamblador de AVRs de la...
-
Upload
marco-antonio-yujra-gutierrez -
Category
Documents
-
view
142 -
download
2
Transcript of En esta sección se muestran unos ejemplos sencillos de programación en ensamblador de AVRs de la...
En esta sección se muestran unos ejemplos sencillos de programación en ensamblador de AVRs de la casa ATMEL. El código 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 código. Estos cambios se comentan en el apartado Ensamblador para AVRs. Solo deberíamos 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 utilización del Watchdog, de SRAM, EEPROM, Comparador Analógico, UART y del convertidor A/D. Las notas que acompañan a los programas le permitirán seguir de
una manera sencilla paso a paso lo que se está realizando en cada momento.ESTABLECIMIENTO Y CONTROL DEL WATCHDOG
DESCRIPCIÓNEsta aplicación 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 parámetro de entrada "del".;* La demora resultante viene dada por:;*;* delay = del * 0.1 ms (aproximadamente);*;* Número de words : 7;* Número de ciclos : 1026 * del + 4;* Registros bajos usados : 1(delcnt);* Registros altos usados : 1(del);*;***** Variables de registro de la Subrutina.def del = r16 ;Tamaño del bloque que se va a copiar.def delcnt = r0 ;Contador de "loop";***** Códigodelay: clr delcnt ;Inicio contador "loop"loop: dec delcnt ;Decrementar delcnt nop ;No operar brne loop ;Desvío a loop si el flag Z de SREG es cero dec del ;Decrementar del
brne loop ;Desvío a loop si el flag Z de SREG es cero ret ;Retorno de subrutina;*;* 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 después de la última;*instrucción wdr.;*;***** Variables de registro del Programa Principal.def temp = r16 ;Variable de almacenamiento temporal.def counter = r17 ;Contador de "loop";***** CódigoRESET: ldi temp,RAMTOP out SPL,temp ;Inicio del Stack Pointer;*;* Inicializar el timer Watchdog;*;* Este trozo de código habilita el timer watchdog e introduce un periodo de 16 ms de;* timeout;*;* Número de words: 3;* Número 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)
out WDTCR,temp;Habilitar el timer Watchdog y poner 16 ms de timeout
;***** Rutina que llega hasta el final porque se produce un reset de watchdog cada;***** 10 ms. ldi counter,5 ;Iniciar el contador de loopmloop1: 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;***** después de 20 ms.
mloop2: wdr ;Reset de watchdog ldi del,200 rcall delay ;Genera un retardo de 20 ms;------------------ CÓDIGO NO EJECUTABLE! ------------------ dec counter brne mloop2 ;Volver a mloop2forever: rjmp forever
LECTURA Y ESCRITURA EN EEPROM
DESCRIPCIÓN
Esta aplicación 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 habilitación 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 dirección "EEawr";*;*;* Número de words : 5 + return;* Número 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 ;Dirección en la que escribir;***** CódigoEEWrite: sbic EECR,EEWE ;Saltar la siguiente instrucción si EEWE está
;borrado rjmp EEWrite ;Esperar más si EEWE no está borrado out EEAR,EEawr ;Escribir la dirección de salida en EEAR
out EEDR,EEdwr ;Escribir el dato de salida sbi EECR,EEWE ;Poner a 1 el bit EEWE ( EEPROM Write strobe )
;Este bit habilita la escritura en EEPROM;Esta instrucción 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 dirección;* "EEard";*;* Número de words : 6 + return;* Número 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 = r16 ;Dirección de la que leer;***** CódigoEERead: sbic EECR,EEWE ;Saltar la siguiente instrucción si EEWE está
;borrado rjmp EERead ;Esperar más si EEWE no está borrado out EEDR,EEard ;Escribir la dirección de salida sbi EECR,EERE ;Poner a 1 el bit EEWE ( EEPROM Read strobe )
;Esta instrucción 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 instrucción 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 dirección de EEPROM y espera hasta que la;* EEPROM está preparada para ser programada. Entonces programa la EEPROM
;* con la variable de registro "EEdwr_s".;*;* Número de words : 7 + return;* Número 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 dirección.def EEdwr_s = r16 ;Dato que se va a escribir;***** CódigoEEWrite_seq: sbic EECR,EEWE ;Saltar la siguiente instrucción si EEWE está
;borrado rjmp EEWrite_seq ;Esperar más si EEWE no está borrado in EEwtmp,EEAR ;Obtener la dirección inc EEwtmp ;Incrementar la dirección out EEAR,EEwtmp ;Escribir la dirección 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 habilitación de escritura en;EEPROM;Esta instrucción necesita 4 ciclos de clock ya que;detiene la CPU durante dos ciclos de clock
ret;*;* EERead_seq;*;* Esta subrutina incrementa la dirección almacenada en EEAR y lee la EEPROM;* en la variable de registro "EEdrd_s".;*;* Número de words : 6 + return;* Número 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 dirección.def EEdrd_s = r1 ;Byte de dato resultado;***** CodeEERead_seq: in EErtmp,EEAR ;Obtener la dirección inc EErtmp ;Incrementar la dirección out EEAR,EErtmp ;Escribir la dirección de salida sbi EECR,EERE ;Poner a 1 el bit EEWE ( EEPROM Read strobe )
;Esta instrucción 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 instrucción 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_s,EEDR ;Obtener el dato ret;*;* Programa de Test/Ejemplo;*;***** Variables de registro del Programa Principal.def counter = r18.def temp = r19;***** CódigoRESET:;***** Programar una posición aleatoria ldi EEdwr,$aa ldi EEawr,$10 rcall EEWrite ;Almacena $aa en la posición $10 de EEPROM;***** Leer desde unas posiciones aleatorias ldi EEard,$10 rcall EERead ;Leer la dirección $10 out PORTB,EEdrd ;Escribir el valor de salida en el Puerto B;***** Rellenar la EEPROM con el patrón $55,$aa,$55,$aa,... ldi counter,64 ;Iniciar el contador de "loop" ser temp ;Pone TEMP a set ( $ff ) out EEAR,temp ;EEAR <- $ff (Dirección 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 (Dirección de comienzo - 1) ldi ZL,2 ;El puntero Z apunta al registro r2loop2:
rcall EERead_seq ;Obtener el dato de la EEPROM st Z,EEdrd_s ;Almacenar en la SRAM inc ZL cpi ZL,12 ;Comprueba si ha llegado al final brne loop2 ;saltar a loop2 si Z = 0, es decir Rd no igual que Rr
forever: rjmp forever ;Mantenimiento en "forever"