Tablas de datos en ensamblador
de microcontroladores PIC
Modelo von Neumann
Memoria
instrucciones
Carga inicial
Programa
+
ejecución
datos
Datos Iniciales
Datos
Procesador
En el modelo de von Neumann hay una única memoria
de donde el procesador extrae tanto datos como instrucciones.
El programa se carga en la memoria junto con los datos iniciales
Modelo Harvard
Memoria
Memoria
Programa
Datos
instrucciones
Carga inicial
Datos Iniciales
ejecución
datos
Procesador
En el modelo de procesador basado en la arquitectura Harvard
la memoria de programa está separada de la memoria de datos.
El programa se carga en la memoria de programa. Y los datos iniciales
deben cargarse como valores inmediatos de las instrucciones.
PIC’s
Memoria
Memoria
Programa
Datos
instrucciones
Carga inicial
movlw
addlw
retlw
Datos Iniciales
…
ejecución
datos
Procesador
Cualquier ensamblador ofrece instrucciones con parámetro
inmediato. Los pic ofrecen además una instrucción
especialmente orientada para construir tablas
Tablas
…
movlw 5
call CodigoAscii
(w con valor 35h)
; rutina CodigoAscii. Parámetro en w
CodigoAscii: addwf PCL
retlw 30h
retlw 31h
retlw 32h
retlw 33h
retlw 34h
retlw 35h
retlw 36h
retlw 37h
retlw 38h
retlw 30h
Una tabla viene a ser una estructura de datos programada que devuelve un valor u otro
dependiendo del parámetro. Hace uso de PCL y de las instrucciones retlw.
PCL y PCLATH
PCLATH
0000 0000
PCL
0000 0001
Inicio
00 000
0000 0001
Contador de programa
Org 0
Goto inicio
Org4
movlw 5h
Addwf PCL
Nop
Nop
Nop
Nop
Nop
Goto inicio
(0000000000000)
(0000000000100)
(0000000000101)
(0000000000110)
(0000000000111)
(0000000001000)
(0000000001001)
(0000000001010)
(0000000001011)
PCL y PCLATH “representan” al contador de programa.
El contador de programa siempre apunta a la SIGUIENTE instrucción a ejecutar
PCL y PCLATH
PCLATH
0000 0000
PCL
0000 0101
Inicio
00 000
0000 0101
Contador de programa
Org 0
Goto inicio
Org4
movlw 5h
Addwf PCL
Nop
Nop
Nop
Nop
Nop
Goto inicio
(0000000000000)
(0000000000100)
(0000000000101)
(0000000000110)
(0000000000111)
(0000000001000)
(0000000001001)
(0000000001010)
(0000000001011)
Al cambiar el contador de programa PCL se ve modificado. No así PCLATH
PCL y PCLATH
PCLATH
0000 0000
PCL
0000 0110
Inicio
00 000
0000 0110
Contador de programa
Org 0
Goto inicio
Org4
movlw 5h
Addwf PCL
Nop
Nop
Nop
Nop
Nop
Goto inicio
(0000000000000)
(0000000000100)
(0000000000101)
(0000000000110)
(0000000000111)
(0000000001000)
(0000000001001)
(0000000001010)
(0000000001011)
PCLATH debe ser modificado explícitamente por el programador
PCL y PCLATH
PCLATH
0000 0000
PCL
0000 1011
Inicio
00 000
0000 0110
Contador de programa
Org 0
Goto inicio
Org4
movlw 5h
Addwf PCL
Nop
Nop
Nop
Nop
Nop
Goto inicio
(0000000000000)
(0000000000100)
(0000000000101)
(0000000000110)
(0000000000111)
(0000000001000)
(0000000001001)
(0000000001010)
(0000000001011)
Cuando se modifica PCL, el contador de programa se carga
con el contenido de PCL y PCLATH
PCL y PCLATH
PCLATH
0000 0000
PCL
0000 1011
Inicio
00 000
0000 1011
Contador de programa
Org 0
Goto inicio
Org4
movlw 5h
Addwf PCL
Nop
Nop
Nop
Nop
Nop
Goto inicio
Lo que equivale a un salto o goto
(0000000000000)
(0000000000100)
(0000000000101)
(0000000000110)
(0000000000111)
(0000000001000)
(0000000001001)
(0000000001010)
(0000000001011)
PCL y PCLATH
PCLATH
PCL
0000 0101
0000 0110
Inicio
00 000
0000 0110
Contador de programa
Org 0
Goto inicio
Org4
movlw 5h
Addwf PCLATH
Nop
Nop
Nop
Nop
Nop
Goto inicio
(0000000000000)
(0000000000100)
(0000000000101)
(0000000000110)
(0000000000111)
(0000000001000)
(0000000001001)
(0000000001010)
(0000000001011)
!!NO OCURRE LO MISMO¡¡ si se modifica el PCLATH
PCL y PCLATH
PCLATH
0000 0101
PCL
0000 0111
Inicio
00 000
0000 0111
Contador de programa
Org 0
Goto inicio
Org4
movlw 5h
Addwf PCLATH
Addwf PCL
Nop
Nop
Nop
Nop
Goto inicio
(0000000000000)
(0000000000100)
(0000000000101)
(0000000000110)
(0000000000111)
(0000000001000)
(0000000001001)
(0000000001010)
(0000000001011)
Modificar el PCLATH no afecta al control de ejecución si no viene seguido
de una modificación del PCL.
PCL y PCLATH
PCLATH
PCL
0000 0101
0000 1100
00 101
0000 1100
nop
nop
nop
nop
nop
nop
nop
(0010100001001)
(0010100001010)
(0010100001011)
(0010100001100)
(0010100001101)
(0010100001110)
(0010100001111)
Contador de programa
Al modificar PCL: PCLATH+PCL se cargan en el contador de programa
PCL,PCLATH: Páginas
PCL
PCLATH
0000 0000
0..255
0000 0001
0..255
0000 0010
0..255
0..255
0000 0011
Memoria de
Programa
Dado este
comportamiento de
PCL-PCLATH. La
memoria de programa
puede considerarse
dividida en páginas:
En los 16F84 solo 10
de los 13 bits del
contador de programa
son útiles (sólo 1K de
memoria de
programa): 8 en PCL
y 2 en PCLATH. Por lo
tanto 4 páginas.
Tablas y páginas: problemas
Pagina 0:
Pagina 1:
[0005]:movlw 5
[0006]:call CodigoAscii
[0007]:… (w con valor 35h)
[0008]:…
…
[000B]:…
[000C]:…
; rutina CodigoAscii. Parámetro en w
CodigoAscii:
[0105]:
addwf PCL
[0106]:
retlw 30h
[0107]:
retlw 31h
[0108]:
retlw 32h
[0109]:
retlw 33h
[010A]:
retlw 34h
[010B]:
retlw 35h
[010C]:
retlw 36h
[010D]:
retlw 37h
[010E]:
retlw 38h
[010F]:
retlw 30h
¡NO FUNCIONA COMO
ESPERAMOS!
En este momento
PCLATH==0.
Al modificar PCL; PCLATH
|PCL se cargan en el
contador de Programa.
Tablas y páginas
Pagina 0:
Pagina 1:
[0005]mvlw HIGH CodigoAscii
[0006]movwf PCLATH
[0007]:movlw 5
[0008]:call CodigoAscii
[0009]:… (w con valor 35h)
[
; rutina CodigoAscii. Parámetro en w
CodigoAscii:
[0105]:
addwf PCL
[0106]:
retlw 30h
[0107]:
retlw 31h
[0108]:
retlw 32h
[0109]:
retlw 33h
[010A]:
retlw 34h
[010B]:
retlw 35h
[010C]:
retlw 36h
[010D]:
retlw 37h
[010E]:
retlw 38h
[010F]:
retlw 30h
Modificamos primer
PCLATH=01.
Al modificar PCL; PCLATH
|PCL se cargan en el
contador de Programa.
¡SOLUCION!
Tablas y páginas:
Tabla entre dos páginas: otro problema
Pagina 0:
Pagina 1:
[0005]mvlw HIGH CodigoAscii
[0006]movwf PCLATH
[0007]:movlw 5
[0008]:call CodigoAscii
[0009]:… (w con valor 35h)
[
; rutina CodigoAscii. Parámetro en w
CodigoAscii:
[00FB]:
addwf PCL
[00FC]:
retlw 30h
[00FD]:
retlw 31h
[00FE]:
retlw 32h
[00FF]:
retlw 33h
[0100]:
retlw 34h
[0102]:
retlw 35h
[0103]:
retlw 36h
[0104]:
retlw 37h
[0105]:
retlw 38h
[0106]:
retlw 30h
Mientras PCL no se
desborde, funciona como
esperamos
Tablas y páginas:
Pagina 0:
Pagina 1:
[0005]mvlw HIGH CodigoAscii
[0006]movwf PCLATH
[0007]:movlw 5
[0008]:call CodigoAscii
[0009]:… (w con valor 35h)
[
; rutina CodigoAscii. Parámetro en w
CodigoAscii:
[00FB]:
addwf PCL
[00FC]:
retlw 30h
[00FD]:
retlw 31h
[00FE]:
retlw 32h
[00FF]:
retlw 33h
[0100]:
retlw 34h
[0102]:
retlw 35h
[0103]:
retlw 36h
[0104]:
retlw 37h
[0105]:
retlw 38h
[0106]:
retlw 30h
¡NO!
Pero si PCL desborda:
PCL=0FFh
PCL+1=00
Como PCLATH permanece a
00, al cargarse PCLATH|PCL
en el contador de programa,
salta a la dirección 0 de la
página 0
Tablas y páginas:
Pagina 0:
Pagina 1:
[0005]
[0006]
[0007]:movlw 5
[0008]:call CodigoAscii
[0009]:… (w con valor 35h)
[
; rutina CodigoAscii. Parámetro en w
CodigoAscii:
[00F5]
mvlw HIGH Salto
[00F6]
movwf PCLATH
[00F7]
addlw 3
[00F8]:
addwf PCL,W
[00F9]:
btfsc STATUS,C
[00FA]:
incf PCLATH
Salto:
[00FB]:
movwf PCL
[00FC]:
retlw 30h
[00FD]:
retlw 31h
[00FE]:
retlw 32h
[00FF]:
retlw 33h
[0100]:
retlw 34h
[0102]:
retlw 35h
¡SOLUCION!
Realizar primer una SUMA
FICTICIA (addwf PCL,W) y
comprobar el carry. Si hay
desbordamiento sumar 1 a
PCLATH
Conclusión
• Las tablas son unas estructuras de datos muy
útiles para cargar datos iniciales en el programa
• Algunos problemas pueden surgir si no
localizamos adecuadamente la tabla en la
memoria de programa
• Es necesario tener en cuenta tales problemas y
resolverlos de manera que la funcionalidad de la
tabla se vuelva independiente de la localización
en la memoria de programa.
Descargar

Tablas de datos en ensamblador de microcontroladores PIC