En esta sección se muestran unos ejemplos sencillos de programación en ensamblador de AVRs de la...

10
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ÓN Esta 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) ;*

Transcript of En esta sección se muestran unos ejemplos sencillos de programación en ensamblador de AVRs de la...

Page 1: En esta sección se muestran unos ejemplos sencillos de programación en ensamblador de AVRs de la casa ATMEL

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

Page 2: En esta sección se muestran unos ejemplos sencillos de programación en ensamblador de AVRs de la casa ATMEL

          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.

Page 3: En esta sección se muestran unos ejemplos sencillos de programación en ensamblador de AVRs de la casa ATMEL

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

Page 4: En esta sección se muestran unos ejemplos sencillos de programación en ensamblador de AVRs de la casa ATMEL

          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

Page 5: En esta sección se muestran unos ejemplos sencillos de programación en ensamblador de AVRs de la casa ATMEL

;* 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

Page 6: En esta sección se muestran unos ejemplos sencillos de programación en ensamblador de AVRs de la casa ATMEL

;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

Page 7: En esta sección se muestran unos ejemplos sencillos de programación en ensamblador de AVRs de la casa ATMEL

forever:          rjmp     forever ;Mantenimiento en "forever"