CONFIGURACIONES DE MEMORIA DEL 8051
Inicialmente la cosa más confusa sobre el 8051 es quizás la existencia de varios espacios de memoria, que comienzan en la misma dirección.
Otros µC, tales como el 68HC11, tienen una configuración de memoria mucho más sencilla, en la que solo existe un área de memoria de tipo Von Neuman, residente en uno o en varios chips.
Dentro del 8051 hay un espacio de RAM llamado DATA. Este espacio comienza en la dirección D:00 (el prefijo 'D:' indica segmento DATA) y termina en la dirección 0x7F (127 en decimal). Este área RAM puede utilizarse para almacenar las variables del programa. Se trata de una región direccionable directamente en la que pueden utilizarse instrucciones como 'MOV A,direcc'. Por encima de la dirección 0x7F se encuentran los registros de funciones especiales (SFR), que también son accesibles mediante direccionamiento directo. Sin embargo en algunos derivados del 8051 existe otro espacio de memoria entre las direcciones 0x80 y 0xFF, llamado IDATA (Indirect DATA), que sólo resulta accesible por direccionamiento indirecto (MOV A,@Ri). Para esta región que se solapa con los SFR se utiliza el prefijo 'I:'. El 8051 carece de estos 128 bytes del espacio IDATA, que se añadieron cuando apareció el 8052. Esta región resulta adecuada para la pila a la que siempre se accede indirectamente a través del apuntador de pila SP (Stack Pointer). Y para hacer las cosas más confusas, resulta que los 128 bytes de RAM comprendidos en las direcciones 0..0x7F también pueden ser accedidos indirectamente con la instrucción MOV A,@Ri
Fig.1. - Los espacios de memoria del 8051.
Un tercer espacio de memoria, el segmento CODE, también comienza en la dirección cero, pero está reservado para el programa o para almacenar valores constantes, ya que el µC no puede escribir en esta región. Se extiende desde C:0000 hasta C:0xFFFF (65536 bytes); parte de este área puede residir dentro del µC y la otra parte, si es necesaria, debe residir en chips externos de memoria EPROM o FLASH. El acceso al contenido del segmento CODE se realiza mediante el contador de programa PC (Program Counter) en los ciclos de búsqueda de instrucciones y con el DPTR (Data Pointer) para la lectura de los datos constantes.
La cuarta región de memoria, llamada XDATA reside en una RAM externa al µC. Comienza en X:0000 y se extiende hasta X:0xFFFF (65536 bytes). El acceso a esta región se realiza mediante el registro de 16 bits DPTR (Data Pointer). En esta región se puede seleccionar un pequeño espacio de 256 bytes, llamado PDATA (acceso paginado), al que se accede con un apuntador de 8 bits (registros R0 o R1). La dirección inicial de esta región PDATA viene dada por 16 bits, siendo los 8 bits de mayor peso los contenidos en el SFR P2, estando a 0 los 8 bits restantes.
Una pregunta inmediata es: "¿Cómo evita el 8051 que el acceso a un dato en D:00, realice también un acceso al dato X:0000?
La respuesta reside en el hardware del 8051: Cuando la CPU intenta acceder a D:00, habilita la RAM interna mediante una señal READ interna, que no provoca cambios en la patilla /RD, utilizada para leer la RAM externa.
MOV A,40H ; Lleva el
valor de la dirección D:0x40 al acumulador.
Este modo de direccionamiento (directo) se utiliza en el modelo de memoria
SMALL.
MOV R0,#0A0H
MOV A,@R0 ; Lleva el
valor de la dirección I:0xA0 al acumulador
Este modo de direccionamiento se utiliza para acceder a la región de RAM interna de
acceso indirecto situada por encima de la dirección 0x7F, aunque también es una
forma alternativa de acceso a los 128 bytes situados debajo de la dirección 0x80.
Una variación de DATA es BDATA (bit data). Esta es un área de 16 bytes (128 bits) que se extiende desde D:0x20 hasta D:0x2F. Se trata de una región muy útil que permite el acceso normal a los bytes con las instrucciones MOV, y también permite el acceso a los bits mediante instrucciones especialmente orientadas al bit, como las siguientes:
SETB 20H.0 ; Pone a uno el bit 0 de la
dirección D:0x20
CLR 20H.2 ; Pone a cero el bit 2 de la
dirección D:0x20
El dispositivo externo EPROM o FLASH de memoria CODE no se habilita durante los accesos a la RAM. De echo, la memoria externa de tipo CODE sólo se habilita cuando una patilla del 8051 llamada PSEN (Program Store Enable) se pone a nivel bajo. El nombre CODE indica que la principal función de la EPROM o FLASH es almacenar el programa.
No existe colisión entre los accesos a la RAM XDATA y la EPROM-FLASH CODE, ya que el dispositivo externo XDATA sólo se activa a petición de dos patillas del 8051 llamadas /RD y /WR (Read & Write), mientras que el dispositivo externo CODE se activa exclusivamente cuando la patilla PSEN se pone a nivel bajo. Lógicamente el 8051 nunca activa a la vez las patillas PSEN y /RD o /WR.
Para acceder a la RAM XDATA existen instrucciones especiales (MOVX)
MOV DPTR,#08000H
MOVX A,@DPTR ; "Lleva al acumulador el contenido de la posición de
; RAM externa cuya dirección está en DPTR (8000H)".
Este modo de direccionamiento se utiliza en el modelo de memoria LARGE.
MOV R0,#080H ;
MOVX A,@R0 ;
Este es un modo de acceso alternativo a la RAM externa que se utiliza en el modelo de memoria COMPACT. La dirección realmente accedida es 0xYY80 siendo YY el contenido del SFR P2.
Un punto importante a recordar es que la patilla PSEN se activa durante la fase de búsqueda de instrucción, y con las instrucciones MOVC...(Move Code) usadas para la lectura de los datos constantes residentes en memoria de código. Por otro lado, las instrucciones MOVX... (Move eXternal) activan las patillas /RD o /WR, según que el movimiento sea hacia la CPU (lectura), o desde la CPU (escritura). La 'X' indica que la dirección no está dentro del 8051, sino que está contenida en un dispositivo eXterno que se habilita con las patillas /RD y /WR.
Así como el programador de PC tiene que elegir entre los modelos de memoria tiny, small, medium, compact, large y huge para definir la segmentación de la RAM, el programador de 8051 tiene que decidir el modelo de memoria a utilizar, el cual determina el lugar de residencia del programa y de los datos.
C51 soporta actualmente las siguientes configuraciones de memoria:
ROM: el tamaño máximo del programa que permite generar C51 es de 64K, sin embargo es posible aumentarlo hasta 1MB mediante el modelo BANKED descrito más abajo. Todos los elementos que se deseen almacenar en la EPROM/ROM, tales como constantes, tablas etc., deben declararse como code.
RAM: Se admiten tres modelos de memoria, SMALL, COMPACT y LARGE
Modelo BANKED: Con este modelo el código puede ocupar hasta 1MB utilizando algunas patillas de un puerto del 8051, o un latch mapeado en memoria. Estos hilos se utilizan para paginar la memoria por encima de la dirección 0xFFFF. Dentro de cada bloque de 64KB debe existir un bloque común (COMMON) para hacer posibles las llamadas a funciones que se encuentren en bancos distintos.
Además de la elección del modelo de RAM, es posible utilizar un modelo globalmente y forzar que ciertas variables y objetos residan en otros espacios de memoria.
Se tratará esta técnica más tarde.
Al disponer de tres modelos de memoria para la RAM, se necesitan criterios para seleccionar el modelo óptimo. En aplicaciones monochip sólo se puede utilizar el modelo SMALL. Si se dispone de memoria RAM externa, es posible elegir entre los modelos SMALL (MOV A,Direct), COMPACT (MOVX A,@R0) y LARGE (MOVX A,@DPTR).
Aunque es posible cambiar de modelo de memoria a lo largo de un proyecto, no es una práctica recomendable.
En el modelo SMALL, las variables se almacenan en la RAM interna del 8051, por lo que el acceso a las mismas es muy eficiente. Debido al limitado tamaño de la RAM del 8051 (128 bytes), y a que en ella residen los registros R0..R7 del procesador y la pila del programa, el espacio disponible para variables es muy reducido. Pese a ello, el modelo SMALL es válido para la mayor parte de las aplicaciones, debido a que el linker maneja la escasa RAM interna del 8051 con técnicas de solapamiento (OVERLAY). De esta manera, el área destinada a los parámetros y a las variables locales de distintas funciones se solapan, si éstas no se llaman mutuamente ni de forma recursiva.
Véase el Capítulo 8 "Soalpamiento de la memoria data realizado por el L51"para más información sobre la técnica de solapamiento.
El modelo SMALL es el más adecuado para aplicaciones en las que el tiempo de ejecución es un factor crítico, ya que el 8051 accede a su RAM interna con mayor rapidez que a cualquier otra área de memoria. Para aprovechar las características ventajosas de este modelo, incluso en programas muy grandes, el programador debe procurar que los arrays y objetos de tamaño grande, así como las variables a las que se accede con poca frecuencia, residan en RAM externa. Por el contrario las variables de acceso frecuente, y de pequeño tamaño deben residir en RAM interna.
Puede ser el mejor modelo en aplicaciones en las que el sistema operativo hace uso de la RAM interna, o en las que la pila adquiere un tamaño elevado. Las variables se almacenan en RAM externa pudiendo tener un tamaño máximo de 128 bytes. El acceso a las mismas se hace mediante instrucciones MOVX A,@R0, lo que proporciona una velocidad de acceso intermedia entre el modelo SMALL (más rápido) y el modelo LARGE (más lento).
Las variables se almacenan en RAM externa pudiendo tener un tamaño máximo de 64 Kbytes. Se accede a las mismas mediante instrucciones MOVX A,@DPTR, lo que proporciona el acceso más lento de todos los modelos de memoria.
Resumiendo: el 8051 dispone de seis espacios de memoria para almacenamiento de datos. Al definir una variable se puede especificar el espacio de memoria elegido para la misma, por medio de las extensiones al lenguaje C para el 8051: data, bdata, idata, pdata, xdata y code. Si al definir una variable se omite el espacio de memoria asignado a la misma, el compilador C51 utiliza automáticamente el tipo de memoria correspondiente al modelo (SMALL, COMPACT o LARGE) utilizado.
Cada tipo de memoria tiene sus pros y sus contras. Aquí se ofrecen algunas recomendaciones para hacer el mejor uso de los mismos.
La selección del tipo de memoria global se realiza incluyendo la línea #pragma SMALL (o COMPACT o LARGE) como primera línea de un fichero C. El compilador C51 utiliza por omisión de la directiva #pragma, el modelo SMALL. Este modelo puede utilizarse en casi el 100% de las aplicaciones, si se tiene la precaución de forzar las variables de tamaño grande, y las variables a las que se accede rara vez, en las áreas PDATA y XDATA.
Véase el capítulo 2 para detalles sobre ubicación de variables.
El modelo COMPACT hace ciertas suposiciones sobre el estado del puerto P2. El espacio XDATA se direcciona mediante instrucciones MOVX que ponen los 16 bits del registro DPTR en los puertos P2 y P0. El modelo COMPACT utiliza el registro R0 como un apuntador de 8 bits, cuyo contenido se pone en el puerto P0 cuando se ejecuta la instrucción MOVX A,@R0. El puerto P2 queda bajo control del usuario para el acceso paginado a la RAM externa. El compilador no tiene información sobre P2, y a menos que se le asigne explícitamente un valor, su contenido será indefinido, aunque generalmente será 0xFF. El linker tiene la tarea de combinar las variables XDATA y PDATA, y si no se le informa adecuadamente, coloca el área PDATA en dirección 0. Por lo tanto el programa COMPACT no funcionará.
Es por tanto esencial asignar a PPAGE en el fichero "startup.a51" el valor adecuado para P2, y poner PPAGEENABLE a 1 para habilitar el modo paginado. La asignación del valor de PPAGE también puede hacerse por medio del control PDATA(ADDR) al realizar la llamada al linker como en:
L51 module1.obj, module2.obj to exec.abs PDATA(0)XDATA(100H)
Notar que el área normal XDATA comienza ahora en 0x100, por encima de la página cero usada para PDATA.