Sei sulla pagina 1di 44

16f84A

Alexis Sanchez

Alexis Sanchez – aasanchez@gmail.com


Registros especiales o SFR (Special
Function Registers)
Registro INDF (Indirect File) (Dirección 00h)
El registro INDF que ocupa la posición 0 no tiene existencia física, por lo que no se podrá
acceder a él. En realidad este registro sirve únicamente para especificar la utilización del
direccionamiento indirecto referenciándolo en el direccionamiento indirecto de datos
aunque se utiliza el contenido de FSR

Significa que se va a añadir, al contenido del registro W, el contenido del registro


apuntado por el registro FSR de dirección 04. Se realiza entonces el Direccionamiento
indirecto con respecto al contenido de FSR. Sirviéndose de INDF únicamente como modo
de notación.

Registro TMR0 (Timer 0) (Dirección 01h)


Este registro almacena el valor del contador TMR0, que como ya sabemos, está
funcionando continuamente e incrementando el valor que tiene almacenado. Las opciones
que controlan este contador residen en el registro OPTION.

El Contador de Programa PC (Program Counter) (Dirección 02h y 82h)


Este registro, normalmente denominado PC, es equivalente al de todos los
microprocesadores y contiene la dirección de la próxima instrucción a ejecutar. Se
incrementa automáticamente al ejecutar cada instrucción, de manera que la secuencia
natural de ejecución del programa es lineal, una instrucción después de la otra. Algunas
instrucciones (que llamaremos de control) cambian el contenido del PC alterando la
secuencia lineal de ejecución. Dentro de estas instrucciones se encuentran GOTO y CALL
que permiten cargar en forma directa un valor constante en el PChaciendo que el
programa salte a cualquier posición de la memoria. Otras instrucciones de control son los
SKIP o saltos condicionales, que producen un incremento adicional del PC si se cumple
una condición específica, haciendo que el programa salte, sin ejecutar, la instrucción
siguiente.

El PC es un registro de 13 bits en el 16F84, lo que permite direccionar 8.192 posiciones


de memoria de programa, pero que internamente solamente podrá direccionar 1.024, por
las limitaciones del PIC que de sobre conocemos.
A diferencia de la mayoría de los microprocesadores convencionales, el PC es también
accesible al programador como registro de memoria interna de datos, en la posición 02.
Es decir que cualquier instrucción común que opere sobre registros puede ser utilizada
para alterar el PC y desviar la ejecución del programa.

El contador de programa especifica la dirección de la instrucción que se va a leer para


ejecutarla. El PC tiene una anchura de 13 bits. El byte (los 8 primeros bits) de menor peso
es llamado PCL (Program Counter Low). Este es leíble y escribible. El byte de mayor peso
se llama PCH (Program Counter High) Este registro contiene los 13-8=5 bits del PC y no
puede ser leído ni escrito directamente. Todos los cambios del PCH van a través del
registro PCLATH, situado en las posiciones 0A y 8A.

Alexis Sanchez – aasanchez@gmail.com


Si el PC es destino de una instrucción, el contenido de PCLATCH se tiene en cuenta
automáticamente. Para las instrucciones GOTO y CALL, tiene lugar la misma operación,
teniendo en cuenta el hecho de que el PC está codificado con 11 bits en la propia
instrucción.

El contador de programa y la pila


Los ocho registros de pila no aparecen en el cuadro de la figura 36 por no estar situad
situados
en el mismo espacio de memoria que los demás. Son registros de trece bits capaces de
contener íntegramente al PC. Su utilización es automática, ya que el PC se introduce en
la pila durante la ejecución de una instrucción CALL o de una interrupción, y se extrae de
la pila durante la ejecución del retorno correspondiente.
Cuando los datos contenidos en el PC son almacenados o extraídos de la pila el registro
PCLATH no se ve modificado.
Estos registros de pila deben considerarse como un buffer de memoria circular,
ci lo que
significa que, si se introduce más de 8 valores del PC, el noveno valor tomará la posición
del primero, y así sucesivamente.
Si nos fijamos, ningún bit de registro indica que la pila está llena, por lo que debemos
tener cuidado de que no se desborde, excepto si queremos realizar operaciones de
retorno especiales, pero esto ya es otro tema.

Figura 38 Principio de determinación de los bits de mayor peso del PC por PCLATCH

El Registro STATUS o Registro de Estado (Dirección 03h y 83h)


Ahora vamos a empezar a a describir los registros cuyos bits no forman bytes, de manera
que un bit puede no tener nada que ver con el que tiene al lado. Estos bits se configuran
con un 1 o un 0, y activan o desactivan una función. Algunos de estos bits loslo podemos
cambiar nosotros manualmente a través del programa.
Otros no los activamos nosotros, si no que los activa automáticamente el PIC cuando
pasan ciertos procesos. Estos bits se llaman flags (banderas). Para hacernos una idea
práctica una idea se levanta
anta (se pone a 1) cuando ha pasado algo, al igual que ocurre en
el fútbol con los linieres de banda, los cuales levantan su bandera cuando hay fuera de
juego o hay saque de banda.
Los flags se usan para dar información adicional cuando se realizan operaciones
operaci lógicas y
aritméticas. Podemos hacer uso de ellas para tomar ciertas decisiones que veremos con
calma para cada operación.
El registro STATUS está formado por 8 bits:
R/W R/W R/W R R R/W R/W R/W R
bit 7 6 5 4 3 2 1 bit 0
IRP RP1 RP0 /TO /PD Z DC C

Alexis Sanchez – aasanchez@gmail.com


R/W significa que el bit correspondiente se puede leer y escribir, mientras que R significa
que solamente puede ser leído.
Ahora diremos el significado de cada bit. Los tres primeros bits son banderas.
Bit 0 (flag): C o bit de Carry (Acarreo)
• 1: acarreo del bit más significativo (bit 7) del resultado de la última operación
de suma, pero no en la resta.
• 0: acarreo del bit más significativo (bit 7) del resultado de la última operación
de resta, pero no en la suma.
Bit 1 (flag): DC o bit de Digit Carry (Acarreo de Dígito): Indica acarreo en el caso de que
haya acarreo de un nibble.
• 1: acarreo del cuarto bit (bit 3) del resultado de la última operación de suma,
pero no en la resta.
• 0: acarreo del cuarto bit (bit 3) del resultado de la última operación de resta,
pero no en la suma.
Bit 2 (flag): Z o bit de Zero (Cero)
• 1: El resultado de la operación lógica es cero
• 0: El resultado de la operación lógica no es cero
Bit 3 (flag): PD o bit de Power Down (Apagado)
• 1: Recién encendido o después de la instrucción CLRWDT, que resetea el
contador WatchDog.
• 0: Después de ejecutar la instrucción SLEEP (Dormir)

Bit 4 (flag): TO o bit de Time Out (Tiempo acabado)


• 1: Recién encendido o después de una instrucción CLRWDT o SLEEP
• 0: Se produjo un reset por el WatchDog Timer.

Bit 5 y 6: RP0 y RP1 o bits de selección de página. Sirven para escoger si se quiere
trabajar en el banco 0 o en el 1. En la figura 39 se detallan sus posibles condiciones, y a
continuación las que se usan comúnmente.
RP0 RP1
- 0 0: Banco de memoria 0 (00h-7Fh)
- 0 1: Banco de memoria 1 (80h-FFh)

Figura 39. Posibles configuraciones de los bits de selección de página. El bit RP1 deberá
ser puesto a cero, ya que si no nos saldríamos del rango de memoria.

Bit 7: bit IRP. Este bit está previsto para un futuro direccionamiento de paginado indirecto,
pero no se utiliza en el 16C84. Tan solo se usa para compatibilidad con las futuras
versiones, por lo que se debe poner a cero.

Alexis Sanchez – aasanchez@gmail.com


El registro FSR o registro de selección de registro (Dirección 04h y 84h)

El contenido del FSR se utiliza para el direccionamiento indirecto. Este registro contiene 8
bits, tamaño suficiente para las versiones actuales del PIC 16CXX; no obstante, es
preciso saber que en direccionamiento indirecto, puede construirse una dirección de 9 bits
utilizando el contenido de este registro y el bit IRP del registro de estado. Esta función no
se utiliza en el 16C84, sino que está prevista para extensiones futuras, de ahí que se
aconseje no usar el bit IRP. Como no es usado en estas versiones, pasaremos este
registro por alto hsata que veamos el direccionamiento indirecto.

Registro PORTA y PORTB (Direcciones 05h y 06h)


Cuando vimos los puertos ya vimos un poco cómo funcionaba este puerte, unque le
dedicamos más atención al registro TRIS. Por ello resumo de nuevo su funcionamiento.
Es muy simple, pues el bit que pongamos a 1 en el registro se reflejará en la patilla
correspondiente; igualmente pasará cuando lo pongamos a 0.

bit 7 6 5 4 3 2 1 bit 0
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0

bit 7 6 5 4 3 2 1 bit 0
RA4 RA3 RA2 RA1 RA0

Aquí todos los bits pueden ser leídos y escritos, excepto los 3 bits más significativos del
puerto A.

Registro EEDATA (Datos de EEPROM) (Dirección 08h)


La posición 07h nos la saltamos, pues no tiene ningún registro contenido.
Esta dirección de memoria guarda el contenido de una posición de memoria EEPROM de
datos antes de su escritura o después de su lectura, según leamos o escribamos en ella.
Para leerla se sigue un proceso especial que comentaré cuando lleguemos a las
instrucciones que hacen uso de ella. Como ya sabemos la memoria EEPROM es bastante
lenta, dato que mantendremos en cuenta cuando accedamos a ella para escribirla, pues
tarda unos 10 ms en completar el proceso.

Registro EEADR (Dirección de EEPROM) (Dirección 09h)


En este registro se guardará la dirección de la posición de memoria EEPROM cuando
queramos acceder a ella, bien para su lectura, o bien para su escritura. El igual que la
dirección anterior, veremos su uso más a fondo cuando lleguemos a las instrucciones que
hacen uso de él. Por otro lado, no hay mucho más que decir.

Registro PCLATH (Contador de Programa Alto) (Dirección 0A y 8A)


El uso de este registro ya lo vimos cuando vimos el PCL y su relación con el PC. Lo
pongo aquí sólo como recordatorio y para no salirnos del orden establecido.

Registro INTCON (Control de Interrupciones) (Dirección 0B y 8B)


Este registro sirve para el control global de las interrupciones y para indicar la procedencia
de algunas de ellas, gracias a los bits de estado. Se dispone de cuatro potenciales
recursos de interrupción:

Alexis Sanchez – aasanchez@gmail.com


- Una fuente externa a través del pin RB0/INT.
- El desbordamiento del temporizador 0 (TMR0).
- Un cambio de estado en los pines RB4 a RB7.
- Programación de la EEPROM de datos.
Cada bit del registro INTCON tiene un significado concreto que se muestra en la siguiente
tabla
bit 7 6 5 4 3 2 1 bit 0
GIE EEIE TOIE INTE RBIE TOIF INTF RBIF
Y la explicación de cada bit viene a continuación:

Bit 0 (flag): RBIF o bit de interrupción del puerto B


- 1: Si se pone a 1, este bit indica un cambio de estado en una de las líneas de
RB4 a RB7 del puerto B.
- 0: Si no, no hay ninguna interrupción

Bit 1 (flag): INTF o bit de interrupción de la Entrada de Interrupción INT


- 1: Si se pone a uno, indica que ha habido una interrupción provocada en la
patilla RBO/INT del puerto B
- 0: Si no, no hay ninguna interrupción

Bit 2 (flag): T0IF o bit de interrupción del Temporizador 0


- 1: Si se pone a uno, este bit indica un desbordamiento del temporizador 0
(TMR0)
- 0: Si no, no ha habido ninguna interrupción.

Bit 3: RBIE o bit de habilitación de las interrupciones del puerto B (RB Interrupt Enable).
- 1: Si se pone a uno este bit, autoriza las interrupciones provocadas por un
cambio de estado de las líneas RB4 a RB7 del puerto B.
- 0: Si se pone a cero, estas interrupciones están deshabilitadas.

Bit 4: INTE o bit de Habilitación de la entrada de Interrupción (Interrupt Enable).


- 1: Si se pone a uno, este bit autoriza las interrupciones provocadas RB0/INT del
puerto B
- 0: Si se pone a cero estas interrupciones están deshabilitadas y cuando se
produzca una interrupción externa el flag correspondiente permanecerá inactivo.

Bit 5: T0IE o bit de habilitación de la interrupción del temporizador por desbordamiento


(Timer 0 Interrupt Enable)
- 1: Si se pone a uno, al igual que las anteriores, este bit autoriza las
interrupciones debidas al desbordamiento del temporizador.
- 0: Si no el flag levantado por el desbordamiento permanecerá inactivo en el
caso de que ocurra

Bit 6: EEIE o bit de habilitación de las Interrupciones del la memoria EEPROM


- 1: Si se pone a 1, este bit permite que se produzcan interrupciones debidas al
fin de escritura de la EEPROM, etc.
- 0: Si se pone a cero este tipo de interrupciones estarán inhibidas

Bit 7: GIE o bit de habilitación global de interrupciones (Global Interrupt Enable)


- 1: Si se pone a uno este bit autoriza todas las interrupciones que estén
enmascaradas mediante sus bits individuales de activación

Alexis Sanchez – aasanchez@gmail.com


- 0: A cero las inhibe.

Cada activador individual debe ponerse a cero por software.


Solamente hay un vector indicador de interrupción (dirección 0004h), por lo que se debe
comprobar estos bits en el programa de interrupción para saber cual es la fuente de la
misma.
Cuando llega una interrupción, el PIC pone el bit GIE a cero, de forma que no se perturbe
el tratamiento de la interrupción en curso, debido a otras interrupciones eventuales. Este
bit se pone automáticamente a uno al terminar el programa de interrupción, con la
ejecución de la instrucción RETFIE.
Los indicadores de interrupciones correspondientes permanecen funcionales incluso
cuando no se han autorizado.
En este caso también pueden leerse y escribirse todos los bits que componen este
registro.

Registro OPTION (o registro de opciones) (Dirección 80h)


Este es el primer registro del banco 1, cuyos registros usaremos menos, pero nos serán
de gran ayuda en determinadas ocasiones. Por ejemplo, este registro sirve para definir
algunos puntos básicos del funcionamiento del PIC.
Los elementos que controla este registro con sus respectivos bits de control vienen
explicados a continuación.

R/W R/W R/W R R R/W R/W R/W


7 6 5 4 3 2 1 0
RBPU INTDEG T0CS T0SE PSA PS2 PS1 PS0

Bits 0, 1 y 2: Bits de configuración del divisor de frecuencia o prescaler. El


funcionamiento de estos bits viene explicado en la siguiente tabla:

PS2 PS1 PS0 División del PS2 PS1 PS0 División del WDT
TMR0
0 0 0 1/2 0 0 0 1/1
0 0 1 1/4 0 0 1 1/2
0 1 0 1/8 0 1 0 1/4
0 1 1 1/ 16 0 1 1 1/8
1 0 0 1 / 32 1 0 0 1 / 16
1 0 1 1 / 64 1 0 1 1 / 32
1 1 0 1 / 128 1 1 0 1 / 64
1 1 1 1 / 256 1 1 1 1 / 128

Bit 3: PSA o bit de asignación del divisor de frecuencia o Prescaler


(Prescaler Assignment).
- 1: El divisor estará asignado al WDT.
- 0: En caso contrario el divisor estará asignado al TMR0

Bit 4: T0SE o bit de tipo de flanco activo (TIMER 0 Signal Edge)


- 1: Si está a 1 el TMR0 se incrementa con el flanco descendente de la señal
aplicada a RA4/T0CK1.
- 0: Si está a cero este se incrementará con el flanco de subida

Alexis Sanchez – aasanchez@gmail.com


BIT 5: T0CS o bit de selección de la fuente de reloj para el contador (registro TMR0)
(TIMER 0 Signal Source)
- 1: En este estado el contador usará la señal aplicada en la patilla RA4/T0CK1
para ser incrementado.
- 0: Si está a cero el temporizador usará el reloj interno, es decir, la frecuencia de
reloj dividida entre cuatro.

Bit 6: INTDEG o bit de selección de tipo de flanco para la entrada de interrupción.


- 1: Si está a uno la entrada RB0/INT será sensible a los flancos ascendentes (o
flancos de subida)
- 0: En caso contrario será sensible a los flancos descendentes (o flancos de
bajada)

Bit 7: RBPU o bit de conexión de resistencias Pull-Up para el Puerto B (RB Pull Up
enable)
- 1: Si está a uno las resistencias permanecen desconectadas
- 0: Si se pone a cero las resistencias se activarán

Como podemos observar, lo normal es que las resistencias se activen ante un 1. Esto es
por que este bit del registro OPTION está negada. Debido a esto, su etiqueta en el
compilador será NOT_RBPU.

El registro TMR0 se incrementa en una unidad con cada impulso de reloj seleccionado
mediante el registro OPTION. Cada vez que llega al valor FF, vuelve a 00 generando una
interrupción, si se ha autorizado, y continúa su ciclo indefinidamente.
El registro TMR0 se puede leer o escribir directamente con cualquier instrucción, con el fin
de conocer su posición actual, o para inicializarlo en un estado determinado. Es
importante saber que después de cualquier escritura en este registro, es necesario un
retardo de dos ciclos de instrucción para que se retome la incrementación. Este retraso es
independiente de la fuente de reloj usada. Las instrucciones concernidas son MOVF
TMR0 o CLRF TMR0.
Para comprobar el paso por cero sin inferir en el desarrollo regular del recuento, es
aconsejable utilizar, por ejemplo, una instrucción MOVF TMR0,W, que no hace mas que
una lectura.
El reloj interno deja de funcionar en el modo SLEEP, por lo que no se puede contar con
sus interrupciones en este modo ni por consiguiente, que salga de este modo de
funcionamiento por medio de dicha interrupción.
Obsérvese que todas las instrucciones que escriben en el TMR0 ponen a cero al
prescaler (divisor), cuando éste está asignado al temporizador.

Registro TRISA y TRISB (85h y 86h)

Después del registro anterior vienen algunos registros del banco 0, que también están
disponibles en el banco 1, pero para mantener la compatibilidad, accederemos a ellos
desde el primero.
Los registros TRISA y TRISB los vimos bastante a fondo cuando estudiamos los puertos,
pero para evitar retroceder hasta entonces, explicaré de nuevo cual y cómo es su
funcionamiento.

Alexis Sanchez – aasanchez@gmail.com


Estos registros son idénticos para el puerto A y el puerto B, con la diferencia de que uno
será de 5 bits y otro de 8 bits, el mismo número de bits que tiene cada puerto.
Los registros TRIS, también son llamados así, sirven para configurar si los bits de cada
puerto serán de entrada o de salida, de acuerdo con la siguiente tabla:

- 1: La patilla del puerto correspondiente será de entrada


- 0: En este caso la patilla actuará como una salida.

Registro EECON1
Este registro contiene configuraciones importantes acerca de la escritura y la lectura de la
EEPROM de datos. En concreto tiene 5 bits de control, cuya distribución y significado es
el siguiente.

7 6 5 4 3 2 1 0
EEIF WRERR WREN WR RD

Bit 0: RD o bit de lectura (Read Data)


- 1: Este bit debe ponerse a uno para poder leer un dato.
- 0: El circuito lo pone automáticamente a cero

Bit 1: WD o bit de escritura (Write Data)


- 1 Este bit debe ponerse a uno para escribir un dato.
- 0: El circuito lo pone automáticamente a cero

Bit 2: WREN o bit de habilitación de escritura. (Write Enable)


- 1: Este bit debe ser habilitado para poder escribir en la EEPROM
- 0: De lo contrario impide cualquier escritura..

Bit 3 (flag): WRERR o flag de error de escritura (Write Error)


- 1: Este bit se pone a 1 si se produce un error de escritura después de una
parada prematura (Reset o Watchdog). En este caso, los contenidos de EEADR y
EEDATA no varían, de manera que el proceso pueda ser repetido correctamente.
- 0: Todo en orden ;).

Bit 4 (flag): EEIF o flag de interrupción de EEPROM ( EEPROM Interrupt Flag)


- 1: Este bit se pone a uno al terminar la escritura en la EEPROM, y debe
ponerse a cero por software
- 0: No hay interrupción alguna.

Registro EECON2
Este registro no está implementado físicamente, por lo cual no se puede leer. Tan sólo
sirve para un proceso de protección de escritura que consiste en copiar en él unos datos
específicos, con el fin de evitar que un programa que tenga un despiste pueda programar
la EEPROM por accidente, manipulando simplemente los bits del EECON1.
Veremos sus aplicaciones cuando lleguemos a la parte de algoritmos sobre la EEPROM.

Alexis Sanchez – aasanchez@gmail.com


EL LENGUAJE ENSAMBLADOR
Introducción

Como ya dije al principio este lenguaje es complejo por su sencillez. Esto quiere decir
que, a diferencia de los lenguajes de alto nivel, aquí no hay funciones que nos solucionen
y simplifiquen el algoritmo, si no que hay que implementar hasta los pasos más
elementales.
Para los PIC se han creado unas instrucciones y una estructura de programa que lo
hacen más sencillo y atractivo todavía. En este apartado veremos la síntesis que tiene
este lenguaje y los elementos que la componen. D

Identificación de elementos del programa en ensamblador


Cada instrucción de un PIC está formada por una palabra de 14 bits y a su vez está
dividida e un tipo de código denominado OPCODE, que especifica el tipo de instrucción, y
uno o más operandos que además especifican la operación de la instrucción. Todo ello
forma un mnemónico o instrucción. Las instrucciones son elementos del lenguaje en
ensamblador que veremos más adelante.
Estos OPCODES o instrucciones se componen de los siguientes tipos de datos. Estos
son abreviaturas usados en el lenguaje ensamblador. Sólo los 6 primeros componen
estos OPCODES.
Como ya he comentado anteriormente, las instrucciones se componen del código de la
instrucción y de algunos operandos, que son los datos con los que la instrucción en sí,
deberá hacer operaciones dentro del microcontrolador. Estos operandos son:

- f Registro de direcciones de registros(file register address) (0x00-0x7F)


- w Registro de trabajo (Working Register)
- b Dirección de un bit dentro de un registro de 8 bits (0-7)
- l ó k Literal
- d Bit de destino
- x Los bits que estén representados por este tipo de dato no tienen ninguna
función y su valor lo define el compilador.

Estos vienen explicados detalladamente a continuación.

- f (file register)

Este carácter se usa para definir registros de cualquier tipo. Cualquier instrucción
que contenga este campo, contendrá la dirección de un registro, no su contenido.
Un registro puede variar entre las direcciones 00h y 7Fh. En el caso de los
registros especiales en vez de la dirección podremos poner directamente el
nombre del registro.
Ej: (ya voy a empezar a poner algunos ejemplos con instrucciones para q nos
vayamos familiarizando)
en vez de:

BSF 03,5
podemos poner:

Alexis Sanchez – aasanchez@gmail.com


BSF STATUS,5

con lo cual habremos pasado de trabajar en el banco 0 al banco 1

- w (working register)

W (w) da nombre al acumulador de los PICs, el cual lo vimos anteriormente


cuando tratamos los registros. Este no es un registro situado en un banco de
memoria, si no que es independiente. A diferencia que el anterior, cuando nos
referimos a él, nos referimos al contenido, no al continente, puesto que el
continente es único, w, y ya viene dado por la instrucción. Su uso es muy sencillo,
pues lo usaremos principalmente para pasar información de un registro a otro, o
para contener la información entre dos o más instrucciones. Es como un
portapapeles, para hacernos una idea ;).

- b (bit addres dentro de un registro)

Esta letra define la dirección de un bit dentro de un byte. En ciertas ocasiones en


vez de modificar o acceder a bytes tendremos que modificar o acceder a bits. De
esta manera podemos especificar a una instrucción que posición ocupa el bit sobre
el cual recaerá la acción que esta ejecute. Al igual que en los registros especiales,
podemos poner directamente el nombre de un bit dentro de un registro.
Ej:
en vez de:

BSF STATUS,5

ponemos:

BSF STATUS,RP0

- l o k (literal)

Este valor será almacenado en la propia instrucción en tiempo de ensamblado,


esto significa que son los valores que nosotros introducimos en las instrucciones
para que trabaje con ellos (independientemente de los datos que podamos
almacenar o contener en la EEPROM de datos). El valor que podemos introducir
dentro de un literal está comprendido entre 0 y 255, ya q es el máximo que puede
representar un byte. No debemos olvidar que este valor debe ser introducido en
hexadecimal. Siendo así, el valor que puede almacenar l está comprendido entre
0 y FF.

- d (destiny bit)

Donde nos encontremos esta letra, deberemos especificar donde se alamacenará


el resultado de una instrucción, en w o en un registro. Puesto que esto no es un
lenguaje de alto nivel, no podemos almacenar el resultado de una operación sobre
una tercera variable o registro, así que este deberá ser almacenado en el registro

Alexis Sanchez – aasanchez@gmail.com


origen (sobrescribiéndose), o en el acumulador. Esto se define a través de dos
valores:
o 1: El resultado se almacenará en f
o 0: El resultado se almacenará en W

- label o etiquetas

Las etiquetas se sitúan a la izquierda de las instrucciones y sirven para agrupar


fragmentos de código. Estos fragmentos pueden ser de dos tipos:
o El primer tipo no es un fragmento tal cual, si no que es un punto del
programa al que podremos saltar de manera incondicional a través de la
instrucción adecuada
o El segundo tipo es denominado subrutina. Este empieza con una etiqueta
y acaba con la instrucción RETURN o RETLW, que veremos más adelante.

Directrices del ensamblador

Las instrucciones más importantes que podemos manejar son las que proporciona el
fabricante de un microprocesador para su producto. Pero existen otras genéricas para
gran cantidad de microcontroladores, que no son para el manejo del PIC, si no del
ensamblador. Estos comandos generalmente se usan para simplificar la tarea de
programar, y reciben el nombre de directrices.
A continuación expongo las más relevantes.

- Directriz EQU

El nombre de esta instrucción viene de la palabra “equal”, o lo que es lo mismo:


“igual”. Sirve para “igualar” la posición de cualquier registro a un nombre
personalizado que le hayamos dado nosotros. Si el nombre es más descriptivo que
una simple dirección, la tarea de programar se hará mucho más sencilla. También
podemos asignar un nombre a una instrucción que repitamos varias veces a lo
largo del algoritmo, de manera que sea mucho más sencillo el tener que
programarlo. A estos nombre que asignamos mediante esta directriz se les
denomina constantes, ya que el registro al que apuntan no variará durante el
programa
Ej:
temp equ 12
DATO EQU 22

Bank_1 EQU BSF STATUS,RP0

Esto es lo que se ha hecho para crear las abreviaturas de los registros antes
expuestas. Estas están contenidas en un fichero que se incluye al principio de
código y del cual hablaremos más tarde (véase apartado Instrucción INCLUDE).

No siempre es necesario que con esta directriz se igualen posiciones de memoria


a las etiquetas, ya que podremos poner nombres a datos. Por ejemplo, podemos
calcular la frecuencia de máquina a partir de la frecuencia de reloj con la finalidad
de emplearla para hacer otros cálculos de la manera que se describe a
continuación:

Alexis Sanchez – aasanchez@gmail.com


clockrate EQU .4000000 ; frecuencia del cristal
fclk EQU clockrate/4 ; frecuencia del reloj interno

Además de esto, podremos igualar a las etiquetas cualquier otro tipo de valores
que usemos, como, por ejemplo, el cero y el 1 en el bit de destino:

W EQU 0
F EQU 1

Generalmente este ejemplo no tendremos que realizarlo, siempre que incluyamos


el fichero correspondiente al PIC con el que estemos trabajando.

- Directriz ORG

Esta directriz dice al ensamblador a partir de que posición de memoria se situarán


las siguientes instrucciones. Recuerda que el 16F84 sólo tiene 1024 posiciones de
memoria flash para código.
Un ejemplo de su uso es el siguiente.

Ej:
Inicia el programa en la posición cero

ORG 0x00

Nos saltamos el vector de interrupción

ORG 0x00 ; El programa comienza en la dirección 0 y


GOTO inicio ; salta a la dirección 5 para sobrepasar
; el vector de interrupción, situado en la posición 4
ORG 0x05
Inicio xxx…..

- Directriz INCLUDE

Esta instrucción índica qué archivos deberán tomarse en cuenta a la hora de


compilar el código. Normalmente se usa para incluir el archivo de PIC que el
ensamblador tiene entre sus archivos, con el cual el compilador será capaz de
reconocer todos los registros especiales y sus bits. Su uso nos recordará al
#include del lenguaje C. Esta línea debe colocarse al principio, y tiene la siguiente
sintaxis:

include "P16F84.INC"

En ciertas ocasiones gran cantidad errores son debidos a que el nombre del
archivo puesto entre comillas no coincide con el que tiene el ensamblador en sus
registros internos. Para suprimirlos basta con poner en la cabecera el nombre de
este archivo.

Alexis Sanchez – aasanchez@gmail.com


Podemos crear archivos con funciones, definiciones y subrutinas que usemos a
menudo en nuestro código, y que para evitarnos tener que copiarlas cada vez,
bastará con incluir el archivo.
El archivo P16F84 contiene, como ya he comentado anteriormente, las
definiciones de los registros, bits y bits de configuración (también llamados fuses).
Con echar un ojo nos bastará para comprender cual es su composición. No
obstante, su inclusión en nuestro programa no es obligatoria, y podemos suprimir
esta directriz, pero a cambio tendremos que redefinir los nombres de los registros
que usemos o bien llamarlos por su posición de memoria.

- Directriz LIST

Este comando sirve para que el compilador tenga en cuenta sobre qué procesador
se está trabajando. Este comando debe estar en todo proyecto, situado debajo del
“include”, con la siguiente sintaxis.

LIST P=16F84

- Directriz END

Al igual que las dos anteriores, esta debe ir incluida una sola vez en todo el
programa. En concreto, esta debe situarse al final, para indicar al ensamblador
que el programa ha finalizado. Esta siempre debe estar presente, aunque el flujo
de nuestro programa acabe en un bucle.

- Directriz #DEFINE

Define se usa para crear pequeñas macros. Con estas macros podremos poner
nombres a pequeños fragmentos de código que nos facilitarán la realización y
comprensión del algoritmo.
Por ejemplo, podremos poner nombres a bits.

# define CERO STATUS,2

Así, en vez de tener que llamar al bit por un numero y un registro, podremos usar
directamente la palabra CERO. Hemos de tener en cuenta que la definición del
ejemplo ya está hecha en el archivo P16F84.inc.
Otro ejemplo muy práctico es el de poner nombre a un fragmento de código usado
frecuentemente. Este fragmento de código, puede ser por ejemplo, el que conmuta
entre los dos bancos.

BSF OPTION,RP0
BCF OPTION,RP0

Como cambiamos varias veces de banco a lo largo de un algoritmo, puede resultar


más práctico ponerle un nombre en vez de la parrafada de arriba.

#define BANCO1 BSF OPTION,RP0


#define BANCO0 BCF OPTION,RP0

Alexis Sanchez – aasanchez@gmail.com


De este modo bastará con poner BANCO1 o BANCO0 para conmutar entre los
dos bancos de memoria.
Una cosa a tener en cuenta es que con la directriz INCLUDE, podemos prescindir
del carácter almohadilla (#), pero en el caso de la directriz DEFINE, no.

- Directriz TITLE

Esta directriz no sirve de mucho, pero será útil para aquellos que quieran que el
compilador tenga en cuenta el título que le ha puesto a su código. Tiene la
siguiente sintaxis:

TITTLE “Nombre del código”

Este nombre aparecerá en los archivos .lst (listados) que cree el compilador.

- Directriz MACRO

A diferencia de la instrucción define, esta directriz permite crear macros más


extensas que #define, que nos evitarán tener que ejecutar reiteradamente
fragmentos de código idénticos. Cuando una macro es invocada, esta es copiada
por el ensamblador en el lugar de la invocación dentro del código fuente. La macro
se declara con la directriz MACRO, y termina con la directriz ENDM.
Ej:

jz MACRO JumpLabel ; Salta aquí


btfsc STATUS, Z ; Pregunta si el
goto JumpLabel ; Flag está a uno
ENDM

; ahora lo invocamos

movf AnyReg, w ; Línea de código


xorwf Constante ; Compara la variable con Constante
jz ThisLabel ; Salta a la macro

Estructura de un programa en ensamblador

Ya hemos estudiado algunas partes del programa en lenguaje ensamblador. Sólo nos
falta conocer la parte más importante: las instrucciones. Pero antes de eso, veremos cual
es la estructura básica de un algoritmo en código ensambladora con la finalidad de ener
claro cual es la estructura de todos los elemento que acabamos de ver. Esto lo veremos
más a fondo cuando veamos todo lo concerniente a la programación.
Esta estructura contiene los siguientes elementos o partes que deben ser codificadas:
- Comentario descriptivo del programa (opcional, pero recomendable)
- Definir el microcontrolador que se usará (con las directrices LIST e INCLUDE).
- Introducir las opciones de compilación (que serán vistas más
adelante)(opcional)
- Establecer las constantes que se usarán (con la directriz EQU).

Alexis Sanchez – aasanchez@gmail.com


- Reservar espacios de memoria (directriz RES) (si es necesario)
- Configurar los puertos
- Desarrollar el programa
- Poner comentarios

Y su estructura es:

Figura 41. Esquema de un programa

Hemos visto la estructura general. Ahora veremos la posición de los elementos del código
por columnas. Estas se dividen en cuatro:

- Columna 1: Etiqueta. Las etiquetas se rigen por las siguientes normas:


· Debe situarse en la primera columna

Alexis Sanchez – aasanchez@gmail.com


· Debe contener únicamente caracteres alfanuméricos
· El máximo de caracteres es de 31

- Columna 2: Operación. En esta columna se situarán las instrucciones

- Columna 3: Son los registros (f, l o k , b y w) donde se almacenarán los


resultados y con los que se operará

- Columna 4: Comentario. Aquí se situará cualquier comentario personalizado


que deseemos. Estos son útiles para saber qué hace un programa sin tener que
descifrar el código entero. El compilador (ensamblador) ignorará todo texto más
allá del carácter punto y coma “;”. Estos comentarios generalmente se sitúan en la
cuarta columna para describir la acción de una línea de código, pero pueden
situarse en cualquier parte de programa para describir cualquier otro evento,
siempre que estén después del carácter “;” (semicolon en inglés).
Veamos más detenidamente cual es su posición:

Figura 42. Esquema de un programa por columnas

Normalmente las columnas son separadas por una tabulación. El espacio mínimo entre
dos columnas es de un carácter, que puede ser un espacio en vez de una tabulación

LAS INTRUCCIONES DEL PIC 16F84


Alexis Sanchez – aasanchez@gmail.com
Introducción
Ya llegamos a la parte más interesante e importante del manejo de un microcontrolador:
las instrucciones. Nuestro microcontrolador, como ya sabemos, pertenece a la gama
media y es de tipo RISC; esto quiere decir que tiene un juego de instrucciones reducido,
en concreto de 35. Estas 35 instrucciones o nemónicos (del inglés mnemonics(os
recuerda a la película ;) ?) y a su vez proveniente del juego de palabras: Nem On Icks)
serán la base de funcionamiento del PIC. Al igual que los bits de los registros, será
imposible aprendernos todas y a la vez su funcionamiento, pero a la hora de codificar
nuestros programas deberemos tenerlas en cuenta. Así, cuando tengamos dudas sobre
su uso, esta guía será la chuleta ideal para recordarlo ;p.
Las instrucciones fundamentalmente se dividen en tres tipos. Esta división viene dada por
el tipo de datos con los que trabajan:

• Instrucciones orientadas a los bytes (byte-oriented operations)


• Instrucciones orientadas a los bits (bit-oriented operations)
• Operaciones con literales y de control (literal and control operations)

Aparte de estas instrucciones, hay otro tipo de instrucciones usadas para simplificar la
tarea de programar, y q generalmente están formadas por dos instrucciones básicas.
Estas no las trataremos a fondo, pero las veremos en un resumen después de
comprender el funcionamiento de las 35 instrucciones básicas.
En los tres apartados siguientes veremos todos los datos que se pueden dar acerca de
una función. Algunos de ellos son irrelevantes y no son nuestro objetivo. En cambio otros,
como la acción, la sintaxis, el funcionamiento, la operación, el comportamiento del registro
STATUS y los ejemplos, son imprescindibles para comprender su funcionamiento.

INSTRUCCIONES ORIENTADAS AL MANEJO DE BYTES (REGISTROS)

ADDWF

Acción Suma el contenido del acumulador y el registro dado, y el


resultado lo guarda en d
Sintaxis ADDWF f,d
Funcionamiento Add W to file register (Añade W al registro)
Operación d = W + f (d puede ser W ó f).
Descripción Esta instrucción suma el contenido de un registro específico al
contenido de W donde f puede ser un registro cualquiera con un
determinado valor.
Comentarios Aunque ya conocemos el funcionamiento del bit d, lo repetiré de
nuevo para el resto de instrucciones:
- Si vale 1, el resultado se guarda en el registro f
- Si vale 0, el resultado se guarda en el acumulador W
Registro Modifica los bits Z, DC y C.
STATUS • Z vale 1 si el resultado de la operación es 0.
• DC vale 1 si el resultado de la operación es un número
superior a 15.
• C vale 1 si el resultado de la operación es positivo o el bit 7
del registro que contiene el resultado vale 0. En caso
contrario C vale 0 (resultado negativo).

Alexis Sanchez – aasanchez@gmail.com


Ejemplo Tomamos como valores iniciales W = 5 y DATO = 10, donde dato
es un registro cualquiera.

ADDWF DATO ; DATO = 15 y W = 5.


ADDWF DATO, 1 ; DATO = 15 y W = 5.
ADDWF DATO, 0 ; W = 15 y DATO = 10.
ADDWF DATO, W ; W = 15 y DATO = 10.

ANDWF

Acción Realiza la operación AND entre un registro y W


Sintaxis ANDWF f,d
Bits (OPCODE) 00 0101 dfff ffff
Operación d = W AND f (d puede ser W o f).
Descripción Esta instrucción realiza la operación lógica AND entre el
acumulador y el registro f. el resultado se guarda dependiendo del
valor de d. Si este se omite, el valor por defecto es 1 y se guarda
en f
Comentarios La operación AND es una de las operaciones básicas del álgebra
de Boole. Esta viene descrita en el apartado de electrónica digital.
Para comprender de nuevo cual es su comportamiento, recojo en
la siguiente tabla los valores de la tabla de verdad de esta
operación.

ENTRADA SALIDA
f W S
0 0 0
0 1 0
1 0 0
1 1 1

La operación lógica es:


S=f·W
Esta instrucción realiza esta operación para cada uno de los 8 bits
de los dos registros, dos a dos, guardando el resultado en el
registro correspondiente.
Registro Modifica el bit Z.
STATUS • Z vale 1 si el resultado de la operación es 0.
Ejemplo 1 Supongamos que W= 00001111 y f = 11110000 antes de ejecutar
la instrucción ANDWF f,d
ENTRADA RESULTADO
W f W·f
Bit 7 0 1 0
Bit 6 0 1 0
Bit 5 0 1 0
Bit 4 0 1 0
Bit 3 1 0 0
Bit 2 1 0 0

Alexis Sanchez – aasanchez@gmail.com


Bit 1 1 0 0
Bit 0 1 0 0
Ejemplo 2 Ahora en nuestro segundo ejemplo tenemos que W = 01110011 y
f = 00101001 antes de ejecutar la instrucción ANDWF f,d
tenemos:
ENTRADA RESULTADO
W f W·f
Bit 7 0 0 0
Bit 6 1 0 0
Bit 5 1 1 1
Bit 4 1 0 0
Bit 3 0 1 0
Bit 2 0 0 0
Bit 1 1 0 0
Bit 0 1 1 1

CLRF

Acción Borra un registro


Sintaxis CLRF f
Bits (OPCODE) 00 0001 1fff ffff
Operación F=0
Descripción Esta instrucción borra un registro específico, poniendo sus bits a
cero
Registro Modifica el bit Z y lo pone a 1 (ya que el resultado de la operación
STATUS es 0).
Ejemplo Tenemos un registro que se llama dato y que vale 3F. Ponemos:
CLRF dato
Ahora dato vale 00

CLRW

Acción Borra el acumulador


Sintaxis CLRW
Funcionamiento Clear W
Operación W=0
Descripción Esta instrucción borra el registro W solamente
Comentarios Donde pone xxx… en la instrucción en hexadecimal, significa que
noo importa qué valor puede contener
Registro Modifica el bit Z y lo pone a 1 (ya que el resultado de la operación
STATUS es 0).
Ejemplo Tenemos el acumulador cargado con el valor 3F. Ponemos:
CLRF dato
Ahora W vale 00

COMF

Alexis Sanchez – aasanchez@gmail.com


Acción Complementa el registro F
Sintaxis COMF f,d
Funcionamiento Complement f
Operación d = NOT f (d puede ser W ó f).
Descripción Esta instrucción complementa un registro, es decir, los ceros los
convierte en unos, y los unos en ceros.
Registro Modifica el bit Z.
STATUS • Z vale 1 si el resultado de la operación es 0.
Ejemplo Supongamos que tenemos un registro fdenominado regist =
00111011; cuando es aplicada la instrucción tenemos que los 0
cambian a valores 1 y los valores 1 cambian a 0 obteniéndose un
registro invertido. El resultado será regist = 11000100.

DECF

Acción Decrementa el registro f


Sintaxis DECF f,d
Funcionamiento Decrement f
Operación d = f – 1 (d puede ser W ó f).
Descripción Esta instrucción decrementa en una sola unidad el registro "f".
Registro Modifica el bit Z.
STATUS • Z vale 1 si el resultado de la operación es 0.
Ejemplo Nuestro registro se llama regist = 5; cuando se aplica la
instrucción DECF f,0 el resultado será W=4.
Por el contrario, si aplicamos la instrucción DECF f,1 el resultado
será regist = 4.

DECFSZ

Acción Decrementa el registro f, y si el resultado es cero, se salta una


instrucción.
Sintaxis DECFSZ f,d
Funcionamiento Decrement f, skip if 0
Operación d = f – 1, si d = 0 SALTA (d puede ser W ó f).
Descripción Esta instrucción decrementa el contenido del registro direccionado
por el parámetro f, y si el resultado es 0 salta la instrucción
siguiente. Si no, sigue con su curso habitual
Comentarios Aquí nos enfrentamos ante la primera instrucción que plantea una
condición, y que modifica el curso del PC.
Registro No modifica ningún bit de estado
STATUS
Ejemplo DECFSZ VALOR, W
INSTRUCCION 1
INSTRUCCIÓN 2

Si el contenido del registro VALOR al decrementarlo es igual a 0,


se guarda el resultado en el acumulador y sigue con la
INSTRUCCION2, saltándose la INSTRUCCION1.

Alexis Sanchez – aasanchez@gmail.com


Si el resultado que guardamos en W no es 0, sigue con la
INSTRUCCION1 y después con la INSTRUCCION2 (no se salta la
inmediata siguiente).

INCF

Acción Suma una unidad al registro f


Sintaxis INCF f,d
Funcionamiento Increment f
Operación d = f + 1 (d puede ser W ó f).
Descripción Esta instrucción incrementa en una sola unidad el registro "f".
Registro Modifica el bit Z.
STATUS • Z vale 1 si el resultado de la operación es 0.
Ejemplo Si tenemos un registro llamado DIA = 7.
Aplicando la instrucción
INCF DIA, 0, tendremos W = 8 y DIA = 7.
Si aplicamos esta otra
INCF DIA, 1, tendremos DIA = 8.

INCFSZ

Acción Incrementa en 1 a f, y si f= 0 salta la siguiente instrucción


Sintaxis INCFSZ f,d
Funcionamiento Increment f, Skip if 0
Operación d = f + 1, si d = 0 SALTA (d puede ser W ó f).
Descripción Esta instrucción incrementa en una sola unidad el registro "f", en
la cual si el resultado “d” es igual a cero, entonces salta la
instrucción siguiente.
Registro No modifica ningún bit de estado.
STATUS
Ejemplo Ejecutamos las siguiente sinstrucciones:

INCFSZ VALOR, W ; el resultado se almacenará en W


INSTRUCCION 1 ; salta aquí si W≠0
INSTRUCCIÓN 2 ; salta aquí si W=0

Si el contenido del registro VALOR es igual a 0 al incrementarlo en


una unidad, se guarda el resultado en el acumulador y sigue con
la INSTRUCCION2, saltándose la INSTRUCCION1.
Si el resultado que guardamos en W no es 0, sigue con la
INSTRUCCION1 y después con la INSTRUCCION2 (no se salta la
inmediata siguiente).

IORWF

Alexis Sanchez – aasanchez@gmail.com


Acción Operación lógica OR entre el acumulador y un registro
Sintaxis IORWF f,d
Funcionamiento Inclusive Or W with F
Operación d = W OR f (d puede ser W ó f).
Descripción Esta instrucción realiza una operación lógica OR inclusivo entre el
acumulador W y el registro direccionado por el parámetro f. El
parámetro d determina donde se almacenará el resultado de la
operación. Si no se pone nada, el valor por defecto es 1 y se
guarda en f.
Comentarios La operación OR inclusivo suele llamarse OR a secas, pero se
pone así para diferenciarla de la Suma Exclusiva que veremos
más adelante. La tabla de verdad de la suma lógica es la que
sigue:
ENTRADA SALIDA
f W S
0 0 0
0 1 1
1 0 1
1 1 1

La operación lógica que describe esta instrucción es esta:


F+W=S
Se puede ver que basta con que uno de los dos registros tenga un
uno para que la salida sea un uno también.
Registro Modifica el bit Z.
STATUS • Z vale 1 si el resultado de la operación es 0.
Ejemplo 1 Supongamos que W= 00001111 y f = 11110000 antes de ejecutar
la instrucción IORWF f,d, y después obtenemos:

ENTRADA RESULTADO
W f W+f
Bit 7 0 1 1
Bit 6 0 1 1
Bit 5 0 1 1
Bit 4 0 1 1
Bit 3 1 0 1
Bit 2 1 0 1
Bit 1 1 0 1
Bit 0 1 0 1
Ejemplo 2 En este segundo ejemplo tenemos que W = 01110011 y f =
ENTRADA RESULTADO

00101001, antes de ejecutar la instrucción IORWF f,d, y después


obtenemos que:

Alexis Sanchez – aasanchez@gmail.com


W f W+f
Bit 7 0 0 0
Bit 6 1 0 1
Bit 5 1 1 1
Bit 4 1 0 1
Bit 3 0 1 1
Bit 2 0 0 0
Bit 1 1 0 1
Bit 0 1 1 1

Al igual que el caso anterior, el microcontrolador compara bit a bit


los dos registros, dos a dos, obteniendo el resultado expresado
en W + f

MOVF

Acción Mueve el contenido de un registro al acumulador o al propio


registro
Sintaxis MOVF f,d
Funcionamiento Move f
Operación d = f (d puede ser W ó f).
Descripción Esta instrucción mueve el contenido del registro f en el mismo
registro f o en W. D determina el destino del resultado. Si no se
pone nada, el valor por defecto es 1 y se guarda en f.
Comentarios Se suele usar para mover datos al acumulador. El hecho de que
se pueda mover sobre sí mismo no es otro que para mirar el
resultado en el registro STATUS (no es ninguna tontería ;))
Registro Modifica el bit Z.
STATUS • Z vale 1 si el resultado de la operación es 0.
Ejemplo Tenemos el registro EDAD = 38

MOVF EDAD, 0 ; hace que W = 38.


MOVF EDAD, 1 ; hace que EDAD = 38.
MOVF EDAD, W ; hace que W = 38.
MOVF EDAD ; hace que EDAD = 38.

MOVWF

Acción Mueve el acumulador al registro f


Sintaxis MOVWF f
Funcionamiento Move W to f
Operación f=W
Descripción Esta instrucción copia el contenido del acumulador W en el
registro direccionado por el parámetro f.

Alexis Sanchez – aasanchez@gmail.com


Comentarios No existe el parámetro d (lógico, o no? En este caso no se puede
copiar el acumulador sobre sí mismo :p )
Registro No modifica ningún bit de estado.
STATUS
Ejemplo Si queremos escribir el valor 10H en el registro TMR0, que está
situado en la dirección 01h, tendremos que cargar primero el valor
en elacumulador y después copiarlo al registro.

MOVWF 10H ; cargar el valor 10H en el acumulador.


MOVWF 01H ; copia el acumulador en la dirección 01H.

O escrito de otra manera:

MOVWF 10H ; cargar el valor 10H en el acumulador.


MOVWF TMR0 ; copia el acumulador en el registro TMR0.

NOP

Acción No opera
Sintaxis NOP
Funcionamiento No Operation
Operación Ninguna
Descripción Esta instrucción no reliza ninguna ejecución, pero sirve para
gastar un ciclo de máquina, equivalente a 4 de reloj
Registro No modifica ningún bit de estado.
STATUS
Ejemplo Si usamos un cristal de cuarzo de 4 Mhz. en el oscilador,
podremos obtener un retardo igual a un microsegundo por cada
instrucción NOP que insertemos en el código del programa:
RETARDO NOP
NOP
NOP
RETURN
Cada vez que llamemos a la subrutina RETARDO, obtendremos 3
microsegundos de demora.

RLF

Acción Rota a la izquierda el registro f


Sintaxis RLF f,d
Funcionamiento Rotate Left through Carry f
Operación d = << 1 (d puede ser W ó f).
Descripción Esta instrucción rota a la izquierda todos los bits del registro
direccionado por el parámetro fpasando por el bit CARRY del
registro STATUS(desde los bits menos significativos a los más
significativos).
Es como si multiplicáramos por dos el contenido del registro.
Veamos el registro fde forma gráfica:

Alexis Sanchez – aasanchez@gmail.com


El bit D7 pasa al CARRY del registro STATUS, el contenido
delCARRY pasa al D0, el D0 al D1, etc.
Registro Modifica el bit C (CARRY).
STATUS
Ejemplo Tenemos el registro VALOR = 00000001 y aplicamos la
instrucción

RLF VALOR

Entonces el resultado será VALOR = 00000010 y el bit C = 0.

Si tenemos el registro VALOR = 10000000 y aplicamos la


instrucción

RLF VALOR

El resultado será VALOR = 00000000 y el bit C = 1.


Ciclos de 1
máquina

RRF

Acción Rota a la derecha el registro f


Sintaxis RRF f,d
Funcionamiento Rotate Right through Carry f
Operación d = f >> 1 (d puede ser W ó f).
Descripción Esta instrucción rota a la derecha todos los bits del registro
direccionado por el parámetro fpasando por el bit CARRY del
registro STATUS(desde los bits más significativos a los menos
significativos).
Es como si dividiéramos por dos el contenido del registro.
Veamos el registro fde forma gráfica:

El bit C del registro STATUS pasa al D7, el D0 pasa al bit C, el D1


al D0, etc.
El bit d determina el destino del resultado. Si no se pone nada, el
valor por defecto es 1 y se guarda en f.

Alexis Sanchez – aasanchez@gmail.com


Registro Modifica el bit C (CARRY).
STATUS
Ejemplo Si tenemos el registro VALOR = 00000001 y aplicamos la
instrucción

RRF VALOR

Entonces el resultado será VALOR = 00000000 y el bit C = 1.

Si tenemos el registro VALOR = 10000000 y aplicamos la


instrucción

RRF VALOR

El resultado será VALOR = 01000000 y el bit C = 0.

SUBWF

Acción Resta el contenido del registro W el registro f


Sintaxis SUBWF f,d
Funcionamiento Subtract W from f
Operación d = f – W (d puede ser W ó f).
Descripción Esta instrucción resta el valor contenido en el acumulador W del
valor contenido en el registro direccionado por el parámetro f. El
parámetro ddetermina el destino. Si no se pone nada el valor por
defecto será 1 y se almacenará en f.
Registro Modifica los bits Z, DC y C.
STATUS • Z vale 1 si el resultado de la operación es 0.
• DC vale 1 si el resultado de la operación es un número
superior a 15.
C vale 1 si el resultado de la operación es positivo o el bit 7 del
registro que contiene el resultado vale 0. En caso contrario C vale
0 (resultado negativo).
Ejemplo Según sean los valores de W y el registro DATO, si aplicamos
SUBWF DATO
obtendremos diferentes resultados en el bit CARRY.

Si DATO = 3 y W = 2; el resultado será DATO = 1 y C = 1.


Si DATO = 2 y W = 2; el resultado será DATO = 0 y C = 1.
Si DATO = 1 y W = 2; el resultado será DATO = FFH y C = 0.
Vemos que C = 1 porque el resultado es positivo y C = 0 cuando
el resultado es negativo.

SWAPF

Acción Invierte los dos nibbles que forman un byte dentro de un


registro
Sintaxis SWAPF f,d
Funcionamiento Swap nibbles in f

Alexis Sanchez – aasanchez@gmail.com


Operación f = 0123 SWAP 4567 de f
Descripción Esta instrucción intercambia el valor de los 4 bits más
significativos (D7-D4) contenidos en el registro f, con los 4 bits
menos significativos (D3-D0) del mismo. El parámetro d determina
el destino. Si no se pone nada, el valor por defecto es 1 y se
guarda en f.
Registro No modifica ningún bit de estado.
STATUS
Ejemplo Tenemos VALOR = 00001111 y W = 00000000. Aplicamos la
instrucción SWAPF

SWAPF VALOR ; VALOR = 11110000B y W = 00000000B.


SWAPF VALOR, W ; VALOR = 00001111B y W = 11110000B.

Con la primera instrucción modificamos el valor del registro DATO,


y en la segunda instrucción modificamos el valor
del acumulador sin que varíe el registro DATO

XORWF

Acción Operación lógica OR-Exclusiva


Sintaxis XORWF f,d
Funcionamiento Exclusive OR W with f
Operación d = W OR f
Descripción Esta instrucción efectúa la operación lógica XOR (OR exclusivo)
entre el valor contenido en el acumulador W y el valor contenido
en el registro direccionado por el parámetro f. El
parámetro d determina el destino. Si no se pone nada el valor por
defecto es 1 y se guarda en f
Comentarios Al igual que las otras operaciones lógicas, la suma exclusiva está
tratada en el capítulo de electrónica digital. No obstante expongo
las tablas de verdad correspondientes a esta operación

ENTRADA SALIDA
f W S
0 0 0
0 1 1
1 0 1
1 1 0

La salida únicamente se podrá a nivel alto cuando las dos


entradas sean distintas. Esto es útil cuando tenemos una suma
lógica en la que 1 + 1 es 10 y nos llevamos 1.
Esta operación algebraicamente se expresa así:

S=f+W

Registro Modifica el bit Z.


STATUS Z vale 1 si el resultado de la operación es 0.

Alexis Sanchez – aasanchez@gmail.com


Ejemplo 1 Tenemos dos registros que se corresponden con los siguientes
valores W= 00001111 y f = 11110000 antes de ejecutar la
instrucción XORWF f,d. Una vez ejecutada obtenemos la siguiente
tabla de verdad sobre los dos registros:
ENTRADA RESULTADO
W f W+f
Bit 7 0 1 1
Bit 6 0 1 1
Bit 5 0 1 1
Bit 4 0 1 1
Bit 3 1 0 1
Bit 2 1 0 1
Bit 1 1 0 1
Bit 0 1 0 1

El PIC compara dos a dos los bits de los registros


Ejemplo 2 Ahora W = 01110011 y f = 00101001 antes de ejecutar la
instrucción XORWF f,d y después obtenemos:
ENTRADA RESULTADO
W f W+f
Bit 7 0 0 0
Bit 6 1 0 1
Bit 5 1 1 1
Bit 4 1 0 1
Bit 3 0 1 1
Bit 2 0 0 0
Bit 1 1 0 1
Bit 0 1 1 0

Alexis Sanchez – aasanchez@gmail.com


INSTRUCCIONES ORIENTADAS AL MANEJO DE BITS

BCF

Acción Pone a cero el bit b del registro f


Sintaxis BCF f,b
Funcionamiento Bit Clear f
Operación F(b) = 0
Descripción Esta instrucción pone a cero un bit que hayamos elegido de un
registro determinado.
Comentarios No debemos olvidar que en la numeración de los bits también se
tiene en cuenta el 0. Si tratamos con un registro especial,
podemos poner el nombre del bit correspondiente.
Registro No modifica ningún bit de estado.
STATUS
Ejemplo BCF PORTA, RA4 ; pone a 0 el bit RA4 del registro PORTA
BCF PORTA, 4 ; igual, si no conocemos en nombre del
bit

Si en el PORTA tenemos como valor inicial 11111111, después de


aplicar el ejemplo anterior, PORTA = 11101111.
BSF
Acción Pone a uno el bit b del registro f
Sintaxis BSF f,b
Funcionamiento Bit Set f
Operación F(b) = 1
Descripción Esta instrucción pone a uno un bit que hayamos elegido de un
registro determinado.
Registro No modifica ningún bit de estado.
STATUS
Ejemplo BSF PORTA, RA0 ; pone a 1 el bit RA0 del registro PORTA
BSF PORTA, 0 ; igual, si no conocemos en nombre del
bit

Si en el PORTA tenemos como valor inicial 00000000, después de


aplicar el ejemplo anterior, PORTA = 00000001.

BTFSC

Acción Comprueba un bit b del registro f, y salta la instrucción


siguiente si este es cero
Sintaxis BTFSC f,b
Funcionamiento Bit Test, Skip if Clear
Operación F(b) = 0? SI, salta una instrucción
Descripción Esta instrucción comprueba el valor del bit b en el registro f, y si b
= 0 entonces se salta la siguiente instrucción. Si b = 1 no salta y
sigue con su ejecución normal.

Alexis Sanchez – aasanchez@gmail.com


Registro No modifica ningún bit de estado
STATUS
Ejemplo BTFSC PORTA, 2
INSTRUCCIÓN 1
INSTRUCCIÓN 2

Si en PORTA tenemos como valor inicial 11111011, el programa


continúa con la instrucción 2, saltándose la instrucción 1
Si en PORTA tenemos el valor 00000100, el programa sigue con
la instrucción 1 y después la instrucción 2

BTFSS

Acción Comprueba un bit b del registro f, y salta la instrucción


siguiente si este es uno
Sintaxis BTFSC f,b
Funcionamiento Bit Test, Skip if Set
Operación F(b) = 1? SI, salta una instrucción
Descripción Esta instrucción comprueba el valor del bit b en el registro f, y si b
= 1 entonces se salta la siguiente instrucción. Si b = 0 no salta y
sigue con su ejecución normal.
Registro No modifica ningún bit de estado
STATUS
Ejemplo BTFSS PORTB, 7
INSTRUCCIÓN 1
INSTRUCCIÓN 2

Si en PORTB tenemos como valor inicial 10000000, el programa


continúa con la instrucción 2, saltándose la instrucción 1. Si
tenemos el valor 01111111, el programa sigue con la instrucción 1
y después la instrucción 2.

Alexis Sanchez – aasanchez@gmail.com


OPERACIONES CON LITERALES Y DE CONTROL

ADDLW

Acción Suma a W un literal


Sintaxis ADDLW
Funcionamiento Add literal to W
Operación W=W+k
Descripción Esta instrucción suma un valor de un literal al contenido del
registro W y lo guarda en W.
Comentarios Es igual que su homologo manejando registros
Registro Modifica los bits Z, DC y C.
STATUS • Z vale 1 si el resultado de la operación es 0.
• DC vale 1 si el resultado de la operación es un número
superior a 15.
• C vale 1 si el resultado de la operación es positivo o el bit 7
del registro que contiene el resultado vale 0. En caso
contrario C vale 0 (resultado negativo).
Ejemplo MOVLW 3 ; carga el acumulador W con el valor 3.
ADDLW 1 ; suma 1 al acumulador.
Al final el acumulador tendrá el valor 4.

ANDLW

Acción Realiza la operación AND entre un literal y W


Sintaxis ANDLW k
Funcionamiento AND W with k
Operación W = W AND k
Descripción Esta instrucción realiza una operación lógica AND entre el
contenido deW y k. El resultado se guarda siempre en el
acumulador W
Registro Modifica el bit Z.
STATUS • Z vale 1 si el resultado de la operación es 0.
Ejemplo Si cargamos el acumulador con el número binario 10101010 y
hacemos un AND con el binario 11110000, nos quedará el
resultado de la operación en el acumulador W.
MOVLW 10101010
ANDLW 11110000
El resultado de la operación queda en W = 10100000.

CALL

Acción Llama a una subrutina en la dirección k


Sintaxis CALL k
Funcionamiento Call subroutine
Operación CALL k...RETURN PC+1.
Descripción Esta instrucción llama a un grupo de instrucciones (subrutina) que

Alexis Sanchez – aasanchez@gmail.com


comienzan en la dirección k, donde k puede ser un valor numérico
o una etiqueta. Siempre termina con la instrucción de retorno
(RETURN oRETLW).
Definición de subrutina: son un grupo de instrucciones que forman
un programa dentro del programa principal y que se ejecutan
cuando las llama el programa principal.
Utilidad: sirven para utilizarlas varias veces en cualquier parte del
programa, sin necesidad de tener que copiar las mismas
instrucciones, con el consiguiente ahorro de memoria.
Funcionamiento: cuando un programa ejecuta una
instrucción CALL, guarda en el stack el valor del
registro PC+1 (PC = Program Counter) de manera que al regresar
de la subrutina continúa con la instrucción siguiente recuperándola
del stack, ejecutando la instrucción de retorno RETURN oRETLW.

Limitaciones: en el PIC16F84 tenemos disponibles 8 niveles


de stack, por lo que el número máximo de CALL reentrantes
(instrucciones CALL que contengan otra instrucción CALL) queda
limitado a 8.
Comentarios Definición de subrutina: son un grupo de instrucciones que forman
un programa dentro del programa principal y que se ejecutan
cuando las llama el programa principal.
Utilidad de las subritunas: sirven para utilizarlas varias veces en
cualquier parte del programa, sin necesidad de tener que copiar
las mismas instrucciones, con el consiguiente ahorro de memoria.
Funcionamiento: cuando un programa ejecuta una
instrucción CALL, guarda en el stack el valor del
registro PC+1 (PC = Program Counter) de manera que al regresar
de la subrutina continúa con la instrucción siguiente recuperándola
del stack, ejecutando la instrucción de retorno RETURN oRETLW.

Limitaciones: en el PIC16F84 tenemos disponibles 8 niveles


de stack, por lo que el número máximo de CALL reentrantes
(instrucciones CALL que contengan otra instrucción CALL) queda
limitado a 8.
Registro No modifica ningún bit de estado.
STATUS
Ejemplo PRINCIPAL: etiqueta que identifica una dirección de memoria.
RETARDO: etiqueta que identifica el comienzo de una subrutina.
BUCLE: etiqueta que identifica una dirección de memoria.

PRINCIPAL CALL RETARDO


BTFSC PORTB, RB0
GOTO PRINCIPAL
*
*
*
RETARDO CLRF CONTADOR
BUCLE DECFSZ CONTADOR, 1
GOTO BUCLE
RETURN

Alexis Sanchez – aasanchez@gmail.com


En este listado vemos que la subrutina RETARDO salta a un
grupo de instrucciones que forman un bucle y cuando éste termina
regresa para seguir con la instrucción siguiente al salto
(BTFSC...).

CLRWDT

Acción Pone el temporizador WDT a cero.


Sintaxis CLRWDT
Funcionamiento Clear WatchDog Timer
Operación WDT = 0
Descripción Esta instrucción se utiliza cuando programamos el PIC con la
opción Watch Dog habilitada. Para evitar el reset del PIC, el
programa debe contener cíclicamente la
instrucción CLRWDT para ponerlo a cero. Si no se pone a cero a
tiempo, el WDT interpretará que se ha bloqueado el programa y
ejecutará un reset para desbloquearlo.
Registro No modifica ningún bit de estado.
STATUS
Ejemplo Bucle CLRWDT
*
*
*
GOTO Bucle

GOTO

Acción Salto incondicional a k.


Sintaxis GOTO k
Funcionamiento Go to address (label)
Operación Salto k
Descripción Esta instrucción ejecuta un salto del programa a la dirección k. El
parámetro k puede ser un valor numérico o una etiqueta.
Registro No modifica ningún bit de estado.
STATUS
Ejemplo INSTRUCCIÓN 1
GOTO ABAJO
INSTRUCCIÓN 3
INSTRUCCIÓN 4
INSTRUCCIÓN 5
ABAJO INSTRUCCIÓN 6

Primero se ejecuta la instrucción 1, después GOTO y continúa con


la instrucción 6 saltándose las instrucciones 3, 4 y 5.

Alexis Sanchez – aasanchez@gmail.com


IORLW

Acción Operación lógica OR entre el acumulador y un literal


Sintaxis IORWF f,d
Funcionamiento Inclusive OR W with l
Operación W = W OR l
Descripción Esta instrucción realiza una operación lógica OR inclusivo entre el
acumulador W y un literal. El resultado siempre se guarda en el
acumulador.
Comentarios La operación OR inclusivo suele llamarse OR a secas, pero se
pone así para diferenciarla de la Suma Exclusiva que veremos
más adelante. La tabla de verdad de la suma lógica es la que
sigue:

ENTRADA SALIDA
f W S
0 0 0
0 1 1
1 0 1
1 1 1

La operación lógica que describe esta instrucción es esta:


F+W=S
Se puede ver que basta con que uno de los dos registros tenga un
uno para que la salida sea un uno también.
Registro Modifica el bit Z.
STATUS • Z vale 1 si el resultado de la operación es 0.
Ejemplo Supongamos que W= 00001111 y l = f0. Ejecutanado la
instrucción IORWF f,d, obtenemos:

ENTRADA RESULTADO
W l W+l
Bit 7 0 1 1
Bit 6 0 1 1
Bit 5 0 1 1
Bit 4 0 1 1
Bit 3 1 0 1
Bit 2 1 0 1
Bit 1 1 0 1
Bit 0 1 0 1

MOVLW

Acción Copia el contenido de un literal al acumulador


Sintaxis MOVLW f
Funcionamiento Move literal to W
Operación W=f

Alexis Sanchez – aasanchez@gmail.com


Descripción Esta instrucción asigna al acumulador W el valor del literal k, el
cual debe estar comprendido entre 0 y 255.
Comentarios Ninguno
Registro No modifica ningún bit de estado.
STATUS
Ejemplo Si tenemos el acumulador a cero o con cualquier valor, y
queremos que contenga el que le asignemos nosotros
directamente entonces usaremos esta instrucción:
W = 0.
Valor a asignar = 100.
Instrucción: MOVLW 100
El acumulador valdrá 100 (W = 100).

Con distinto valor de partida del acumulador:


W = 225.
MOVLW 100
El acumulador valdrá 100 (W = 100).

RETFIE

Acción Retorno de la llamada a una subrutina


Sintaxis RETFIE
Funcionamiento Return From Interrupt
Operación FIN INTERRUPCIÓN
Descripción Esta instrucción devuelve el control al programa principal después
de ejecutarse una subrutina de gestión de una interrupción.
Comentarios Ninguno
Registro No modifica ningún bit de estado
STATUS
Ejemplo ORG 00H
BUCLE GOTO BUCLE; bucle infinito.
ORG 04H; vector de interrupción.
RETFIE ; retorna de la interrupción

Este código de programa ejecuta un bucle infinito. Si habilitamos


una de las interrupciones del 16F84, en cuanto ésta se produzca
pasará el control al programa situado en la dirección 04h y la
instrucción RETFIE regresa de la interrupción.
Al ejecutarse una interrupción, el bit GIE del registro INTCON se
pone a 0 y así evita que otra interrupción se produzca mientras ya
está con una en marcha.
Con la instrucción RETFIE ponemos de nuevo el bit GIE a 1 para
así atender de nuevo a futuras interrupciones.

Alexis Sanchez – aasanchez@gmail.com


RETLW

Acción Retorno de subrutina y carga literal k en el acumulador


Sintaxis RETLW
Funcionamiento Return with Literal in W
Operación RETORNO con W = k
Descripción Esta instrucción retorna de una subrutina al programa principal,
cargando el acumulador W con el literal k.
Es la última instrucción que forma una subrutina, al igual
que RETURN, con la diferencia que carga en W el valor de k.

Comentarios ¿Y para qué me sirve regresar de una subrutina con un


determinado literal en el acumulador? Nos será muy útil al
programar con TABLAS.
Registro No modifica ningún bit de estado
STATUS
Ejemplo CALL SUBRUT1; llama a Subrut1.
MOVWF DATO 1 ; carga W en Dato1.
CALL SUBRUT2; llama a Subrut2.
MOVWF DATO2 ; carga W en Dato2.
*
*
SUBRUT1 RETLW 0A ; carga W = 0A y retorna.
SUBRUT2 RETLW 0B ; carga W = 0B y retorna.

RETURN

Acción Retorno de una subrutina.


Sintaxis RETURN
Funcionamiento Return from subroutine
Operación RETORNO
Descripción Esta instrucción retorna de una subrutina al programa principal en
la instrucción siguiente a la llamada de la subrutina, tomando el
valor almacenado en el stack para continuar.
Es la última instrucción que forma una subrutina (al igual
que RETLW).
Comentarios El procedimiento es siempre el mismo. Así, tenemos que crear la
subrutina y darle el nombre para poder ser llamada; al final de la
subrutina se debe escribir la instrucción denominada RETURN.
Entonces podemos concluir que una subrutina está constituida por
un conjunto de instrucciones demarcadas por un nombre que se
encuentra al inicio y la instrucción RETURN que se encuentra al
final demarcando el final de la subrutina.
Estos mismos pasos debemos seguirlos para la instrucción
RETLW
Registro No modifica ningún bit de estado.
STATUS

Alexis Sanchez – aasanchez@gmail.com


Ejemplo CALL COMPARA ; llama a Compara.
INSTRUCCION1 ; vuelve aquí cuando se
INSTRUCCION2 ; ejecuta return
*
*
COMPARA INSTRUCCIÓN R1
INSTRUCCIÓN R2
RETURN

Aquí llamamos a la subrutina COMPARA, se ejecutan las


instrucciones R1 y R2 y con el RETURN regresa a la instrucción
siguiente al CALL y ejecuta las instrucciones 1, 2 y sigue con el
programa.

SLEEP

Acción Paso a modo de bajo consumo


Sintaxis SLEEP
Funcionamiento Go into Standby Mode
Operación EN ESPERA.
Descripción Esta instrucción detiene la ejecución del programa, deja el PIC en
modo suspendido y el consumo de energía es mínimo.
No ejecuta ninguna instrucción hasta que sea nuevamente
reinicializado (reset) o surja una interrupción.
Durante este modo, el contador del Watch Dog sigue trabajando, y
si lo tenemos activado el PIC se reseteará por este medio.
Registro No modifica ningún bit de estado.
STATUS
Ejemplo No creo que haga falta… ;)

SUBLW

Acción Resta al literal k el valor del acumulador.


Sintaxis SUBLW k
Funcionamiento Substract W from Literal
Operación W=k-W
Descripción Esta instrucción resta al literal k el valor almacenado en W y el
resultado se guarda en el acumulador.
Registro Modifica los bits Z, DC y C.
STATUS • Z vale 1 si el resultado de la operación es 0.
• DC vale 1 si el resultado de la operación es un número
superior a 15.
• C vale 1 si el resultado de la operación es positivo o el bit 7
del registro que contiene el resultado vale 0. En caso
contrario C vale 0 (resultado negativo).
Ejemplo MOVLW 10 ; carga el acumulador W con el valor 10.
SUBLW 15 ; resta a 15 el valor del acumulador.
Al final el acumulador tendrá el valor W = 5.

Alexis Sanchez – aasanchez@gmail.com


XORLW

Acción Operación lógica OR exclusivo entre el acumulador y el


literal k
Sintaxis XORLW k
Funcionamiento Exclusive OR Literal with W
Operación W = W XOR k
Descripción Esta instrucción realiza un OR exclusivo entre el contenido
del acumulador W y el valor del literal k. El resultado se guarda
siempre en el acumulador (recuerda que k es un literal, no un
registro).
Comentarios Al igual que las otras operaciones lógicas, la suma exclusiva está
tratada en el capítulo de electrónica digital. No obstante expongo
las tablas de verdad correspondientes a esta operación

ENTRADA SALIDA
f W S
0 0 0
0 1 1
1 0 1
1 1 0

La salida únicamente se podrá a nivel alto cuando las dos


entradas sean distintas. Esto es útil cuando tenemos una suma
lógica en la que 1 + 1 es 10 y nos llevamos 1.
Esta operación algebraicamente se expresa así:

S=f+W
Registro Modifica el bit Z.
STATUS • Z vale 1 si el resultado de la operación es 0.
Ejemplo W = 01110011 y k = 00101001 antes de ejecutar la instrucción
XORWF k
ENTRADA RESULTADO
W k W+k
Bit 7 0 0 0
Bit 6 1 0 1
Bit 5 1 1 1
Bit 4 1 0 1
Bit 3 0 1 1
Bit 2 0 0 0
Bit 1 1 0 1
Bit 0 1 1 0

Alexis Sanchez – aasanchez@gmail.com


INSTRUCCIONES DE LA GAMA BAJA
Entre estas instrucciones no se han incluido dos rutinas que aparte de no pertenecer a las
35 instrucciones de la gama media, no pueden ser clasificadas en ninguna de las
categorías expuestas anteriormente, aunque normalmente son acogidas dentro de las
instrucciones con literales y de control. Estas instrucciones son OPTION y TRIS. La razón
por la cual no pertenecen a estas 35 instrucciones es porque fueron creadas pensando en
la gama baja, ya que carece de 4 de las instrucciones de la gama media: ADDLW,
RETFIE, RETURN y SUBLW. No por ello se ha prohibido a la gama media disponer de
estas instrucciones:

OPTION

Acción Guarda el valor del acumulador en el registro OPTION


Sintaxis OPTION
Funcionamiento -
Operación OPTION = W
Descripción Esta instrucción guarda en el registro especial OPTION el valor
contenido en el acumulador W
Registro No modifica ningún bit de estado.
STATUS
Ejemplo MOVLW 10H ; carga el acumulador con el valor 10h.
OPTION ; carga el registro OPTION con el acumulador.

Esta instrucción existe para mantener la compatibilidad con los


PIC producidos con anterioridad, y como en el futuro podría dejar
de implementarse, Microchip aconseja realizar el ejemplo anterior
de esta otra forma:

BSF STATUS, RP0 ; activa el banco 1.


MOVLW 10H ; carga el acumulador con 10h
MOVWF OPTION_REG ; carga OPTION con el acumulador.

TRIS

Acción Guarda el acumulador en uno de los registros de TRIS.


Sintaxis TRIS f
Funcionamiento -
Operación TRIS de f = W.
Descripción Esta instrucción guarda el valor del acumulador W en uno de los
registros especiales de TRIS que indicamos en el parámetro f.
Los registros TRIS determinan el funcionamiento como entrada y
salida de las líneas I/O del PIC.
Registro No modifica ningún bit de estado.
STATUS
Ejemplo MOVLW 16h ; carga el acumulador W con el valor 16h
TRIS PORTA ; carga el registro PORTA con el acumulador.

Alexis Sanchez – aasanchez@gmail.com


Esta instrucción existe para mantener la compatibilidad con los
PIC producidos anteriormente, y como en el futuro podría dejar de
implementarse, Microchip aconseja realizar el ejemplo anterior de
esta otra forma (aunque ocupa más memoria...):
BSF STATUS, RP0 ; activa el banco 1.
MOVLW 16h ; carga el acumulador con el valor 16h
MOVWF TRISA ; carga el registro PORTA con W.

Alexis Sanchez – aasanchez@gmail.com


INSTRUCCIONES ESPECIALES
Existe un conjunto de instrucciones especiales diseñadas para facilitar las operaciones a
la hora de diseñar nuestros algoritmos. Estas instrucciones pueden ser implementadas
con una, dos o tres de las instrucciones de la gama media. La mayoría de ellas se basa
en las operaciones con los acarreos y con los bits del registro status en general. Este
cuadro sólo debe servir de referencia, y no debemos usarlo en el caso de que estemos
empezando. Sólo lo usaremos si vemos muy claro el funcionamiento de las instrucciones,
pero es recomendable usar la forma equivalente, que tiempo de acomodarnos ya
tendremos. Otra cosa que debemos tener en cuenta es que no por reducir algoritmos a
una sola expresión, vamos a ahorrar ciclos de máquina.

Mnemónico Parámetros Descripción Traducción Operación Flags


Equivalente
ADDCF f, d Add Carry to File Sumar acarreo a f BTFSC 3,0 Z
INCF f,d
ADDDCF f, d Add Digit Carry to File Sumar acarreo de digito a f BTFSC 3,1 Z
INCF f,d
B K Branch Saltar a unaetiqueta GOTO k -
BC K Branch on Carry Saltar a una etiqueta si hay BTFSC 3,0 -
acarreo GOTO k
BDC K Branch on Digit Carry Saltar a una etiqueta si hay BTFSC 3,1 -
acarreo de digito GOTO k
BNC K Branch on No Carry Saltar a una etiqueta si no BTFSS 3,0 -
hay acarreo GOTO k
BNDC K Branch on No Digit Carry Saltar a una etiqueta si no BTFSS 3,1 -
hay acarreo de digito GOTO k
BNZ K Branch on No Zero Saltar a una etiqueta si no BTFSS 3,2 -
hay cero GOTO k
BZ K Branch on Zero Saltar a una etiqueta si hay BTFSC 3,2 -
cero GOTO k
CLRC Clear Carry Poner a cero acarreo BCF 3,0 -
CLRDC Clear Digit Carry Poner a cero acarreo de BCF 3,1 -
digito
CLRZ Clear Zero Poner a cero el flag Zero BCF 3,2 -
LCALL K Long CALL Llamada larga a una BSF/BCF 0A,3 -
etiqueta BSF/BCF 0A,4 -
CALL k -
LGOTO K Long GOTO Salto largo a una etiqueta BSF/BCF 0A,3 -
BSF/BCF 0A,4 -
GOTO k -
MOVFW F Move File to W Mover registro a W MOVF f,0 Z
NEGF f, d Negate File Negar un registro COMF f,1 Z
INCF f,d
SETC Set Carry Poner a uno el acarreo BSF 3,0 -
SETDC Set Digit Carry Poner a uno el acarreo de BSF 3,1 -
digito
SETZ Set Zero Poner a uno el Zero BSF 3,2 -
SKPC Skip on Carry Saltar si hay acarreo BTFSS 3,0 -
SKPDC Skip on Digit Carry Saltar si hay acarreo de BTFSS 3,1 -
digito
SKPNC Skip on No Carry Saltar si no hay acarreo BTFSC 3,0 -
SKPNDC Skip on No Digit Carry Saltar si no hay acarreo de BTFSC 3,1 -
digito
SKPNZ Skip on Non Zero Saltar si no hay Zero BTFSC 3,2 -
SKPZ Skip on Zero Saltar si hay Zero BTFSS 3,2 -
SUBCF f,d Substract Carry from File Restar acarreo delregistro BTFSC 3,0 Z
DECF f,d
SUBDCF f,d Substract Digit Carry from Restar acarreo de dígito del BTFSC 3,1 Z
File registro DECF f,d
TSTF f Test File Probar registro MOVF f,1 Z

Alexis Sanchez – aasanchez@gmail.com


CUADRO DE INSTRUCCIONES
Para finalizar, las 35 instrucciones de la gama media las encontraremos resumidas en
los tres próximos cuadros.

Instrucciones orientadas a los bytes

Mnemónico Parámetros Descripción Ciclos Banderas


ADDWF f, d Add W and f 1 C, DC, Z
ANDWF f, d AND W with f 1 Z
CLRF f Clear f 1 Z
CLRW - Clear W 1 Z
COMF f, d Complement f 1 Z
DECF f, d Decrement f 1 Z
DECFSZ f, d Decrement f, Skip 1(2) None
if 0
INCF f, d Increment f 1 Z
INCFSZ f, d Increment f, Skip 1(2) None
if 0
IORWF f, d Inclusive OR W 1 Z
with f
MOVF f, d Move f 1 Z
MOVWF f Move W to f 1 None
NOP - No Operation 1 None
RLF f, d Rotate left f 1 C
through carry
RRF f, d Rotate right f 1 C
through carry
SUBWF f, d Subtract W from f 1 C, DC, Z
SWAPF f, d Swap nibbles in f 1 None
XORWF f, d Exclusive OR W 1 Z
with f

Alexis Sanchez – aasanchez@gmail.com


Instrucciones orientadas a los bits

Mnemónico Parámetros Descripción Ciclos Banderas


BCF f, b Bit Clear f 1 None
BSF f, b Bit Set f 1 None
BTFSC f, b Bit Test f, Skip if Clear 1 (2) None
BTFSS f, b Bit Test f, Skip if Set 1 (2) None

Operaciones con literales y de control

Mnemónico Parámetros Descripción NroCic. Banderas


ADDLW k Add literal and W 1 C, DC, Z
ANDLW k AND literal with W 1 Z
CALL k Call subroutine 2
CLRWDT - Clear Watchdog 1 TO,PD
Timer
GOTO k Go to address 2 None
IORLW k Inclusive OR literal 1 Z
with W
MOVLW k Move literal to W 1 None
RETFIE - Return from interrupt 2 None
RETLW k Return with literal in 2 None
W
RETURN - Return from 2 None
Subroutine
SLEEP - Go into standby mode 1 TO,PD
SUBLW k Subtract W from literal 1 C, DC, Z
XORLW k Exclusive OR literal 1 Z
with W

Microchip recomienda no utilizar las instrucciones TRIS y OPTION, para mantener la


compatibilidad con el PIC16CXX. Aunque eso no significa que tengamos que hacer caso y
no usarlas.

Alexis Sanchez – aasanchez@gmail.com

Potrebbero piacerti anche