Está en la página 1de 11

Tema 5.

1 Las memorias de los procesadores AVR


Los procesadores AVR tienen tres tipos de memoria:

Memoria flash o memoria de programas

Memoria esttica o memoria para datos

Memoria EEPROM

Las primeras dos memorias (flash y esttica) son las que se usan ms comnmente durante la ejecucin de
programas. En la siguiente figura se muestran los mapas de memoria de estos dos tipos de memoria:

Como se observa en la figura, la memoria de programa o memoria flash es una memoria de 8 Kbytes que est
organizada como 4K palabras de 16 bits cada una. En el procesador AT90S8515 el PC (Program Counter) es
un registro de 12 bits, lo que le permite direccionar 4K celdas (212 = 4096).
La memoria esttica est organizada en bytes, es decir, en celdas de 8 bits cada una. Las primeras 96
direcciones de la memoria esttica corresponden a los 32 registros de propsito general y a los 64 registros
de entrada/salida. Las siguientes 512 direcciones corresponden a la memoria esttica interna. Es posible
agregar una memoria esttica externa que compartira el espacio de direccionamiento con la memoria interna.
Esta extensin de la memoria ocupar las siguientes direcciones disponibles hasta un mximo de 64 Kbytes.
La memoria esttica o de datos puede ser accesada por medio de cinco modos de direccionamiento:

Directo,

Indirecto con desplazamiento,

Indirecto,

Indirecto con predecremento, e

Indirecto con posincremento

En el modo directo se puede direccionar toda la memoria de datos. En el modo indirecto con desplazamiento
se pueden alcanzar 63 localidades de memoria basadas en las direcciones dadas en los registros Y o Z. En
modo de direccionamiento indirecto con predecremento o posincremento, los contenidos de los registros X, Y
y Z son decrementados o incrementados.
La memoria EEPROM
Esta memoria se accesa por medio de tres registros direccionados en el espacio de E/S:

Registro de direccin (EEARH y EEARL)

Registro de dato (EEDR)

Registro de control (EECR)

En el registro de direccin (EEARH:EEARL) se especifica la direccin de la memoria EEPROM a accesar. En


el caso del procesador AT90S8515, la memoria EEPROM es de 512 bytes.
El registro de datos (EEDR) contiene el dato ledo o a ser escrito a la memoria EEPROM. En una operacin
de escritura se debe colocar la direccin en EEARH:EEARL y el dato a escribir en EEDR. Al finalizar la
operacin de escritura, el dato almacenado en EEDR se guard en la EEPROM. En una operacin de lectura
se debe colocar la direccin en EEARH:EEARL y el dato ledo estar disponible en EEDR al finalizar la
operacin.
Cuando se escribe a la memoria EEPROM, el CPU se detiene durante dos ciclos de reloj antes de ejecutar la
siguiente instruccin. Cuando se lee de la memoria EEPROM, el CPU se detiene cuatro ciclos del reloj antes
de ejecutar la siguiente instruccin.
En el registro de control, EECR, los bits 0, 1 y 2 nos permiten especificar la operacin a realizar con la
EEPROM.
El bit 2 es llamado Bit Maestro de Escritura (EEMWE, EEPROM Master Write Enable). Si este bit est en 0, no
puede escribirse a la memoria EEPROM. Si est en 1, entonces puede escribirse a la EEPROM.
El bit 1 es llamado Bit de Escritura (EEWE, EEPROM Write Enable). Cuando la direccin y el dato a escribir a
la EEPROM han sido fijados, este bit debe activarse para escribir el dato a la EEPROM. Para que este bit
tenga efecto, el bit EEMWE debi ser activado antes, de otro modo no se escribe nada a la memoria
EEPROM. Para la escritura deben seguirse los siguientes pasos:
1.

Esperar hasta que EEWE sea cero.

2.

Escribir la direccin destino en EEARH:EEARL.

3.

Escribir el dato en EEDR.

4.

Escribir un "1" al bit EEMWE del registro de control EECR. Para esto, el bit EEWE dese estar
inactivo.

5.

Antes que transcurran cuatro ciclos de reloj despus de activar el bit EEMWE, se debe escribir un "1"
al bit EEWE.

El bit 0 es llamado Bit de Lectura (EERE, EEPROM Read Enable). Cuando la direccin ha sido fijada en
EEARH:EEARL, debe activarse el bit EERE. Cuando este bit es desactivado por el hardware, el dato ledo se
encuentra en EEDR.

Tema 5.2 Punteros


Dentro de los registros de uso general, los registros R26:R27, R28:R29 y R30:R31 tienen un rol extra muy
importante; estos pares de registros se utilizan como apuntadores, es decir, registros que pueden almacenar
direcciones. Este rol es tan importante que estos pares de registros tienen nombres especiales: X, Y y Z,
respectivamente.
Los registros X, Y y Z pueden almacenar direcciones de 16 bits de la memoria esttica, que como
seguramente recuerdas, es la memoria de datos; el registro Z tambin puede almacenar direcciones de la
memoria de programa, que como seguramente recuerdas, es la memoria flash. La siguiente figura muestra
estos tres registros apuntadores:

El byte menos significativo de la direccin de 16 bits se almacena en el registro menor, y el byte ms


significativo se almacena en el registro mayor. Cada registro del par tiene su nombre: XL y XH para R26 y
R27, respectivamente, YL y YH para R28 y R29, respectivamente, y ZL y ZH para R30 y R31,
respectivamente.
El acceso a memoria utilizando estos punteros requiere el uso de las instrucciones LD (LoaD) y ST (STore).
La siguiente tabla ilustra el uso de estas instrucciones y sus opciones con el registro X:

Apuntador

Secuencia

Ejemplos

Lectura/Escritura desde LD R1,X


direccin X, sin
ST X,R1
cambiar el apuntador.

X+

Lectura/Escritura desde LD R1,X+


direccin X, el
ST X+,R1
apuntador se
incrementa en uno
despus del acceso a
memoria.

-X

El apuntador se
decrementa en uno y
despus se
Lee/Escribe desde
direccin X.

LD R1,-X
ST -X,R1

De manera similar se pueden utilizar los registros Y y Z.


Slo hay una instruccin para leer desde la memoria de programa, utiliza el registro Z y es la
instruccin LPM (Load from Program Memory). Esta instruccin copia el byte al que apunta el registro Z de la
memoria de programa al registro R0.
Dado que la memoria de programa est organizada como palabras de 16 bits (cada palabra consiste de dos
bytes: el byte alto y el byte bajo) el bit menos significativo selecciona el byte: 0= byte bajo, 1=byte alto.

Tema 5.3 Acceso a memoria sin incrementos


En esta seccin hablaremos del uso de la memoria de datos o memoria esttica o SRAM. Veremos que esta
memoria se utiliza cuando la cantidad de datos es tal que los registros de uso general se vuelven insuficientes
para almacenar los datos que manipula nuestro programa. Tambin conoceremos algunas instrucciones que
nos permiten intercambiar informacin entre la SRAM y los registros de propsito general.
Como mencionamos en el apartado anterior, el acceso a memoria puede utilizar los apuntadores X, Y y Z. En
esta seccin ilustraremos el uso de estos apuntadores sin incrementos, es decir, sin modificar el contenido del
apuntador utilizado.
El uso de la memoria SRAM
Slo los programas ms simples en lenguaje ensamblador pueden evitar el uso de la memoria de datos,
manejando todos sus datos en los registros de propsito general. En programas de complejidad media o
mayor, por lo general, la cantidad de datos es tal que los registros de uso general son insuficientes. Es
entonces que se vuelve inaplazable el uso de la memoria, ya sea la memoria SRAM o memoria de datos, o la
memoria Flash o de programa.
La SRAM puede utilizarse para definir variables simples, pero tambin para definir buffers, buffers circulares y
tablas, o para almacenar temporalmente resultados intermedios.
Para almacenar un dato en la SRAM es necesario definir la direccin de la celda en la que se guardar el
dato. Las direcciones de la SRAM van desde 0 x 0060 hasta el final de la memoria de datos interna; en el
caso del procesador AT90S8515, este lmite es 0 x 025F.
La instruccin STS nos permite almacenar informacin en la SRAM; por ejemplo, la siguiente instruccin:
sts 0 x 0060,R1
Copia el contenido del registro R1 a la celda 0 x 0060 de la SRAM, que denotaremos como SRAM [0 x 0060].
La instruccin:
lds R1,0 x 0060
Copia el contenido de la celda SRAM [0 x 0060] al registro R1.
Usando nombres simblicos para las direcciones podemos simplificar la escritura y el mantenimiento de los
programas. Las siguientes lneas de cdigo ilustran esto:
.EQU MiDireccPreferida = 0 x 0060
:
sts MiDireccPreferida,R1

Los direccionamientos mostrados arriba corresponden al modo de direccionamiento directo, que se ilustra en
la siguiente figura:

Observen que: i) interviene un registro, que dependiendo de la operacin ser el origen o el destino; ii) en la
instruccin se incluye un campo de direccin de 16 bits; y iii) este modo de direccionamiento permite
direccionar todo el espacio de la memoria de datos (desde la direccin $0000 hasta la direccin $FFFF, si
hubiera suficiente memoria instalada).
Usando apuntadores
Otra forma de accesar la SRAM es mediante el uso de apuntadores. Como comentamos en la seccin
anterior, los procesadores AVR manejan tres registros apuntadores:

X (XH:XL o R27:R26),

Y (YH:YL o R29:R28), y

Z (ZH:ZL o R31:R30).

La siguiente figura ilustra este modo de direccionamiento, que corresponde al direccionamiento indirecto:

Observen que en este modo de direccionamiento tambin es posible accesar cualquier celda de la memoria
de datos, ya que su espacio de direccionamiento abarca de la direccin $0000 a la direccin $FFFF.
Las siguientes lneas de cdigo ilustran el uso de apuntadores:
; Definimos smbolos

.EQU MiDireccPreferida1 = 0 x 0060


.EQU MiDireccPreferida2 = 0 x 0061
.EDU MiDireccPreferida3 = 0 x 0062
.DEF MiRegistroPreferido = R1
.DEF OtroRegistro = R2
.DEF OtrRegistroMas = R3
; Preparamos apuntadores
; La funcin HIGH regresa el byte alto de su argumento
; La funcin LOW regresa el byte bajo de su argumento
ldi XH,HIGH(MiDireccPreferida1)
; R27 <-- ByteAlto(0 x 0060)
ldi XL,LOW(MiDireccPreferida1)
; R26 <-- ByteBajo(0 x 0060)
ldi YH,HIGH(MiDireccPreferida2)
ldi YL,LOW(MiDireccPreferida2)

; R29 <-- ByteAlto(0 x 0061)


; R28 <-- ByteBajo(0 x 0061)

ldi ZL,HIGH(MiDireccPreferida3)
ldi ZL,LOW(MiDireccPreferida3)

; R31 <-- ByteAlto(0 x 0062)


; R30 <-- ByteBajo(0 x 0062)

; Transferimos de SRAM a registros


ld MiRegistroPreferido,X
; R1 <-- SRAM[X]
ld OtroRegistro,Y
; R2 <-- SRAM[Y]
ld OtroRegistroMas,Z ; R3 <-- SRAM[Z]
El cdigo anterior ejemplifica el uso de apuntadores sin incremento: una vez que definimos los valores de los
registro X, Y y Z estos permanecen sin cambio cuando se accesa la memoria.
El siguiente programa ilustra el uso de la SRAM para guardar datos. Calcula la suma de tres nmeros que se
almacenan en las celdas 0 x 0060, 0 x 0061, 0 x 0062 y almacena el resultado en la celda 0x0063 de la
SRAM.
; Archivo: ejsram1.asm
; Calcula la suma de tres datos que se guardan en memoria
.NOLIST
.INCLUDE "8515def.inc"
.LIST
; Definimos datos de forma simblica
.EQU Dato1 = 15
.EQU Dato2 = 23
.EQU Dato3 = 34
; Definimos direcciones de forma simblica
.EQU MiDireccPreferida1 = 0 x 0060
.EQU MiDireccPreferida2 = 0 x 0061
.EQU MiDireccPreferida3 = 0 x 0062
.EQU MiDireccPreferida4 = 0 x 0063
; Cargamos datos a SRAM
ldi r16,Dato1
sts MiDireccPreferida, r16
ldi r16,Dato2
sts MiDireccPreferida2, r16
ldi r16,Dato3
sts MiDireccPreferida3,r16
; Preparamos apuntadores
ldi XH,HIGH(MiDireccPreferida)
ldi XL,LOW(MiDireccPreferida)
ldi YH,HIGH(MiDireccPreferida2)
ldi YL,LOW(MiDireccPreferida2)

; X apunta a Dato1
; Y apunta a Dato2

ldi ZH,HIGH(MiDireccPreferida3)
ldi ZL,LOW(MiDireccPreferida3)

; Z apunta a Dato3

; Transferimos de SRAM a registros


ld R1,X
; R1 <-- SRAM[X]
ld R2,Y
; R2 <-- SRAM[Y]
ld R3,Z
; R3 <-- SRAM[Z]
; Obtenemos la suma de los tres datos
add R1,R2
add R1,R3
; Guardamos el resultado en SRAM
sts MiDireccPreferida4,R1
loop:
rjmp loop
Aunque el programa es muy elaborado para el clculo tan simple que realiza, ilustra el proceso general para
el uso de la SRAM:

Almacenar los datos en la SRAM

Cargarlos a registros para poder manipularlos

Almacenar resultados en la SRAM

Observando la memoria desde el AVRStudio


La siguiente figura ilustra como activar la vista de los registros de propsito general y de la memoria de datos,
de modo que podamos observar la ejecucin de programas que acceden a la memoria de datos (si la imagen
no es muy clara da clic sobre la misma para que puedas observarla mejor).

El punto 1 muestra las opciones del men "View": Memory (Alt+4) y Register (Alt+0), entre otras. El punto 2
seala la ventana de los registros y el punto 3 muestra la ventana de la memoria. En esta ltima, se muestra
que se seleccion la memoria de datos (Data). La opcin de Direccin (Address) muestra el 0 x 60, indicando
que se muestra el inicio de la memoria de datos.

Conforme se traza el programa (con F11), podrs observar los cambios que se operan, tanto en los registros
como en la memoria de datos.

Tema 5.4 Acceso a memoria con incrementos


Como observamos en el Tema 5.2, los procesadores AVR pueden utilizar un par de modos de
direccionamiento indirecto que incluyen predecremento o posincremento a travs de los registros apuntadores
X, Y y Z.
La siguiente figura ilustra el direccionamiento indirecto con predecremento:

En la figura podemos observar que el contenido del apuntador (X, Y o Z) se decrementa en uno (en la figura
se muestra como la suma de -1) y el nuevo valor del apuntador se utiliza para accesar al espacio de datos, de
ah su nombre.
La figura de abajo ilustra el direccionamiento indirecto con posincremento:

En esta figura podemos observar que el contenido del apuntador (X, Y o Z) se utiliza para accesar el espacio
de datos y posteriormente se incrementa en uno.
Las instrucciones siguientes ejemplifican estos modos de direccionamiento:

st -Y,R0 ; Almacena el contenido de R0 en la direccin a la que apunta Y


; con predecremento
ld R1,-Z ; Carga en R1 desde la direccin a la que apunta Z
; con predecremento
st X+,R5 ; Almacena R5 en la direccn a la que apunta X
; con posincremento
ld R6,Z+ ; Carga en R6 desde la direccin a la que apunta Z con
; posincremento
Veremos ms adelante la utilidad de estas instrucciones para manejar datos organizados como tablas o
arreglos.

Tema 5.5 Programas que ilustran el acceso a memoria


En esta seccin mostraremos y analizaremos un par de programas que ilustran el manejo de datos en la
memoria de datos (SRAM).
Primer ejemplo
El primer programa con el que ilustraremos el manejo de la memoria de datos (SRAM) es el siguiente:
; Archivo: ejsram.asm
; Calcula la suma de tres datos que se guardan en memoria
.NOLIST
.INCLUDE "8515def.inc"
.LIST
; Definimos los tres datos de forma simblica
.EQU Dato1 = 15
.EQU Dato2 = 23
.EQU Dato3 = 34
; Definimos direcciones de forma simblica
; Nota que la primera direccin es el inicio de la memoria SRAM (0 x 0060)
.EQU MiDireccPreferida1 = 0 x 0060
.EQU MiDireccPreferida2 = 0 x 0061
.EQU MiDireccPreferida3 = 0 x 0062
.EQU MiDireccPreferida4 = 0 x 0063
; Cargamos datos a la memoria SRAM
; La secuencia es: Rd <- Dato y despus SRAM[Direccion] <- Rd
ldi r16,Dato1
sts MiDireccPreferida1, r16
ldi r16,Dato2
sts MiDireccPreferida2, r16
ldi r16,Dato3
sts MiDireccPreferida3,r16
; Preparamos apuntadores
; Dado que las direcciones de la memoria de programa son palabras
; de 16 bits, se requieren dos registros de ocho bits para guardar
; las direcciones de datos almacenados en esta memoria
ldi XH,HIGH(MiDireccPreferida1) ; X apunta a Dato1
ldi XL,LOW(MiDireccPreferida1)
ldi YH,HIGH(MiDireccPreferida2)
ldi YL,LOW(MiDireccPreferida2)

; Y apunta a Dato2

ldi ZH,HIGH(MiDireccPreferida3)

; Z apunta a Dato3

ldi ZL,LOW(MiDireccPreferida3)
; Transferimos de SRAM a registros
ld R1,X ; R1 <-- SRAM[X]
ld R2,Y ; R2 <-- SRAM[Y]
ld R3,Z ; R3 <-- SRAM[Z]
; Obtenemos la suma de los tres datos
add R1,R2
add R1,R3
; Guardamos el resultado en la memoria SRAM
sts MiDireccPreferida4,R1
loop:
rjmp loop
Las instrucciones que se utilizan para accesar la memoria de datos (SRAM) son sts y ld.
La instruccin sts tiene el siguiente formato:
sts k,Rr
y realiza la operacin
SRAM[k] Rr
La instruccin ld que se utiliza en este programa tiene el siguiente formato:
ld Rd,X
y realiza la operacin
Rd SRAM[X
Segundo ejemplo
El siguiente programa ilustra el uso de las memorias de programa y de datos para manejar tablas de datos. El
programa define en una tabla, almacenada en la memoria de programa (Flash), el alfabeto en minsculas.
El programa regresa en la variable "Letra" definida en la memoria SRAM, la letra que corresponde a la
constante "Numero"; es decir, si "Numero" fuera 3, debera dejar en la variable "Letra" el cdigo ASCII de la
"c", la tercera letra del alfabeto.; Archivo: tabla.asm
; Ilustra el uso de tablas devolviendo el cdigo ascii de las
; letras del alfabeto en minsculas
.NOLIST
.INCLUDE "8515def.inc"
.LIST

; incluir el archivo de definiciones del 8515

.EQU Numero = 20

; Buscamos la vigsima letra del alfabeto

; Define segmento de datos, para usar datos en SRAM


.DSEG
Letra: .byte 1

; Reservamos un byte para la letra a recibir

; Definimos el segmento de cdigo, que utiliza la memoria Flash


.CSEG
rjmp Inicio
Inicio:
; Hacemos que Z apunte a MiTabla
ldi zl,LOW(2*MiTabla)
ldi zh,HIGH(2*MiTabla)
; Vamos a buscar la letra definida como la constante "Numero"

; Usaremos r17:r16 como una palabra, ya que MiTabla est definida


; en la memoria de programa, que utiliza direcciones de 16 bits
; Las siguientes instrucciones hacen que r17:r16 = Numero - 1
; que es el ndice dentro de la tabla que corresponde a la letra
; que buscamos
ldi r16,Numero
dec r16
clr r17
; Ahora sumamos el ndice r17:r16 al registro Z, para que
; este registro "apunte" a la letra buscada.
add ZL,r16
adc ZH,r17
; Ahora hacemos que R0 contenga MiTabla[Z]
lpm
; Finalmente, guardamos el ASCII de la letra en la variable "Letra"
en SRAM
; Para esto, hacemos que X apunte a esta variable en la SRAM
ldi XH,HIGH(Letra)
ldi XL,LOW(Letra)
st X,R0
fin:
rjmp fin
; Guardamos en MiTabla los cdigos ASCII del alfabeto en minsculas
; Al definirlos entre comillas, el ensamblador "traduce" el carcter
; entrecomillado a su codigo ASCII
; MiTlabla[0]="a", MiTabla[1]="b", etc.
MiTabla:
.db "a","b","c","d","e","f","g","h","i","j"
.db "k","l","m","n","","o","p","q","r","s"
.db "t","u","v","w","x","y","z"
Despus de estudiar estos dos ejemplos de programas que utilizan datos en memoria, tanto la de programa
como la de datos, es tiempo de que realices la prctica de programacin con la que demostrars tu dominio
sobre el uso de las memorias de los procesadores para manejar variables.

También podría gustarte