Está en la página 1de 2

Es muy sencillo. El PC, program counter, tiene 12 bits de largo.

Cuando tu haces una operación aritmetica que modifica al PCL (parte


baja del PC) puedes ingresar como dato en la operación un numero
constante, k, que puede valer entre 0 y 255, o sea 8 bits.

Este numero, por ejemplo, en una tabla, se le suma al PCL para


enviarlo al "offset" deseado, por ejemplo

addwf PCL, f
retlw 0x01
retlw 0x02
retlw 0x03
retlw 0x04
retlw 0x05

bueno, aquel seria un ejemplo. El problema se presenta en el siguiente


caso. El PC esta formado por dos registros:

PCLATH + PCL = PC
siendo

PCLATH = PC<12:8>
y
PCL = PC<7:0>

por lo tanto, cuando yo sume este registro PC con uno de 8 bits solo
estare modificando los bits menos significativos de PC, ESTO es lo que
produce que al hacer una tabla podamos "direccionar" como maximo 255
posiciones, aproximadamente.

¿Cómo se soluciona? Bueno, el PCLATH, es un registro que uno puede


modificar. Para esto aclaremos algo. Existen dos formas de modificar
el PC. Una es mediante un goto computado, que se refiere a operaciones
aritmeticas (o logicas) que modifiquen al PCL. La otra forma de
modificar el registro PC es mediante las instrucciones de salto (goto
y call).

GOTO COMPUTADO:
Estas instrucciones ponen el resultado de la operación llevada a
cabo en los bits menos significativos (8) del registro PC, pero
tambien copian el contenido de PCLATH a la parte alta del registro PC.

INSTRUCCIONES DE SALTO:
A estas instrucciones, se les pasa como parametro un numero de
11 bits (que uno generalmente reemplaza por un label, por ejemplo
"goto loop") y cuando se ejecuta esta instrucción se copian del PCLATH
al PC los bits 12 y 11 del PC...
En estas instrucciones es donde esta el problema del salto
cuando la memoria de programa tiene mas de 2K, pero eso es otro tema
para otra explicacion.

Bueno, vayamos a la solucion. Obviamente la solucion radica en


modificar uno mismo el PCLATH de acuerdo a lo que se este haciendo,
asi que veamos un ejemplo y luego lo explico:
movlw HIGH(inicio_tabla)
movwf PCLATH
movf offset, w
addlw LOW(inicio_tabla)
btfss STATUS, C
goto acceso
incf PCLATH, f
acceso movf offset, w
inicio_tabla addwf PCL, f
retlw 0x01
retlw 0x02
retlw 0x03
retlw 0x04
retlw 0x05

Bien, en primer lugar HIGH(inicio_tabla) es una instrucción para el


compilador, que devuelve la parte alta (bits <12:8> de la direccion
del "inicio_tabla") ese numero lo cargo en principio en el PCLTAH, ya
que estoy seguro de que por lo menos ese sera el valor requerido.
Luego, cargo en W el offset que se ingreso en la tabla y se lo sumo al
valor que tiene el registro PCL en el comienzo de la tabla, de esta
manera obtengo como resultado, en W, el valor que tendra el PCL luego
de las sumas. Si PCL valia alli, por ejemplo 0xF7, y mi offset era de
0x25, el resultado final seria de 0x11C. Este numero, como no es de 8
bits, sera recortado al valor de 0x1C y se generara un carry,
indicando que hubo un desbordamiento u overflow en la suma.
Lo que hacemos, es que si detectamos ese carry, sabemos que algo IRÁ
mal en la suma, porque se necesitara que se incremente el PCLATH,
entonces lo incrementamos nosotros a mano y luego simplemente hacemos
como siempre.

Bueno, espero que lo entiendas, creo que esta claro, pero cualquier
cosa, me consultas. Para mas informacion, consulta la nota de
aplicación numero AN556 de microchip, que lo explica tambien.

Por ultimo, este codigo, logicamente, sirve solo para direccionar


tablas de hasta 256 items, que es el valor maximo del offset. SI
quieres hacer tablas mas largas, basandote en esto, deberas hacer algo
parecido, pero usando dos registros para el offset haciendo algo asi:

OFFSET_HIGH PCLATH PCLATH


| + | = |
OFFSET_LOW PCL PCL

Bueno, esto es todo, cualquier duda, no tengan problemas en consultarme por este
medio

También podría gustarte