Direccionamiento de datosBueno como hay mucha gente con dudas con respecto a esto pense en escribir un hilo y dejar constancia para todos los demas.
El PIC18 es el primer PIC en introducir una memoria de datos lineal, basta de tener que estar cambiando bancos para cambiar algun registro de nuestros perifericos. Es un gran alivio, bueno.... En parte. Esto trajo problemas que vamos a ver mas adelante. La memoria RAM sigue estando dividida en "bancos" pero esta ves tenemos todos nuestros SFR ( Registros de nuestros perifericos ) al final en el ultimo banco.
Ademas otro cambio, es que posee un set mas rico de instrucciones, y como si fueran pocos cambios se puede habilitar mediante los bits de configuracion un set extendido de instrucciones.
¿Por que nos importa eso? por que el comportamiento de las instrucciones y del direccionamiento es distinto si esta activo o no el set extendido.
Para analizarlo las instrucciones poseen 4 tipos de direccionamiento:
- No tienen ( CLRWDT, SLEEP )
- Literal ( En el que el dato va en el opcode y no en la memoria, ADDLW, MOVLW )
- Directo ( En el que la direccion va en el opcode 8bits maximo, mas de la mitad de las instrucciones )
- Indirecto ( En el que se usa la direccion de los registros FSR )
El acceso indirecto permite el acceso a toda la memoria RAM sin preocuparnos por los bancos ya que el registro puede almacenar la direccion completa (12 bits) y no solo 8 bits como las instrucciones con acceso directo, solo debemos cargar la direccion al FSR y accedimos sin problemas.
Funcionamiento con set de instrucciones estandar (legacy , compatibilidad con los PIC16)El acceso directo se separa en 2 partes:
- Por el Access Bank
- A traves del BSR
Cuando vemos las instrucciones observamos algo distinto a los PIC16
¿Que es esa 'a' que aparece?, Si recordamos en los PIC16 solo teniamos f,d
Es decir f = direccion de registro ( 8 bits ) y d indicando a donde se escribe ( 1 = F, y 0 = W )
Pero ahora tenemos una 'a' que nos complica la vida.
Esa 'a' indica si va a acceder al Access bank o si va usar el registro BSR (Bank Select Register).
En el Access bank encontramos todos nuestros registros SFR, es decir los de nuestros perifericos. Y las primeras direcciones de memoria de la RAM de 0x00 a 0x5F
Mientras que con BSR (4 bits) podemos junto con los 8 bits del opcode generar todas las direcciones de la RAM.
¿Por que Microchip quiso complicarse la vida con esto? Es simple.
Supongamos que estamos en la direccion RAM 0x1.00 (separo en bytes asi se nota el banco y el opcode), si tenemos todos nuestros datos alli, y quisieramos poner a 1 o 0 el pin RB0, para eso deberiamos cambiar BSR por 0x1 para leer el dato, trabajo, cambio BSR a 0xF para poder cambiar el PORTB, luego tendria que cambiar nuevamente al anterior banco.
Esto es ineficiente. Entonces el señor Microchip levanto las tablas de instrucciones, dividio las aguas del rio
y dijo:
Para evitar esto directamente usamos esa 'a' para indicar a que se refieren esos 8 bits.
Si 'a' es 0, la direccion a la que apunta esos 8 bits va a ser el banco 15 ( 0xF60 a 0xFFF ) y el caso que los 8bits sean menores a 0x5F apuntan al banco 0 ( 0x000 0x05F ) -Conocido como Access Bank
Si 'a' es 1, la direccion se va a formar con el BSR:opcode(8bits datos)
De esta forma mientras trabajamos en el banco 3 por ejemplo es posible acceder a los SFR eficientemente. Y no tenemos que estar cambiando el BSR a cada rato. Incluso podriamos acceder hasta 3 secciones de memoria a la misma ves, las primeras posiciones de memoria 0x00 a 0x5F, los SFR, y ademas todo el banco que estemos trabajando.
Esto en ASM ya viene definido, asi como tenemos W y F, el .inc agrega ACCESS y BANKED para la 'a', normalmente para mantener la compatibilidad con los PIC16 se puede omitir la 'a' asi el codigo es funcional tanto en uno como en otro, se asume que es ACCESS si no se incluye nada. Obviamente requiere algunas cosas mas como usar BANKSEL para el cambio de bancos, asi el compilador es el encargado de poner el codigo ese.
Funcionamiento con set de instruciones extendido ( aca se pierde toda la compatibilidad )Este set presenta una mejora para programas en C el cual hace mucho uso de un stack. Hasta ahora no encuentro quien usa este set, desconozco tambien si XC8 aprovecha el set este o no. PERO por las dudas vamos a agregarlo aca para que nadie se sorprenda
Activar este set agrega unas 8 instrucciones mas, pero esto no es lo problematico, sino lo que es problematico es que tambien afecta al modo de direccionamiento de aquellas instrucciones que poseian un direccionamiento directo, que como se nombro es mas de la mitad de las instrucciones.
¿Como funciona cuando se activa este set?Se podria separa nuevamente en dos. Cuando 'a' es 1, y cuando es 0.
- 'a' = 1 = BANKED
Igual que en el caso anterior con el set estandar de instrucciones la direccion esta formada por el BSR:opcode(dato) , es decir ese modo no cambio para nada
- 'a' = 0 = ACCESS
Este es el modo que cambia y bastante. Las dos situaciona se dan:
- Cuando el opcode ( me refiero a los 8 bits de datos que lleva ) es mayor o igual a 0x60 accedemos como antes, es decir vamos a acceder al banco 15 donde estan nuestros SFR, igual que sin el set extendido.
- Cuando el opcode es menor a 0x60 ( menor igual que 0x5F ) es cuando realemente cambia, esto hace que se pierda por asi decirlo el acceso directo y se cree un acceso indirecto con offset. Esta ves la direccion a la cual se va a acceder va a estar dada por el registro indirecto FSR2 (12 bits) + un offset de 8 bits dado por el opcode. Ejemplo si FSR2 = 0x210 y tenemos un
ADDWF [0x10],F,ACCESS
va a sumar lo que esta en la direccion 0x220 ( 0x210 + 0x10 ) con W y va a guardarlo en el mismo lugar (por la F).
Observaran que ahora la instruccion tiene unos corchetes , esto es obligatorio en este set. Por esta forma de direccionamiento (que cambia como funcionan las instrucciones) y por como es la sintaxis de las instrucciones es que pierde la retro-compatibilidad