domingo, 27 de noviembre de 2011

EEPROM INTERNA DE LOS ATMEGA

En este post mostraré un pequeño ejemplo sobre la lectura y escritura de la eeprom interna de los atmega.
En el ejemplo trabajo con un mega8, pero el código es fácilmente aplicable a otros ATmega.

El mega8 tiene 512 Bytes en su eeprom (este tamaño varia con cada dispositivo). Su eeprom solamente permite, además de leer, borrar y escribir en una sola operación (la cual demora 8.5 milisegundo aprox), esto en comparación con otros ATmega que permiten solamente borrar, solamente escribir y borrar, y escribir en una misma operación, ósea permiten realizar tareas separadas lo cual puede ayudar a reducir tiempo de escritura.

Bueno, vamos con el programa y explicaré algunas cositas.

Primero un par de macros nuevas que usaré.
Esta primera macro espera hasta que el bit indicado sea 0.

macro1

Esta espera a que el bit sea 1.

macro2

Ahora la primera parte del programa.

ima1

Aquí usaremos el uart para enviar algunos datos, la velocidad será de 9600.
Si queremos iniciar la eeprom con algunos datos tenemos que declararlos. La declaración de los datos y la separación de espacios de la eeprom inicia con “eseg” (segmento de eeprom).

.org    0x000    .db    0x00,0x01,0x02,0x03,0x04 –> Esta parte de código asignará los valores en hexadecimal a las posiciones de memoria iniciadas en 0x000.
.org    0x010    .db    "hola mundo" –> Esta otra parte también asignará los valores a las posiciones iniciando en 0x010.
.org    0x020    .db    0x30,0x31,0x32,0x33,0x34 –> Aquí la asignación inicia en 0x20 y termina en 0x24,
.db "ING. ELECTRONICA"—> Para esta parte no se da un inicio u origen, pero por encontrarse debajo de la asignación anterior que terminó en 0x24, ésta tendrá su inicio en 0x25.
.org    0x50
    data_eeprom_10:    .byte    10     // separa 10 Bytes iniciando en 0x50.
    data_eeprom_5:     .byte     5      // separa 5  Bytes iniciando en 0x5A.
    data_eeprom_16:   .byte     16    // separa 16 Bytes iniciando en 0x5F.

La eeprom cuenta con 3 registros:
EEAR(EEARH:EEARL): Es el registro donde se debe escribir la dirección del byte que se quiere leer o escribir.
EEDR : Es el registro del cual se leerá el dato en una operación de lectura, y en él se debe poner el dato en una operación de escritura.
EECR: Es el resistor donde se encuentran los bits de configuración. Aquí se indicara que operación se desea realizar.

Las rutinas de lectura y escritura son mostradas abajo, en ellas lo primero que hay que hacer es esperar a que termine la operación anterior de escritura (si es que la hubiera). Antes de llamar a la rutina la dirección para leer debe estar en X y el dato retorna en R16, y para escribir la dirección la dirección está en Y y el dato en R16. R16,X y Y pueden ser cambiado a cualquier otro registro.

ima4

En la parte principal de programa se inicia la pila y se configura el uart.


En el programa encontramos tres bucles.
En el primer bucle se leerán los datos que inician en la dirección X=0x10 (“hola mundo”), estos datos se enviarán por el uart y también se irán guardando en la posición Y=data_eeprom_10.
Luego hay un saldo de línea.

El funcionamientos de los otros dos bucles es similar al primero.
Aquí están las rutinas de salto de línea y de envió de datos por el uart.

ima3

Ahora… luego de escribir todo este programa y compilarlo obtenemos como salida un archivo .eep.

panel

En este archivo se encuentran, en formato intel hex, todos los datos de para iniciar nuestra eeprom, este archivo se debe grabar en nuestro microcontrolador después de grabar la flash.

eefile

Al abrir el archivo EEPROM.eep veremos lo mostrado en la imagen superior. El formato es intel y allí podemos ver las posiciones de memoria y cada uno de los bytes.

Ahora simularemos esto en proteus.

p1

Para cargar nuestros datos a la eeprom  interna debemos hacer doble click sobre el ATMEGA8.
En la ventana que nos aparece debemos ir hasta “Advanced Properties” y seleccionar “Initial Contents of Data EEPROM” y luego en la parte derecha (usando el icono de carpeta) debemos seleccionar nuestro archivo con los datos iniciales.

p2

Luego cuando iniciemos nuestra simulación veremos en la eeprom del ATmega lo siguiente.

p4

Si no les aparece lo anterior, y cada vez que quieran resetear la data guardada en la eeprom, deben hacer click en “Reset Persistent Data”…Esto borra todo el contenido de las eeprom’s que se encuentren en la simulación.
p3

Cuando ejecutemos nuestro programa veremos lo siguiente.

p5
p6

Ahora… y seguro se preguntan como transformo mi archivo EEPROM.eep a EEPROM.bin (es el tipo de archivo en el cual debe estar la data incial para la eeprom)--- proteus no permite cargar los datos iniciales desde el .eep.

Para esto pueden usar el “avr-objcopy.exe”, este ejecutable los pueden encontrar dentro de su instalación del avr gcc, se encuentra dentro de una carpeta de nombre bin.
Hay que usar la ventana de comando para hacer la conversión. Un ejemplo seria así.

>avr-objcopy.exe –I ihex ruta_del_archivo_hex.hex –O binary nombre_del_archivo_de_salida.bin

O mas fácil aun, pueden usar este programita que me tome la molestia de hacer en visual C#. Si no lo pueden ejecutar deben instalar en netframework 3.5.

programa

Este programa le pasa los parámetros correctos al “avr-objcopy.exe” para crear el archivo binario. El ejecutable de esta aplicación debe estar en la misma carpeta que el “avr-objcopy.exe”.

Si abren el archivo binario verán los siguiente.

eebin

En esta oportunidad además de este programita muy útil, también compartiré los archivos EEPROM.asm, macros.inc, EEPROM.eep, EEPROM.bin.

El link: EEPROM

Bueno, espero esto les ayude… Hasta pronto.