UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
TEMA1: ARQUITECTURA DE LOS AVR INTRODUCCIÓN Aprender a programar microcontroladores significa aprender a usar todos sus recursos para luego aplicarlos en el diseño deseado. Es un proceso continuo, sistemático y que demanda por sobre todo bastante paciencia. En este capítulo empezaremos por conocer el hardware interno de los AVR enfocándonos en los megaAVR de las series ATmegaXX8 y ATmegaXX4, que son actualmente los mejores microcontroladores de 8 bits de Atmel disponibles en encapsulados DIP de 28 y 40 pines respectivamente. Las XX indican los kBytes de memoria FLASH que lleva el megaAVR, por ejemplo, el ATmega168A tiene 16 kBytes de FLASH. Entre los miembros de estas familias podemos citar al ATmega48A, ATmega88P, ATmega168PA, ATmega328P, ATmega164A, ATmega324P, ATmega644PA y ATmega1284P. Como se puede notar, al final de cada nombre todavía puede aparecer un sufijo como A, P, V o PA, que identifica una característica adicional del megaAVR como ser de una sub-serie que opera a bajo voltaje (V) o que están fabricados con tecnología picoPower (P) para trabajar consumiendo menos energía. En algunas sub-series se han corregido ciertos bugs encontrados en versiones anteriores del AVR. Esto no necesariamente significa que tengan ser mejor, pues todos los microcontroladores de todas las marcas suelen tener pequeños bugs que en la gran mayoría de aplicaciones se pasan por alto. Quizá el único momento en que nos percatemos de la sub-serie específica de nuestro mega AVR sea cuando lo identifique el software programador, leyendo su código de identificación. Por lo demás no debería preocuparnos la sub-serie del megaAVR. Los programas son compatibles tanto en código fuente como en código máquina. Así que para facilitar la lectura de aquí en adelante nos referiremos a estos megaAVR simplemente como ATmegaXX4 o ATmegaXX8, entendiendo que pueden tener o no el sufijo explicado. Existe mucha compatibilidad entre los microcontroladores de Atmel, por lo que la teoría expuesta es aplicable en gran parte a otras series de AVR como los tinyAVR, los megaAVR con USB o incluso a los AVR antiguos como los clásicos ATmega8535, ATmega8515, ATmega16, ATmega32, etc. A decir verdad, los AVR que estudiaremos son como las versiones mejoradas de los "clásicos" megaAVR citados anteriormente.
Características Comunes de los megaAVR Citaremos las características más notables de los ATmegaXX8 y ATmegaXX4. Quizá muchas de ellas no las comprendas de plano. Puedes tomar eso como referencia para medir tu avance en el dominio del AVR.
Tienen un repertorio de 131 instrucciones. Están optimizadas para generar un mejor código con los compiladores de alto nivel, en especial el C.
Poseen 32 Registros de Trabajo de 8 bits cada uno. Se denominan desde R0 a R31. Esto en realidad es aplicable a todas las familias de los AVR de bits, incluyendo los ATxmega.
Tienen una velocidad de ejecución de hasta 20 MIPS (20 Millones de Instrucciones Por Segundo), que se alcanzará cuando el reloj del sistema (XTAL) sea de 20 MHz. Aunque como en cualquier otro microcontrolador, en la práctica no será una velocidad sostenida, porque en el programa habrá instrucciones que se demoran 2 ó más ciclos de instrucción. Sin embargo, siguen siendo bastante rápidos si los comparamos por ejemplo con sus contrapartes de Microchip, los PIC18, los cuales tienen un límite de 10 o 12 MIPS.
Tienen un Timer0 de 8 bits que puede trabajar como Contador o Temporizador o Generador de hasta dos canales de ondas PWM de 8 bits de resolución.
MSc. Ing. Jacob Astocondor Villar
1
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Tienen un Timer1 de 16 bits que opera en modo Contador, Temporizador o como Generador de hasta dos canales de ondas PWM con resolución configurable de hasta 16 bits.
Los ATmega1284 tienen adicionalmente un Timer3 idéntico al Timer1.
Tienen un Timer2 de 8 bits, parecido al Timer0 pero equipado adicionalmente para operar con un XTAL externo de 32 kHz de modo asíncrono.
Tienen un Comparador Analógico.
Tienen un módulo TWI (Two Wire Interface) para comunicaciones con el protocolo I2C en modos Maestro y Esclavo.
Tienen un módulo SPI programable. Soporta los modos Maestro y Esclavo. Sirve además como la interface de programación serial del megaAVR.
Tienen un Conversor ADC de 10 bits, con hasta 8 canales de entrada.
Tienen un USART0: Puerto serie Transmisor Receptor Síncrono Asíncrono Universal.
Los ATmegaXX4 tienen adicionalmente un USART1, con características idénticas a las del USART0.
Operan con voltajes de alimentación entre 1.8V y 5.5V. Mienrtras más alta sea la frecuencia de operación del AVR más alto será el nivel de alimentación requerido, por ejemplo, para trabajar a la máxima frecuencia de 20 MHz, Vcc debe tener un valor muy estable entre 4.5V y 5V.
Tienen un Oscilador RC interno configurable como oscilador principal del sistema.
Tienen 6 modos Sleep, para una mejor administración del consumo de la energía.
Tienen un circuito BOD o detector de bajo voltaje de alimentación.
Tienen un temporizador Watchdog, para vigilar que el programa no quede colgado.
Los megaAVR de la serie ATmegaXX8 tienen 3 puertos de E/S (con 23 pines en total) y los megaAVR de la serie ATmegaXX4 tienen 4 puertos de E/S (con 32 pines en total).
Oscilador del sistema seleccionable, desde el Oscilador RC interno hasta cristales de cuarzo.
Tienen un modo de programación paralela de alto voltaje HVPP (a 12V) y un modo de programación serial en bajo voltaje SPI (a 5V). Los ATmegaXX4 pueden adicionalmente ser programados por su interface de depuración JTAG. Por otro lado, la interface debugWIRE de los ATmegaXX8 no ofrece la función de programación con la misma capacidad.
Tienen un sistema de depuración OCD con interface JTAG en el caso de los ATmegaXX4 y con interface debugWIRE en el caso de los ATmegaXX8. En general, la interface JTAG (compuesta por 4 pines) está disponible en todos los megaAVR de 40 pines o más y la interface debugWIRE (conformada por una sola línea) está presente en los megaAVR con menos de 40 pines.
Su memoria de programa FLASH tiene una sección de Boot Loader para albergar un programa cargador del mismo nombre. De los megaAVR estudiados en este curso (entre los ATmegaXX4 y ATmegaXX8) el único que no ofrece esta funcionalidad es el ATmega48. El programa de Boot Loader le permite al microcontrolador auto-programarse sin necesidad de usar un programador externo como el USBasp o AVR ISP MkII. Es así como trabajan los módulos Arduino, por ejemplo.
MSc. Ing. Jacob Astocondor Villar
2
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Empaques de los megaAVR
Diagrama de pines de los ATmegaXX8 en encapsulado PDIP.
Diagrama de pines de los ATmegaXX4 en encapsulado PDIP. Diagrama de bloques de los megaAVR El siguiente diagrama muestra los principales elementos de un AVR y que tarde o temprano los tendrás que memorizar.
Diagrama de bloques simplificado de los megaAVR ATmegaXX4 / ATmegaXX8 . Ahora una somera descripción de lo que representan estos bloques.
MSc. Ing. Jacob Astocondor Villar
3
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
El CPU es el circuito encargado de leer, decodificar y ejecutar las instrucciones del programa. Dispone de 32 registros de trabajo y un ALU (Unidad Aritmético Lógica) con el que realiza las operaciones de suma, resta, AND lógica, OR lógica, etc.
La Memoria FLASH, de Programa almacena las instrucciones del programa del AVR. Es una memoria permanente pero que se puede reprogramar para cambiar de tarea.
La Memoria RAM, de Datos aloja las variables que procesa el CPU.
El Contador de Programa es un registro que evoluciona para indicar cuál será la siguiente instrucción que debe ejecutar el CPU.
La Pila o Stack es un segmento de la memoria RAM para guardar el valor del Contador de Programa y también variables temporales del programa cuando sea necesario.
Los periféricos del AVR son elementos que se pueden usar para una determinada tarea; por ejemplo, el Timer0 sirve para temporizaciones. El USART para comunicaciones seriales RS232, etc. Casi todos ellos serán estudiados en un capítulo aparte.
Los puertos de E/S, PORTA,..., PORTD, son las líneas hacia/desde el exterior donde se pueden conectar los dispositivos a controlar, como diodos LED, transistores, LCDs, etc. Los megaAVR de 40 pines tienen los 4 puertos completos, mientras que a los megaAVR de 28 pines les falta PORTA y algunos pines en los otros puertos.
Hay más recursos presentes dentro de un AVR que también son imprescindibles pero cuyo trabajo queda en segundo plano. Algunos de ellos serán abordados en otro momento.
LA MEMORIA DE PROGRAMA Es de tipo FLASH. Aquí es donde se aloja el programa que el CPU ejecutará. Se puede modificar por completo mediante un dispositivo programador por hasta 10 000 veces. Pero tampoco deberíamos tanto. No conozco a nadie que haya llegado a ese límite con un solo microcontrolador. Lo más probable es que, por más cuidado que tengas, llegues a freír tu AVR antes de tiempo en algún accidente. Eso es algo muy “normal”. En los AVR las instrucciones de programa son de 16 ó de 32 bits. Pero siendo la gran mayoría de 16 bits, podemos decir que un AVR de N bytes de memoria FLASH puede almacenar hasta N/2 instrucciones de código ensamblador. Antiguamente parecía sencillo reconocer la cantidad de memoria FLASH que tenían algunos AVR. Por ejemplo, un ATmega32 tiene 32 k-bytes, un ATmega8L tiene 8 k-bytes. Los megaAVR de ahora todavía conservan esa correspondencia entre el número que aparece en su nombre y la cantidad de k-bytes de FLASH, solo que las nuevas series también llevan un número que puede entrar a confundir un poco. En la siguiente tabla apreciamos los AVR de las series ATmegaXX8, ATmegaXX4, ATmegaXX5 y ATmegaXX50. Las XX representan la cantidad de FLASH de megaAVR. Al final de cada nombre aparece el sufijo yy representando a las letras P, V, A o PA. Personalmente, creo que al haber varias series, es más fácil separar primero los números que representan la capacidad de FLASH porque deben ser números redondos (digitalmente hablando), es decir, deben ser potencias de 2, como 4, 8, 16, 32, 64 ó 128. Por ejemplo, ¿cuánta memoria FLASH tendrá un ATmega3290P?, ¿3290 kbytes, 329 kbytes, 32 kbytes o 3 kbytes? Como el único número redondo es 32, la respuesta es 32 kbytes y deducimos que este megaAVR es de la serie 90P. Se llega más rápido a la respuesta si leemos las opciones empezando por la izquierda.
MSc. Ing. Jacob Astocondor Villar
4
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Tabla AVR Memoria FLASH
AVR
Memoria RAM
Memoria EEPROM
Pines de E/S
ATmega48yy 4 K
512
256
23
ATmega88yy 8 K
1K
512
23
ATmega168y 16 K y
1K
512
23
ATmega328y 32 K y
2K
1K
23
-
-
-
-
-
ATmega164yy
16 K
1K
512
32
ATmega324yy
32 K
2K
1K
32
ATmega644yy
64 K
4K
2K
32
ATmega1284yy
128 K
16 K
4K
32
-
-
-
-
-
ATmega165yy
16 K
1K
512
54/69
ATmega325yy
32 K
2K
1K
54/69
ATmega3250yy
32 K
2K
1K
54/69
ATmega645yy
64 K
4K
2K
54/69
ATmega6450yy
64 K
4K
2K
54/69
Secciones de Aplicación y de Boot Loader Los AVR ofrecen la posibilidad de escribir en su memoria de programa FLASH incluso en tiempo de ejecución. Esta función puede ser aprovechada para almacenar datos procesados por el usuario o para permitir la auto-programación del AVR. Para facilitar y robustecer el proceso de auto-programación los AVR dividen su memoria FLASH en dos segmentos lógicos, de Aplicación y de Boot loader. La Sección de Aplicación está destinada a almacenar el programa que el AVR ejecuta habitualmente, como leer sensores, controlar motores, etc. La Sección de Boot loader está diseñada para almacenar el código del Boot loader, que es un pequeño programa para cargar el programa del AVR en la Sección de Aplicación, así como Windows carga en la RAM de la PC el programa que vamos a utilizar. Un Boot loader no es precisamente un mini S.O. porque ya hay S.O. para microcontroladores conocidos como RTOS (Real Time Operating System). Además, a diferencia de un SO para PC, un Boot loader debe ser el programa más pequeño posible y se debe ubicar al final de la memoria FLASH. No todos los megaAVR tienen Sección de Boot Loader, como el ATmega48.
MSc. Ing. Jacob Astocondor Villar
5
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Secciones de Aplicación y de Boot Loader de la memoria de programa del AVR. La Sección de Boot loader siempre se ubica al final de la memoria FLAH pero su tamaño varía de acuerdo con el AVR y con la configuración establecida por los fuses BOOTSZ1 y BOOTSZ0. Por ejemplo, el ATmega644PA puede tener una Sección de Boot loader entre 512 palabras y 4096 palabras, según la siguiente tabla. Tabla BOOTSZ1 BOOTSZ1 BOOTSZ0 Tamaño del Boot Loader
Dirección del Boot Loader
1
1
512 palabras
0x7E00 - 0x7FFF
1
0
1024 palabras
0x7C00 - 0x7FFF
0
1
2048 palabras
0x7800 - 0x7FFF
0
0
1096 palabras
0x7000 - 0x7FFF
Los fuses BOOTSZ1 y BOOTSZ0 solo se pueden modificar al grabar el AVR. Su configuración por defecto siempre establece el tamaño mayor elegible de la Sección de Boot loader. El hecho de que la Sección de Boot Loader esté diseñada para alojar el programa cargador no significa que esté limitada a esa tarea. Si no la vamos a usar para su propósito primigenio, podemos emplearla como si fuera parte de la Sección de Aplicación, o sea, como si no existiera la división entre estas dos Secciones y por ende no tendrá importancia el valor que pongamos en los fuses BOOTSZ1 y BOOTSZ0.
MSc. Ing. Jacob Astocondor Villar
6
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Configuración de los Fuses de Boot loader en el programa grabador. A propósito, la configuración de los fuses BOOTSZ1 y BOOTSZ0 en Proteus no tiene ningún efecto porque Proteus aún no soporta simulaciones con Boot Loader. Así que están como decorativos.
Configuración de los Fuses de Boot loader en Proteus.
MSc. Ing. Jacob Astocondor Villar
7
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
La Memoria de Datos SRAM Actualmente suena redundante especificar memoria SRAM (Static RAM) porque casi todas las RAM de los microcontroladores son estáticas. Decimos simplemente RAM, a la memoria cuya función “tradicional” es alojar temporalmente los datos que se procesan en el programa. La cantidad de RAM disponible internamente depende del modelo de AVR y, a diferencia de la memoria FLASH, no tiene una directa correspondencia con el nombre del dispositivo. Aun así, podemos observar en la siguiente tabla que en muchos modelos existe una relación que se repite (los ATmega128nn rompen la relación, y pueden no ser los únicos). Los megaAVR con 4K de FLASH tienen 512 bytes de RAM, los megaAVR con 8 K y 16 K de FLASH tienen 1 K de RAM, y así, tal como se ve en la tabla.
AVR
Memoria FLASH
Tabla AVR Memoria RAM
ATmegaNNN
4K
512
ATmegaNNN
8K
1K
ATmegaNNN
16 K
1K
ATmegaNNN
32 K
2K
ATmegaNNN
64 K
4K
ATmegaNNN
128 K
4K, 8K o 16K
Algunos Modelos ATmega48A, ATmega48PA, ATmega48P/V, ATmega48/V ATmega88A, ATmega88PA, ATmega88P/V, ATmega88/V ATmega168A, ATmega168PA, ATmega168P/V, ATmega168/V ATmega164A, ATmega164PA ATmega165A, ATmega165PA ATmega169, ATmega169P ATmega328, ATmega328P ATmega324A, ATmega324PA ATmega325A, ATmega325PA ATmega3250A, ATmega3250PA ATmega329P, ATmega3290P ATmega644A, ATmega644PA ATmega645A, ATmega645P ATmega6450A, ATmega6450P ATmega128, ATmega1281 ATmega1284, ATmega1284P
En los modelos listados y en general en todos los megaAVR de las series más recientes el espacio de la memoria RAM (entendida en su concepto tradicional) empieza en la dirección 0x0100 y termina en 0x02FF, 0x04FF, 0x08FF, 0x10FF, 0x20FF o 0x40FF, según el modelo. La verdad, no importa mucho saber dónde termina como la cantidad misma. La dirección de inicio sí es de consideración pero cuando se programa en lenguaje ensamblador. Quizá alguien pudiera preguntar por qué la dirección de inicio no es 0x0000, como en otros microcontroladores. Porque las primeras direcciones, desde 0x0000 hasta 0x00FF, están reservadas para acceder a los Registros de Trabajo y a los Registros de E/S del AVR en ‘modo de memoria’. Normalmente los 32 Registros de Trabajo se acceden directamente con instrucciones como LDI o MOV. Pero también se les puede acceder direccionándolos como si fueran parte de la memoria RAM, con instrucciones como LD o ST y con las direcciones presentadas. En ocasiones esto facilitará mover bloques de datos entre la RAM y los registros de trabajo aprovechando la potencia de los punteros.
Del mismo modo, los Registros de E/S, que tampoco ocupan posiciones reales en la RAM, pueden ser accedidos como si en verdad fueran RAM con las instrucciones como LD y ST, para lo cual emplean las direcciones mostradas en la figura. Los Registros de E/S y los Registros de E/S extendidos son hermanos, por decirlo de algún modo, y tienen funciones análogas. Están separados solo por tener diferente modo de acceso, pero eso se explicará mejor en su sección respectiva.
MSc. Ing. Jacob Astocondor Villar
8
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
El direccionamiento y distinción de los espacios de la RAM solo son de preocupación al trabajar en ensamblador. Al programar en lenguajes de alto nivel los compiladores se encargan de toda la administración de la RAM, salvo que reciban directivas avanzadas.
Espacio de la Memoria RAM del megaAVR. EL CONTADOR DE PROGRAMA, PC El PC es un registro que indica la siguiente instrucción que debe ejecutar el CPU. Si vale 0x0000, ejecutará la primera instrucción de la memoria; si vale 0x0002 ejecutará la tercera instrucción, y así... Al arrancar microcontrolador, el PC vale 0x0000 y se va incrementando automáticamente, con lo que el AVR debería ejecutar una a una desde la primera hasta la última instrucción del programa. En realidad, en el código habrá instrucciones que modifiquen el valor del PC de modo que el programa nunca termine.
La Pila y el Puntero de Pila La Pila o STACK es una memoria que almacena temporalmente el valor del PC (Program Counter) cuando el programa llama a una subrutina o cuando salta a un Vector de Interrupción. También sirve para guardar datos temporalmente cuando los 32 Registros de Trabajo no sean suficientes. Al igual que en una PC, la Pila forma parte de RAM Interna. No es un pedazo de RAM con características especiales, es una simple área cuya dirección de inicio la puede establecer el usuario y cuyo tamaño es indefinido porque crece y decrece en tiempo de ejecución. Las que sí son especiales son las instrucciones que trabajan con la Pila, como PUSH y POP. Estas instrucciones no necesitan conocer la locación en la Pila a/de donde guardarán/recuperarán los datos. Aprovechan, en cambio, su acceso de tipo LIFO (Last In First Out), que significa “el último dato en entrar será el primero en Salir”. Es por eso que siempre se recurre a la analogía con una pila de platos de donde no podemos tomar un plato que se encuentra en el fondo o en la mitad. Para llegar a él primero tendríamos que quitar los platos que están encima. Pero hasta ahí llega la analogía porque a diferencia de las pilas de platos, las pilas en RAM crecen de arriba abajo, es decir, cada dato que se va depositando en la Pila ocupa una dirección inferior a la anterior.
MSc. Ing. Jacob Astocondor Villar
9
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Esta dirección la va marcando el Puntero de Pila, el cual se decrementa cada vez que se coloca un dato en la Pila y se incrementa cada vez que se toma un dato de ella. La Pila trabaja de cabeza para evitar que sus datos colisionen (se solapen) con las variables accedidas aleatoriamente, las cuales se van mapeando en la RAM normalmente de abajo arriba. Registro SPH SPH
SP15
SP14
SP13
SP12
SP11
SP10
SP9
SP8
Registro SPL SPL
SP7
SP6
SP5
SP4
SP3
SP2
SP1
SP0
El Puntero de Pila está representado por los registros de E/S SPH y SPL, que concatenados actúan como un registro de 16 bits. Como se dijo anteriormente, este registro tiene un comportamiento de autoincremento y auto-decremento. La única intervención por parte del usuario debería ser su inicialización, esto es, cargarle la última dirección de la RAM. Pero esta operación solo es indispensable al programar en ensamblador. Los compiladores como el C inicializan la Pila automáticamente. Sin embargo, incluso en C es importante conocer estos conceptos para entender por ejemplo por qué un programa para un ATmega328P nunca funcionará en un ATmega168P, incluso si el tamaño del código es pequeño y le puede caber sobradamente.
Los Registros de Trabajo y los Punteros X, Y y Z Todos los AVR de 8 bits, desde los tinyAVR hasta los ATxmega cuentan con 32 Registros de Trabajo nombrados desde R0 hasta R31. Los Registros de Trabajo tienen la función de alojar los datos más inmediatos que el CPU procesa. ¿Acaso ésa no era tarea de la RAM?. Bueno, sucede que en todos los microcontroladores inspirados en la arquitectura de los procesadores de Intel (como los AVR, ARM y Freescale entre otros) el acceso a la memoria RAM toma más ciclos que el acceso a los Registros de Trabajo. En los AVR de 8 bits, por ejemplo, se puede acceder a los Registros de Trabajo en un solo ciclo, puesto que todos están directamente conectados al CPU, o mejor dicho, son parte del CPU. En cambio, la mayoría de las instrucciones ensamblador que acceden a la RAM consumen 2 ciclos de instrucción. No es posible cargar datos en la RAM directamente ni moverlos entre locaciones diferentes de la RAM (a menos que tengan DMA, como los AVR32). Para esas operaciones los Registros de Trabajo actúan como intermediarios. Pero quizá la participación más notable de Los Registros de Trabajo sea en el ALU (Unidad Aritmético Lógica) para computar las operaciones aritméticas y lógicas. Por ejemplo imaginemos que deseamos obtener la raíz cuadrada de un número de punto flotante ubicado en la RAM y almacenar el resultado de nuevo en la RAM. En lenguaje C bastaría con escribir una sola sentencia, pero el código máquina generado involucra una tarea más compleja: al inicio el CPU mueve los 4 bytes del número desde la RAM a los Registros de Trabajo, luego viene el trabajo pesado, que implica el procesamiento de varios datos intermedios. En lo posible todos estos datos también estarán en los registros de trabajo para aprovechar su velocidad y eficacia. Solo al terminar el cómputo el CPU depositará el resultado en la RAM.
MSc. Ing. Jacob Astocondor Villar
10
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Los compiladores de alto nivel también suelen emplear los Registros de Trabajo para pasar los argumentos de sus funciones. Creo que con esos ejemplos debe quedar clara la razón de ser de los Registros de Trabajo. En la siguiente figura podemos notar que los Registros de Trabajo se parten por la mitad. La diferencia está en que los primeros 16 registros (R0 a R15) no admiten la instrucción LDI, que sirve para cargar constantes al registro (otro aspecto primordial de la programación en ensamblador9. Los registros R26 a R31 tienen la capacidad adicional de funcionar como punteros de 16 bits cada uno.
LOS REGISTROS DE TRABAJO DE LOS AVR. El par de registros R27-R26 forma el Puntero X, el par R29-R28 forma el Puntero Y, y el par R31-R30 forma el Puntero Z. Los punteros pueden apuntar a (contener la dirección de) cualquier locación del espacio de RAM. Esto junto con las instrucciones adecuadas conforman el direccionamiento indirecto más potente, muy útil por ejemplo para mover grandes bloques de datos.
Terminamos esta sección explicando las direcciones que figuran en el mapa de los Registros de Trabajo. En principio a los Registros de Trabajo no les debería hacer falta tener direcciones porque están directamente unidos al CPU. Hay instrucciones adecuadas como LDI y MOV para acceder a ellos. Sin embargo, los AVR les brindan direcciones para adicionalmente poder ser accedidos como si fueran parte de la RAM, es decir, con instrucciones que están diseñadas para la RAM, como LD y ST. De esta manera
MSc. Ing. Jacob Astocondor Villar
11
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
se hacen más flexibles las operaciones de transferencias de datos entre los diferentes espacios de memoria. Cuando manipulamos los Registros de Trabajo utilizando sus direcciones podemos decir que los estamos accediendo “en modo RAM”, pero sin perder de vista que los Registros de Trabajo no pertenecen a la RAM porque no están implementadas físicamente allí.
Los Registros de E/S Anteriormente se dijo que para programar el AVR primero había que conocer sus recursos. Pues bien, todos ellos se pueden controlar mediante los Registros de E/S. por ejemplo, si queremos manejar el puerto B, debemos conocer los registros PORTB, DDRB y PINB. Si queremos programar el USART0, debemos conocer los registros UDR0, UCSR0A, UCSR0B, UCSR0C, UBRR0L y UBRR0H. Si queremos… En tiempo de ejecución los registros de E/S (Entrada Salida) lo controlan todo, no solo las operaciones de los módulos periféricos, como se podría inferir a partir de la denominación E/S, sino que también controlan la performance del mismo CPU. En este caso los registros a conocer serían MCUCR, MCUSR o SMCR. Entenderás que no tiene caso seguir mencionando las funciones de otros Registros de E/S. es por eso que cada módulo se trata por separado estudiando con detenimiento cada registro y cada uno de los bits que lo componen. Espero que los mapas de memoria de los Registros de E/S que presento no te hagan pensar que están divididos en una suerte de bancos, como en los PICmicro. No, señor, nada de eso. Todos los espacios de memoria en los AVR son lineales. Yo los quise subdividir para una mejor presentación.
MSc. Ing. Jacob Astocondor Villar
12
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Cada registro es de 8 bits y en total se cuentan 224 registros de E/S, aunque ni siquiera la mitad están implementados físicamente. Las locaciones que aparecen sin nombre están RESERVADAS y no nunca deberían ser accedidas. De modo similar, hay registros con algunos bits sin nombre ni funcionalidad que también se consideran reservados. Un ejemplo es el registro SMCR, mostrado abajo. No está prohibido acceder a dichos bits pero se recomienda dejarlos en 0 por compatibilidad con futuros AVR. Estas aclaraciones aparecen por doquier en los datasheets. Yo prefiero decirlas ahora para no tener que estar repitiéndolo a cada rato después. Registro SMCR ---
---
---
MSc. Ing. Jacob Astocondor Villar
---
SM2
SM1
SM0
SE
13
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Los antiguos microcontroladores AVR solo tenían el espacio de los 64 primeros Registros de E/S. A ellos les alcanzaba ese espacio aunque a veces a duras penas porque todos los registros estaban allí apretujados. Los Registros de E/S tenían sus propias instrucciones de acceso, IN y OUT, que de hecho todavía se usan. Las instrucciones de ensamblador IN y OUT utilizan el rango de direcciones 0x00 a 0x3F para acceder a los Registros de E/S. En el esquema mostrado estas direcciones aparecen fuera de los paréntesis. Con la aparición de nuevos periféricos en los AVR, aumentaron los registros de E/S y se sobrepasaba el alcance de las instrucciones IN y OUT. Así fue necesario diseñar los Registros de E/S para que también pudieran ser direccionados como si fueran parte de la RAM, o sea, con instrucciones como LD o ST, las cuales tienen mayor cobertura y permiten repotenciar las transferencias de datos. Para este tipo de acceso, llamado “en modo RAM”, las instrucciones como LD o ST utilizan el rango de direcciones 0x20 a 0xFF, que en los mapas de memoria aparecen dentro de los paréntesis. A juzgar por sus direcciones, ya podrás deducir que la única diferencia entre los Registros de E/S (estándar) y los Registros de E/S Extendidos es que estos últimos se acceden exclusivamente en “modo de memoria” con instrucciones como LD y ST, y los primeros todavía admiten el uso de las instrucciones clásicas como IN y OUT. El direccionamiento y distinción de los Registros de E/S estándar o extendidos son de especial preocupación al trabajar en ensamblador. Al programar en lenguajes de alto nivel los compiladores son quienes escogen el modo de acceso y las instrucciones que consideren más convenientes, salvo que reciban directivas contrarias.
Registros Generales del Micro controlador Estos son registros de E/S que no están relacionados con una parte exclusiva del microcontrolador. Por tanto los volveremos a ver al mencionar en otros capítulos, aunque sea para referirnos a uno solo de sus bits. El Registro de Estado SREG Todo microprocesador tiene un registro para reflejar el estado de las operaciones lógicas y aritméticas del módulo ALU. SREG también incluye dos bits con funciones disímiles. El registro SREG es bastante utilizado en los programas en ensamblador. Cuando se trabaja con compiladores de alto nivel su presencia solo sería justificable por el uso del bit I. Registro SREG
I
T
H
S
V
N
Z
C
Registro de Microcontrolador Global Interrupt Enable 1. Habilitar las interrupciones individuales habilitadas. Las interrupciones individuales serán habilitadas en otros registros de control.
I
0. No se habilita ninguna de las interrupciones sin importar sin importar sus configuraciones individuales. El bit I se limpia por hardware después de ocurrir una interrupción, y se setea por la instrucción para habilitar posteriores interrupciones. El bit I también se puede setear o limpiar por la aplicación con las instrucciones SEI y CLI.
T
Bit Copy Storage
MSc. Ing. Jacob Astocondor Villar
14
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Las instrucciones para copiar bits (Bit LoaD) y BST (Bit STore) usan el bit T como inicio o destino para el bit de la operación. Con la instrucción BST se puede copiar un bit de un registro de trabajo al bit T y con la instrucción BLD se puede copiar el bit T a un bit de un registro de trabajo. Half Carry Flag
H
El flag H indica un medio acarreo en algunas operaciones aritméticas. El bit H es muy útil en aritmética BCD. Sign Bit, S = N ? V
S El bit S es siempre un or exclusivo entre los flags N y V. Leer abajo. Two’s Complement Overflow Flag
V El flag V soporta aritmética de complemento a dos. Negative Flag
N El flag N indica un resultado negativo en una operación lógica o aritmética. Zero Flag
Z El flag Z indica un resultado cero en una operación lógica o aritmética. Carry Flag
C El flag C indica un acarreo en una operación lógica o aritmética.
El Registro MCUCR MCUCR = MCU Control Register. MCU a su vez significa Micro Controller Unit. Aunque probablemente de este registro solo vayamos a usar el bit PUD, es bueno conocerlo ahora aprovechando que hace referencia a muchas de las características del microcontrolador que se estudiaron en este capítulo. Ampliaremos la funcionalidad del bit PUD en el capítulo de entrada y salida generales y los bits IVSEL junto con IVCE serán mejor expuestos en el capítulo de interrupciones.
Registro MCUCR JTD
BODS
BODSE
PUD
---
---
IVSEL
IVCE
Registro de Microcontrolador JTD
JTAG Interface Disable
MSc. Ing. Jacob Astocondor Villar
15
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
0. La interface JTAG estará habilitada si está programado el fuse JTAGEN. 1. la interface JTAG está deshabilitada. Para evitar deshabilitaciones no intencionadas de la interface JTAG, se debe seguir una secuencia especial para cambiar este bit: el software de aplicación debe escribir este bit dos veces el valor deseado dentro de cuatro ciclos de reloj. Este bit no se debe alterar cuando se esté usando el sistema OCD (On Chip Debug) BOD Sleep Sirve para deshabilitar el circuito del BOD durante el modo Sleep, si estaba activo. Recuerda que se activa por los fuses BODLEVEL2-0. BODS
Para poner 1 en el bit BODS se requiere seguir una secuencia especial que involucra el bit BODSE. Primero se escribe 1 en los bits BODS y BODSE. Luego se debe escribir 1 en el bit BODS y 0 en el bit BODSE dentro de los siguientes cuatro ciclos de reloj. El bit BODS estará activo durante tres ciclos de reloj después de haberse seteado. Para apagar el circuito BOD para el modo Sleep actual se debe ejecutar la instrucción Sleep mientras el bit BODS esté activo. El bit BODS se limpia automáticamente después de tres ciclos de reloj. BOD Sleep Enable
BODSE El bit BODSE habilita la configuración del bit de control BODS, como se explicó en la descripción del bit BODS. Pull-up Disable PUD
1. Se deshabilitan las pull-up de todos los pines de los puertos, sin importar el valor de los registros DDRx y PORTx. 0. Las pull-up se habilitaran por los registros DDRx y PORTx. Interrupt Vector Select 0. Los Vectores de Interrupción se ubican en el inicio de la memoria FLASH. 1. Los Vectores de Interrupción se mueven al inicio de la Sección de Boot Loader de la memoria FLASH. Para evitar cambios no intencionados en este bit se debe seguir una secuencia especial: a. Escribir 1 en el bit IVCE.
IVSEL b. Dentro de los cuatro ciclos de reloj siguiente, escribir el valor deseado en el bit IVSEL mientras se escribe un 0 en el bit IVCE. Las interrupciones se deshabilitarán automáticamente durante la ejecución de esta secuencia. Las interrupciones se deshabilitan en el ciclo en que se setea el bit IVCE y permanecen deshabilitadas hasta después de la instrucción que escribe el bit IVSEL. Si no se escribe el bit IVSEL, las interrupciones permanecen deshabilitadas por cuatro ciclos de reloj. El bit I en el registro de estado SREG no se afecta por la deshabilitación automática. Nota: si los Vectores de Interrupción están colocados en la Sección de Boot Loader, y el bit de candado BLB02 está programado, las interrupciones se deshabilitan durante la ejecución del programa desde la Sección de Boot Loader. Interrupt Vector Change Enable IVCE
Se debe escribir 1 en el bit IVCE para habilitar el cambio del bit IVSEL. El bit IVCE se limpia por hardware cuatro ciclos después de que se haya escrito o cuando se escribe el bit IVSEL. Setear el bit IVCE deshabilitará las interrupciones, como se explicó en la descripción del bit IVSEL.
MSc. Ing. Jacob Astocondor Villar
16
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
EL REGISTRO MCUSR MCUSR = MCU Status Register. Es el registro de estado del microcontrolador, MCU. MCUSR está conformado por bits de Flag que sirven para identificar la causa del reset del microcontrolador. Para averiguar la fuente de reset el programa debe leer el registro MCUSR tan pronto como sea posible y luego limpiar sus Flags. Observa que a diferencia de los Flags de las Interrupciones, los Flags de MCUSR se limpian escribiendo un cero y no un uno. Registro MCUSR
---
---
---
JTRF
WDRF
BORF
EXTRF
PORF
Registro de Microcontrolador JTAG Reset Flag
JTRF
Este bit se pone a uno si se produce un reset por un uno lógico en el Registro JTAG Reset seleccionado por la instrucción de JTAG AVR_RESET. Este bit se pone a cero por un Reset POR, o escribiendo un cero lógico en el flag. Watchdog Reset Flag
WDRF
Este bit se pone a uno cuando se produce un Reset por el Watchdog. Este bit se pone a cero por un reset Power-on o escribiendo un cero lógico en el flag. Brown-out Reset Flag
BORF
Este bit se pone a uno cuando se produce un Reset Brown-out. Este bit se pone a cero por un reset Poweron o escribiendo un cero lógico en el flag. External Reset Flag
EXTRF
Este bit se pone a uno cuando se produce un Reset Externo. Este bit se pone a cero por un reset Power-on o escribiendo un cero lógico en el flag. Power-on Reset Flag
PORF
Este bit se pone a uno cuando se produce un Reset Power-on. Este bit se pone a cero escribiendo un cero lógico en el flag.
Los Fuses de los AVR Los fuses del microcontrolador establecen una característica importante en su operación, tanto que solo se puede modificar en el momento de programarlo. Por ejemplo, no se podría escoger el tipo de oscilador a usar después de haber iniciado el programa. Sería como cambiarle los neumáticos a un automóvil en marcha. Cada aplicación puede requerir una configuración particular y si no se establecen los fuses correctos, el programa puede funcionar mal, suponiendo que funcione. :)
MSc. Ing. Jacob Astocondor Villar
17
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
A diferencia de los PICmicro, en los AVR los fuses no pueden formar parte del código HEX, así que siempre será necesario configurarlos directamente en el entorno del programa grabador de AVR. Los fuses sí pueden incluirse en los archivos de depuración como ELF, para simulaciones o depuraciones. Por otra parte, y esto es para bien, hay muy poca variación en los fuses de los AVR, inclusive de distintas series. Por eso serán de fácil recordación, en contraste con los fuses de los PICmicro, donde son casi inmemorizables. La comparación es siempre con los PIC18, por supuesto, porque los PIC16 en general no están a la altura. Los fuses están contenidos en los denominados Bytes de Fuses, que son registros (de 8 bits obviamente) implementados en EEPROM (no en la EEPROM de datos de AVR). Por eso un 1 es el valor por defecto cuando un bit no está programado. Los megaAVR más recientes tienen 3 Bytes de Fuses llamados Byte de Fuses Bajo, Alto y Extendido. El Byte de Fuses Bajo es el mismo en todos ellos. Los otros empiezan a cambiar un poco, en orden más que en funciones, según cada modelo en particular. Mientras más reciente sea la serie, se encontrarán menos divergencias. El conjunto de Bytes de Fuses mostrado a continuación pertenece a los AVR de la serie ATmegaXX4. En otras series pueden aparecer, desaparecer o cambiar algunos fuses, por ejemplo los AVR de la serie ATmegaXX5 tienen adicionalmente el fuse RSTDISBL. En lo sucesivo se describirán las funciones de los fuses más conocidos, no solo los presentados aquí. Tabla Byte de Fuses Bajo Descripción Valor por Defecto 7 Divide clock by 8 0 (programado) 6 Clock output 1 (sin programar) 5 Select start-up time 1 (sin programar) 4 Select start-up time 0 (programado) 3 Select Clock source 0 (programado) 2 Select Clock source 0 (programado) 1 Select Clock source 1 (sin programar) 0 Select Clock source 0 (programado) Tabla Byte de Fuses Alto Byte de Fuses Alto Bit Descripción Valor por Defecto OCDEN 7 Enable OCD 1 (sin programar) JTAGEN 6 Enable JTAG 0 (programado) SPIEN 5 Enable Serial Programming 0 (programado) WDTON 4 Watchdog Timer always on 1 (sin programar) EESAVE 3 EEPROM memory is preserved 1 (sin programar) BOOTSZ1 2 Select Boot Size 0 (programado) BOOTSZ0 1 Select Boot Size 0 (programado) BOOTRST 0 Select Reset Vector 1 (sin programar) Tabla Byte de Fuses Extendido Byte de Fuses Extendido Bit Descripción Valor por Defecto – 7 – 1 – 6 – 1 – 5 – 1 – 4 – 1 – 3 – 1 BODLEVEL2 2 Brown-out Detector trigger level 1 (sin programar) BODLEVEL1 1 Brown-out Detector trigger level 1 (sin programar) BODLEVEL0 0 Brown-out Detector trigger level 1 (sin programar) Byte de Fuses Bajo CKDIV8 CKOUT SUT1 SUT0 CKSEL3 CKSEL2 CKSEL1 CKSEL0
Bit
Pongo en relieve estos detalles porque hay muchos programadores, como el famoso WinPic800, en los que los fuses se configuran bit a bit, como se ve abajo. ¿Cómo harías si tuvieras que configurar el uso de MSc. Ing. Jacob Astocondor Villar
18
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
un oscilador de XTAL de 16 MHz en un ATmega3250P? Primero tendrías que conocer los fuses correspondientes, ¿cierto? En este caso son CKSEL0, CKSEL1, CKSEL2 y CKSEL3. Luego tendrías que descubrir cuál es la combinación correcta para un XTAL de 16MHz. No te preocupes, todo esto lo estudiaremos ampliamente.
Configuración de los fuses en WinPic800. WinPic800 es bueno pero sus engreídos son los PICmicro y a los AVR no les da tanta consideración como a ellos (debe ser por su nombre ;). También existen programadores con software de mejor interface como el AVRprog2 con su software AVRFLASH, cuyo entorno se muestra en abajo. A propósito, la toma indica que hay opciones para usar un XTAL mayor de 8MHz. Podrías elegir cualquiera, a menos que sepas lo que significan arranque rápido o lento, y estés seguro de que necesitas uno de ellos. Bueno, mejor vamos a la descripción de los fuses de una vez.
Configuración de los fuses en AVRFLASH.
CKSEL3-0. SELECCIÓN DEL RELOJ MSc. Ing. Jacob Astocondor Villar
19
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Este fuse se representa por los bits CKSEL3, CKSEL2, CKSEL1 y CKSEL0. Sirve para adaptar el circuito interno del oscilador según el componente externo o interno que se usará como fuente del reloj del sistema.
Reloj Externo. En este caso la fuente de reloj será una señal de onda cuadrada externa aplicada al pin XTAL1 del AVR. Su frecuencia podrá estar en todo el rango posible, desde 0 hasta 20 MHz.
Se establece con los bits CKSEL3-0 = 0000, respectivamente.
Oscilador RC Interno Calibrado. Con esta opción no se necesitarán añadir componentes externos. El reloj será el oscilador RC Interno, el cual tiene una frecuencia cercana a 8MHz, y adicionalmente ofrece al diseñador la posibilidad de ajustar por software dicha calibración hasta en 1%. Es útil para sistemas de bajo costo aunque de menor nivel de estabilidad. Es la opción por defecto.
Se establece poniendo los bits CKSEL3-0 = 0010, respectivamente.
XTAL Externo de Baja Frecuencia. Para utilizar un XTAL externo de 32.768 kHz con capacitores de estabilización opcionales. Es una configuración diseñada para aplicaciones de reloj.
En los ATmegaXX8 y ATmegaXX4 se establece poniendo los bits CKSEL3-0 = 0100 o 0101. En otros megaAVR puede variar.
Oscilador RC Interno de 128kHz. Este oscilador es parecido al RC de 8MHz, solo que ofrece menor precisión y no se puede calibrar.
En los ATmegaXX8 y ATmegaXX4 se establece con los bits CKSEL3-0 iguales a 0011. En otros megaAVR puede no estar disponible.
XTAL Externo de Baja Potencia. Esta configuración soporta cristales de 0.9 MHz hasta 16 MHz. Estos cristales ahorran energía pero su uso es recomendado solo en ambientes libres de ruido. El XTAL se coloca entre los pines XTAL1 y XTAL2 del AVR y debe usar capacitores externos de entre 12pf y 22pf, similar al circuito con XTAL estándar de alta frecuencia.
En los ATmegaXX8 y ATmegaXX4 los valores de los bits CKSEL3-0 dependerán del rango de frecuencia del XTAL, según la siguiente tabla.. Tabla Rango del XTAL en MHz Rango del XTAL en MHz
CKSEL3-0
0.9 - 3.0
1011 o 1010
3.0 - 8.0
1101 o 1100
8.0 - 16.0
1111 o 1110
XTAL Externo Estándar. Con esta configuración el XTAL usado estará entre 0.4 MHz y 20 MHz (el máximo admisible). El XTAL se coloca entre los pines XTAL1 y XTAL2 del AVR y debe tener capacitores externos de entre 12pF y 22pF.
En los ATmegaXX8 y ATmegaXX4 se establece con los bits CKSEL3-0 = 0111 o 0110, dependiendo de la frecuencia del cristal usado, segun la siguiente tabla..
MSc. Ing. Jacob Astocondor Villar
20
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Tabla Rango del XTAL en MHz Rango del XTAL en MHz
CKSEL3-0
0.4 - 16
0111 o 0110
0.4 - 20
0111
Observa que con los 4 bits CKSEL3-0 es posible formar hasta 16 combinaciones. Entre las no citadas, algunas están reservadas y no deberían usarse, y otras corresponden a configuraciones relacionadas con el uso de un Resonador Cerámico en lugar del XTAL externo estándar o de baja potencia. Excluí las combinaciones del resonador cerámico para evitar una sobrecarga de números innecesaria. En la mayoría de las prácticas de cursomicros.com se usa un XTAL de 8 MHz. Puede ser estándar o de baja potencia. El XTAL de cuarzo brinda el reloj más preciso y estable, lo que es ideal para aplicaciones que usan los módulos síncronos como el USART o TWI (I2C). Debemos recordar que un 0 es un bit programado y un 1 es un bit sin programar. En los entornos de los programadores 0 suele ser una casilla marcada. Por ejemplo, en WinPic800 la combinación CKSEL3-0 = 0111 se vería así.
SUT1-0. Retardos de Reset y de Arranque Se representa por los bits SUT1 y SUT0. En realidad se trata de dos temporizadores. El Retardo de Reset funciona con el circuito RC del Watchdog y se encarga de mantener el AVR en estado de reset por 4.1 ms o 65 ms después de un RESET, por ejemplo, después de conectar la alimentación Vcc del AVR. Esto serviría para que se estabilice el nivel de Vcc antes de que el AVR empiece a trabajar. Se representa por .
MSc. Ing. Jacob Astocondor Villar
21
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Pero ahí no termina. Para asegurarse de que el oscilador del sistema también se haya estabilizado, habrá un Retardo de Arranque hasta que transcurran 1K o 16K ciclos de reloj CK. Durante ese lapso el AVR también se mantiene en estado de reset y luego recién el procesador empezará a ejecutar el programa. El Retardo de Arranque no solo se activa después de un reset sino también después de que el AVR salga de los estados Power-save o Power-down, que son dos de los seis modos SLEEP que tienen los megaAVR. La configuraciones de los retardos de reset y de arranque varían de acuerdo con la fuente de reloj del sistema. La siguiente tabla muestra solo las opciones admisibles para un XTAL estándar o de baja potencia. Tabla CKSEL0
CKSE SUT1 Retardo de SUT0 reset L0
Retardo de arranque
Fuente de Oscilador, Condiciones de alimentación
0
10
14CK
1K CK
XTAL baja frecuencia, BOD enabled
0
11
4.1ms + 14CK
1K CK
XTAL baja frecuencia, fast rising power
1
00
65ms + 14CK
1K CK
XTAL baja frecuencia, slowly rising power
1
01
14CK
16K CK
XTAL, BOD enabled
1
10
4.1ms + 14CK
16K CK
XTAL, fast rising power
1
11
65ms + 14CK
16K CK
XTAL, slowly rising power
En esta tabla XTAL baja frecuencia no se refiere al XTAL de reloj de 32.768 kHz, sino a un XTAL estándar o de baja potencia cuya frecuencia no esté cercana a la máxima admisible por el AVR, que para los ATmega 8xx o 4xx es de 20MHz. Esta condición concuerda con el valor del bit CKSEL0 dado en las tablas de los bits CKSEL3-0 vistas anteriormente. Como se ve algo confuso, vamos a poner un ejemplo de diseño. Supongamos que nuestra aplicación utilizará un ATmega644P a una frecuencia muy estable de 20 MHz. En primer lugar debemos utilizar un XTAL estándar de 20MHz, para lo cual debemos programar los bits CKSEL3-0 con 0111 (ver las tablas de arriba). Como el bit CKSEL0 en este caso es 1, descartamos las configuraciones de la tabla donde CKSEL0 es 0. Así mismo, como 20MHz no es una frecuencia baja, también descartamos la configuración de XTAL baja frecuencia, slowly rising power. Ahora todavía tenemos las tres opciones resaltadas en la siguiente tabla. MSc. Ing. Jacob Astocondor Villar
22
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Tabla CKSEL0 CKSE SUT1 L0 SUT0
Retardo de reset
Retardo de arranque
Fuente de Oscilador, Condiciones de alimentación
0
10
14CK
1K CK
XTAL baja frecuencia, BOD enabled
0
11
4.1ms + 14CK
1K CK
XTAL baja frecuencia, fast rising power
1
00
65ms + 14CK
1K CK
XTAL baja frecuencia, slowly rising power
1
01
14CK
16K CK
XTAL, BOD enabled
1
10
4.1ms + 14CK
16K CK
XTAL, fast rising power
1
11
65ms + 14CK
16K CK
XTAL, slowly rising power
¿Cuál elegir? Vemos que los ciclos de reloj son todos iguales a 16K CK. Entonces nuestra decisión dependerá del retardo de reset requerido. Si nuestro circuito tiene una alimentación Vcc que se eleva lentamente (slowly rising power), “debemos” elegir un retardo de 65ms con SUT1-0 = 11. Pero si en nuestro circuito el nivel de Vcc se eleva rápidamente (fast rising power), podemos optar por el retardo de 4.1ms con SUT1-0 = 10. Por supuesto que también en este caso podemos optar por el retardo de 65ms. Por último, explicamos lo que significa XTAL, BOD enabled. BOD es un circuito interno que detecta cuando la tensión de Vcc cae debajo de ciertos niveles. También sirve para que el AVR no esté trabajando con una alimentación defectuosa. Así que configurar el retardo de 14 CK (lo mismo que nada) equivale a no utilizar retardo de reset y solo debe utilizarse cuando nuestra aplicación trabaje con un circuito BOD externo o interno. El BOD interno del AVR se configura con los bits BODLEVEL2-0.
CKDIV8. PRESCALER DEL RELOJ DEL SISTEMA Los megaAVR recientes, como los tratados en este capítulo, tienen un prescaler en el sistema de reloj, que dividirá la frecuencia del reloj cualquiera que sea su fuente (XTAL, RC Interno etc.). El Prescaler puede dividir la frecuencia del reloj entre 256, entre 128, entre 64,… hasta 1, dependiendo del valor que se cargue en el Registro de E/S CLKPR, el cual se puede modificar en cualquier momento en tiempo de ejecución. En este momento basta con saber que el bit CKDIV8 configura el registro CLKPR para que el reloj se divida inicialmente entre 8 o entre 1.
Tabla CKDIV8 CKDIV8
Factor del Prescaler del Reloj
0
8
1
1
El valor por defecto del bit CKDIV8 es 0 = programado = reloj dividido entre 8. Si lo dejamos así, nuestro megaAVR operará 8 veces más lento. Es más sencillo desmarcar esa casilla que escribir el código MSc. Ing. Jacob Astocondor Villar
23
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
que reconfigura el Prescaler. A propósito, el Wizard de CodeVision AVR genera ese código automáticamente.
BODLEVEL2-0. Voltaje de Disparo del BOD Es un reset por baja tensión. Esta característica le permite al AVR auto resetearse cada vez que detecte una caída de tensión en la alimentación Vcc, por debajo de un nivel establecido por los bits BODLEVEL2, BODLEVEL1 y BODLEVEL0. En la figura subsiguiente la señal de RESET INTERNO se activa cuando el nivel de Vcc cae por debajo de VBOT-. Luego para que el procesador del AVR vuelva a ejecutar el programa no solo bastará que Vcc supere el valor de VBOT+, sino que transcurra el RETARDO DE RESET . La diferencia entre VBOT+ y VBOT- constituye el mecanismo de histéresis. El AVR tiene un filtro pasa-bajas interno para evadir el ruido y evitar un reset ante los microvalles de tensión en Vcc. La caída de tensión tiene que ser mayor a 2us (valor típico).
Tabla BODLEVEL2-0 BODLEVEL2-0
Voltaje de disparo de BOD (valor típico)
111
BOD Desactivado
110
1.8
101
2.7
100
4.3
MSc. Ing. Jacob Astocondor Villar
24
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
WDTON. Habilitación del Watchdog El Watchdog o WDT es un temporizador que puede monitorizar el funcionamiento fluido del microcontrolador. El WDT lo estudiaremos al final porque no es imprescindible. Por el momento diremos que se trata de un temporizador que una vez habilitado debemos resetear periódicamente en el programa. Si no lo hacemos, causará un reset en el AVR y el programa se volverá a ejecutar desde cero. Cuando el WDT no está habilitado por su fuse WDTON (hardware) todavía es posible activarlo por software. Pero una vez activado por su fuse no habrá rutina software que lo apague. En la mayoría de las prácticas no querremos estar preocupándonos del estado del WDT, así que la mejor decisión será tenerlo inhabilitarlo, que felizmente es el valor por defecto del bit WDTON, así que ni siquiera tendríamos que tocarlo.
MSc. Ing. Jacob Astocondor Villar
25
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
CKOUT. Salida de Reloj Cuando este fuse está programado la señal de reloj del sistema saldrá por el pin CLKO de los megaAVR (ver más abajo). Esta señal incluye el efecto del Prescaler de reloj. Puede servir para sincronizar el microcontrolador con otros dispositivos de la aplicación, pero se usa muy raramente, así que lo habitual es dejar CKOUT con su valor por defecto 1, o sea sin programar. Si se programa accidentalmente y el diseño utiliza el pin CLKO para una función de E/S, se puede producir un corto circuito que dañe el pin o hasta el megaAVR completo.
MSc. Ing. Jacob Astocondor Villar
26
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
OCDEN y JTAGEN. Habilitar Depuración JTAG El fuse OCDEN sirve para habilitar el módulo OCD interno del megaAVR. El módulo OCD (On Chip Debug) es el sistema de depuración que poseen los microcontroladores. Está constituido por todo un circuito que puede monitorizar el estado del CPU, de los periféricos internos, de todos los registros del AVR y de las memorias RAM, FLASH y EEPROM. Los resultados serán enviados a una computadora a través de una interface que puede ser JTAG, debugWIRE, PDI, aWire o Nexus, según el tipo de microcontrolador. Del lado de la computadora estará corriendo un programa como Atmel Studio 6 en modo depuración para recibir todos los datos e ir visualizándolos en la pantalla. También es posible enviar desde la PC comandos de ejecución del programa como Step into, Step over, etc. En otras palabras, es como correr el simulador de Atmel Studio 6 o Proteus VSM, pero esto será real y a veces en tiempo real. En el caso de los ATmegaXX4 el módulo OCD se conecta al exterior mediante la interface JTAG, la cual está conformada por los pines TMS, TCK, TDI y TDO (ver más abajo). La interface JTAG debe ser habilitada por separado porque tiene doble función: Además de la depuración también sirve para programar el AVR. La interface JTAG se puede habilitar/deshabilitar de dos formas: por hardware, programando el fuse JTAGEN y por software, mediante el bit JTD del registro MCUCR. En consecuencia, si vamos a programar nuestro AVR por JTAG solo es necesario activar el fuse JTAGEN y tener el bit JTD del registro MCUCR en cero. De hecho, el AVR viene de fábrica con JTAGEN activado y el registro MCUCR inicia con todos sus bits en cero. Pero si además vamos a utilizar la interface JTAG para depurar el programa del AVR, también tenemos que activar el fuse OCDEN. El valor predeterminado de OCDEN es desactivado y si no vamos a entrar en depuración, debemos dejarlo así para que su circuito no consuma energía innecesariamente. MSc. Ing. Jacob Astocondor Villar
27
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Para programación o para depuración, si la interface JTAG está habilitada, los pines TMS, TCK, TDI y TDO no podrán ser usados como pines de E/S convencionales. Son 4 pines que solo los megaAVR de varios puertos pueden ostentar.
DWEN. Habilitar Depuración debugWIRE No todos los AVR tienen un sistema de depuración sofisticado con interface JTAG porque demanda muchas líneas de E/S. Para los AVR que no disponen de tantos pines ATmel diseñó interfaces más sencillas como debugWIRE o aWire, conformadas por una sola línea, que es el mismísimo pin de RESET del AVR, aunque normalmente no se grafica así en sus diagramas de pines. aWire es propio de los AVR de 32 bits y sirve para depuración como para depuración. En cambio, debugWIRE solo se encuentra en los AVR de 8 bits y no permite la programación del AVR. A diferencia de JTAG, para la depuración debugWIRE solo se requiere activar el fuse DWEN. Con ese hecho se pone en acción el circuito OCD interno del AVR al tiempo que el pin DW / RESET queda destinado como pin de E/S para la depuración. La configuración predeterminada del fuse DWEN es deshabilitada y debemos dejarla así si no lo vamos a usar. De lo contrario, el circuito de monitoreo del OCD interno también estará funcionando activamente, MSc. Ing. Jacob Astocondor Villar
28
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
consumiendo energía innecesaria; y lo peor de todo, perderemos la opción de reprogramar nuestro AVR a bajo voltaje. Para rehabilitarlo tendríamos que utilizar una interface de programación a alto voltaje. Si retomamos nuestro enfoque sobre los megaAVR de 3 y 4 puertos, diremos que los ATmegaXX4 poseen depuración con interface JTAG y los ATmegaXX8, depuración con interface debugWIRE.
MSc. Ing. Jacob Astocondor Villar
29
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
EESAVE. Preservar Contenido de la EEPROM Cada vez que grabamos nuestro AVR con un nuevo programa se ejecutará previamente un borrado completo de la memoria FLASH y de la EEPROM interna. Si queremos que la EEPROM no se borre en este proceso debemos programar este fuse. Su configuración predeterminada es sin programar, como se muestra abajo.
MSc. Ing. Jacob Astocondor Villar
30
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
SPIEN. Habilitación de Programación SPI Este fuse permite habilitar o deshabilitar la programación SPI. Para entender esto primero debemos saber que los microcontroladores AVR tienen los siguientes modos de programación (sin contar la programación por la interface de depuración):
La programación mediante la interface SPI (Serial Port Interface) en bajo voltaje, esto es, con 0V aplicados al pin RESET. Es la interface más común y está presente en casi todos los AVR, incluyendo por supuesto en nuestros estudiados ATmegaXX4 y ATmegaXX8.
La programación mediante la interface Paralela. Aquí el voltaje aplicado al pin RESET debe estar comprendido 11.5 V y 12.5 V. Este modo permite programar algunos fuses, como SPIEN y RSTDISBL, que no son accesibles desde la interface SPI en bajo voltaje. Sin embargo, la interface paralela tiene el inconveniente de requerir cerca de 15 pines del AVR.
La programación mediante la interface SPI en alto voltaje, donde se aplica 12V al pin RESET. Solo se encuentra en los pequeños AVR que no tienen los suficientes pines para soportar la programación paralela, en algunos tinyAVR para ser más precisos.
Por lo tanto, la programación en alto voltaje, serial o paralela, siempre estará disponible pero la programación serial SPI se puede deshabilitar mediante el fuse SPIEN. La modificación del bit SPIEN solo es posible desde la programación en alto voltaje. Los megaAVR vienen con su programación serial activada de fábrica, como se aprecia en la siguiente imagen.
BOOTSZ1-0. Tamaño de la Sección de Boot Loader Este fuse configura el tamaño que tendrá la Sección de Boot Loader, estudiada previamente. Si no vamos a usar esta característica del megaAVR, no interesan los valores que tengan los bits BOOSZ1 y BOOTSZ0. MSc. Ing. Jacob Astocondor Villar
31
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
BOOTRST. Ubicación del Vector de Reset El Vector de Reset es la dirección de la memoria FLASH por donde se empezará a ejecutar el programa. Normalmente es 0x0000 porque el código del programa empieza a mapearse desde la primera dirección. La única situación en que esto debe cambiar es cuando se usa un programa de Boot Loader. Cuando el fuse BOOTRST está activado el vector de reset será la primera dirección de la Sección de Boot Loader. Como es de esperar, la configuración por defecto de este fuse es sin programar, como se ve abajo, y no debería modificarse a menos que se sepa bien lo que se hace.
MSc. Ing. Jacob Astocondor Villar
32
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
RSTDISBL. Deshabilitar Reset Externo Suele estar disponible en los AVR que cuentan con pocos puertos. Por defecto este fuse no está programado y el pin de RESET cumple su función habitual de reiniciar la ejecución del programa cuando se pone a nivel bajo, además de permitir al AVR entrar en modo de programación de bajo voltaje. Pero si programamos el bit RSTDISBL, el pin RESET trabajará como PC6, o sea, como el séptimo pin de E/S del puerto C. Yo no suelo programar este bit porque me gusta resetear el AVR a cada rato para asegurarme de que programa siempre inicia bien. Pero más allá de gustos, debemos insistir en que si el pin RESET pierde su función habitual, ya no podremos reprogramar nuestro AVR con bajo voltaje. De llegar a esa fatalidad, deberemos utilizar un programador que trabaje a alto voltaje (12V) para reponer el estado del fuse RSTDISBL.
MSc. Ing. Jacob Astocondor Villar
33
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
SELFPRGEN. Habilitar Autoprogramación Este fuse solo está disponible en los megaAVR que no dividen su memoria en secciones de Aplicación y de Boot Loader, es decir, en los AVR que no soportan el Boot Loader convencional. Con el fuse programado se podrá utilizar la instrucción de ensamblador SPM en cualquier parte del programa. En caso contrario SPM no tendrá efecto. Por defecto el fuse SELFPRGEN está sin programar. Ya sea que se trabaje en C o en ensamblador, el programador normalmente sabe si va a acceder a la memoria FLASH para escritura. En ese caso se deberá activar este fuse. Y si no tienes idea de lo que estoy hablando, casi te puedo asegurar que no interesa el valor que le des a este fuse y hasta te recomendaría que lo actives.
MSc. Ing. Jacob Astocondor Villar
34
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Lock Bits o Bits de Candado “Last, not least”. De hecho, los Bits de Candado son más importantes que los fuses. Por eso aparecen en primera posición en los softwares de grabación. Todos los megaAVR disponen de los Bits de candado generales LB1 y LB2 y, obviamente, los bits de candado de Boot Loader solo están presentes en los megaAVR con soporte de Boot Loader. Tabla Byte de Bits de Lock Byte de Bits de Lock
Bit
Descripción
Valor por defecto
-
7
–
1 (sin programar)
-
6
–
1 (sin programar)
BLB12
5
Boot Lock bit (Bit de candado de Boot Loader)
1 (sin programar)
BLB11
4
Boot Lock bit (Bit de candado de Boot Loader)
1 (sin programar)
BLB02
3
Boot Lock bit (Bit de candado de Boot Loader)
1 (sin programar)
BLB01
2
Boot Lock bit (Bit de candado de Boot Loader)
1 (sin programar)
LB2
1
Lock bit (Bit de candado general)
1 (sin programar)
LB1
0
Lock Bit (Bit de candado general)
1 (sin programar)
Los lock bits generales LB1 y LB2 establecen tres modos de protección de las memorias del AVR, de sus fuses y de los mismos lock bits, como se describen en la tabla de abajo. Para entender esto debemos saber que a diferencia de algunos otros microcontroladores donde la programación de la memoria FLASH suele ir unida con la programación de sus fuses, en los AVR es posible programar y leer por separado los diferentes espacios de memoria [no volátiles] que poseen. El modo por defecto es 1. Allí podremos seguir reprogramando por separado las memorias FLASH y EEPROM del AVR así como los fuses. Sobre los mismos lock bits, todavía podremos programarlos para pasar al modo 2 y 3. En el modo 2 las opciones disponibles desde las interfaces de programación serial y paralela serán: primero, leer las memorias FLASH, EEPROM y los fuses (para propósitos de verificación seguramente) y segundo, programar los lock bits, siempre y cuando vayamos a establecer el modo 3 o el mismo 2, es decir, no podremos regresar al modo 1 por esta vía. La interface JTAG todavía nos permitirá escribir en la FLASH y EEPROM, aunque es una puerta que debe haber sido abierta previamente programando el fuse JTAGEN, lo cual será poco probable. Si elegimos el modo 3 nuestro AVR quedará con su programa actual y no podremos volver a programarlo. Con esta opción tampoco se podrá leer el código de programa del AVR por ninguna interface desde ningún dispositivo externo. Este modo se usa para proteger el código del programa. Para quienes conozcan los PIC, es como programar el fuse de protección de código. Desde el modo 1 siempre podremos pasar al modo 2 o 3, y desde el modo 2 al modo 3. Pero para regresar un nivel de seguridad atrás la única forma es aplicando una instrucción chip erase, que borrará las memorias EEPROM y FLASH, y los lock bits regresarán al modo 1. Obviamente, por cuestiones de seguridad los lock bits son los últimos en borrarse.
MSc. Ing. Jacob Astocondor Villar
35
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Tabla Modo de LB Modo LB2 de LB LB1
Tipo de protección
1
11
No se habilita ninguna característica de Candado.
2
10
Se deshabilitan las posteriores programaciones de las memorias FLASH y EEPROM tanto en modo de programación Serial y Paralela. También se bloquean los bits de los fuses.
00
Se deshabilitan las posteriores programaciones y verificaciones de las memorias FLASH y EEPROM tanto en modo de programación Serial, Paralela y JTAG (si se tiene). También se bloquean los bits de los Fuses y los bits de candado de Boot Loader en los modos de programación Serial y Paralela.
3
Para comprender el uso de los 4 bits de candado de Boot Loader debemos conocer primero la función de las Secciones de Aplicación y de Boot Loader, además de las instrucciones de ensamblador LPM y SPM, que participan activamente en la auto-programación del AVR. LPM (Load from Program Memory) sirve para leer un byte de dato de la memoria FLASH. SPM (Store to Program Memory) sirve para escribir un byte de dato en la memoria FLASH. Ambas instrucciones, LPM y SPM, trabajan con el puntero Z para direccionar la memoria FLASH. Tabla Modo de BLB0 Modo de BLB02 BLB0 BLB01
Tipo de protección
1
11
No habrá restricciones para SPM o LPM en su acceso a la Sección de Aplicación.
2
10
No se permite el uso de SPM para escribir en la Sección de Aplicación.
00
No se permite el uso de SPM para escribir en la Sección de Aplicación, ni el uso de LPM para leer la Sección de Aplicación desde la Sección de Boot Loader. Si los Vectores de Interrupción están ubicados en la Sección de Boot Loader, las interrupciones se deshabilitan durante la ejecución desde la Sección de Aplicación.
01
No se permite el uso de LPM para leer la Sección de Aplicación desde la Sección de Boot Loader. Si los Vectores de Interrupción están ubicados en la Sección de Boot Loader, las interrupciones se deshabilitan durante la ejecución desde la Sección de Aplicación.
3
4
Tabla Modo de BLB1 Modo de BLB1
BLB12 BLB11
Tipo de protección
1
11
No habrá restricciones para SPM o LPM en su acceso a la Sección de Boot Loader.
2
10
No se permite el uso de SPM para escribir en la Sección de Boot
MSc. Ing. Jacob Astocondor Villar
36
UNIVERSIDAD NACIONAL DEL CALLAO
FIEE-2014-V
MICROCONTROLADORES
Tabla Modo de BLB0 Modo de BLB02 BLB0 BLB01
Tipo de protección
1
11
No habrá restricciones para SPM o LPM en su acceso a la Sección de Aplicación.
2
10
No se permite el uso de SPM para escribir en la Sección de Aplicación.
Loader.
3
4
00
No se permite el uso de SPM para escribir en la Sección de Boot Loader, ni el uso de LPM para leer la Sección de Boot Loader desde la Sección de Aplicación. Si los Vectores de Interrupción están ubicados en la Sección de Aplicación, las interrupciones se deshabilitan durante la ejecución desde la Sección de Boot Loader.
01
No se permite el uso de LPM para leer la Sección de Boot Loader desde la Sección de Aplicación. Si los Vectores de Interrupción están ubicados en la Sección de Aplicación, las interrupciones se deshabilitan durante la ejecución desde la Sección de Boot Loader.
El valor predeterminado de todos bits de candado es 1 ó sin programar. En los softwares de programación como WinPic800 significa que las casillas respectivas están desmarcadas y así se deberían dejar. En otros software como AVRFLASH se indican las configuraciones por sus modos (1, 2, 3 ó 4) y siendo los modos 1 los predeterminados, también deberían quedar así, a menos que estemos seguros de lo que hacemos.
MSc. Ing. Jacob Astocondor Villar
37
UNIVERSIDAD NACIONAL DEL CALLAO
MSc. Ing. Jacob Astocondor Villar
FIEE-2014-V
MICROCONTROLADORES
38