Asm Desde Cero (2009)
Asm Desde Cero (2009)
Asm Desde Cero (2009)
Ensamblador desde
cero
Microcontroladores PIC
Este tutorial introduce al lector en el conocimiento sobre las instrucciones
de los microcontroladores de la firma de Microchip. Podrás aprender cada
una de las instrucciones paso a paso y adquirir conocimiento para que sea
capaz desarrollar tus propios programas, a la vez, sirve de manual de
referencia tanto para aficionados, profesionales o estudiantes.
Leon Pic
www.ucontrol.com.ar
18/03/2009
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
A pesar que mucho le escapan a este lenguaje, hay otros que nos sentimos cómodos con
él .
--------------------------------------------------------------------------
Lo primero que hay que saber para este lenguaje, es que cada línea de código, es una
instrucción que realiza el CP o un paso que realiza el CP. A diferencia de otros lenguajes,
como por ejemplo el C, una línea de instrucción, puede llevar uno o más pasos que el CP
debe realizar. Más adelante entenderán el porqué.
A esto último dicho, nos explica el porqué de un programa escrito en ASM (assembler) lleva
menos línea de instrucción que el mismo programa realizado en otro lenguaje. Esto se
traduce que, cuanto menos líneas de código, menor consumo de la memoria de programa.
Nota: Entendemos por el mismo código, al realizar un software para realizar una dicha
tarea. Una tarea que debe realizar nuestro microcontrolador, puede ser escrito en diferentes
lenguajes, y es el programa que se utilizó quien lo traduce a formato hex (1 y 0).
Para dar un ejemplo un poco más claro, digamos que el CP, es una persona. Esta persona se
le da un papel que tiene diferentes tareas a realizar. Estas tareas, están una debajo de la
otra y lee línea por línea y hace lo que le dice esa línea. Cada línea, posee una instrucción
que se debe hacer. Cuando terminó de hacer esa instrucción, continua con la línea de abajo.
El CP, hará esas tareas sin negarse y lo hará fielmente a lo que está escrito. Por lo que, si
hace una tarea mal, es porque le pusimos una o más instrucciones mal.
Si bien, el CP hará lo que nosotros le pidamos, el CP nos pide que respetemos algunas cosas.
Estas cosas, dependerán de cada microcontrolador y que debemos saber para poder
programar en forma correcta al PIC.
www.ucontrol.com.ar Página 2
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
* La primer columna se llama ETIQUETA y sirve para darle el nombre a una pocición de la
memoria del programa al que se necesita apuntar. Los que no se den cuenta, ya lo haran.
Si no sirve para el PIC, ¿Para qué complicarla más? Todo lo contrario, es para ayudar al
programador de que no se olvide que intentó hacer.
Todos los lenguajes, desde los más básicos, hasta los más avanzados, tienen esta
características ya que en el, pondremos que es lo que queremos hacer o explicar el
programa.
;OBSERVACIONES
;OBSERVACIONES
;OBSERVACIONES (y la cantidad que necesitemos)
www.ucontrol.com.ar Página 3
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Los registros, son posiciones de memoria el cual se utilizan para ir configurando el pic
mientras se corre el programa, cambiar de bancos para acceder a otras partes de memorias,
son banderas que nos van diciendo que está pasando con distintas operaciones, son
habilitaciones o deshabilitaciones para módulos que trae el PIC. Por ejemplo, conversor
Analógico/Digital, PWM.
Estos registros, tienen una ancho de bit de acuerdo al PIC, que hay de 8 bit, 16 bit y 32 bit.
Excepto la palabra configuración y que la veremos mas adelante. El tamaño de los registro
depende del tipo de microcontrolador.
Cada registro, posee un nombre, y cada bit o un grupo de bit, se puede utilizar para lo
descripto anteriormente (habilitar/deshabilitar, etc).
A continuación, ver el archivo adjunto. Es la posición de la RAM y sus 4 bancos. Este, es del
PIC16F877
Como notarán, en las cuatro columnas, hay nombres. Estos nombres son todos los registros
que posee este PIC. Verán que hay registros que se repiten. No quiere decir que están
duplicados, triplicados o cuatriplicados, si no que se puede acceder a ellos no importa en que
banco estemos trabajando. (Ya lo entenderán, no se preocupen).
Cada vez que se programe el PIC y se necesite trabajar con uno de estos registros, se debe
acceder al banco que esté dicho nombre. Es por eso, que esta tabla es muy importante a la
hora de trabajar.
Aprovechando que subí esta tabla del pic, cuando de ejemplo de programación, será sobre
este pic.
Microchip provee en forma gratuita estos datasheet. Y hay uno por cada PIC. Por lo que si no
tienen este datasheet, descárgenlo de la página de Microchip. Cuando empecemos a
programar, lo necesitarán.
www.ucontrol.com.ar Página 4
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Uno de los registros muy utilizado, es el registro de trabajo W, el cual, se utiliza para
mover un dato/valor de un registro a otro, cargar valores en un registro, y con la ayuda
de la ALU puede hacer operaciones matemáticas.
Observen con atención el diagrama de bloque dónde se encuentra W que está adjuntado.
www.ucontrol.com.ar Página 5
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
trabajo.
* Memoria de Programa
Es la ubicación física dónde se guarda el firmware que hemos creado, o sea, nuestro
programa. Y tiene un ciclo de 100.000 de lectura y/o escrituras antes de estropearse y es
del tipo FLASH (pero este es flaco :mrgreen: Es un chiste).
El PIC 16F877, tiene una memoria de programa de 8Kb por un ancho de 14 Bits, o sea que
cada posición de memoria tiene 14 bit (B'11111111111111', o H'3FFF') Cada línea de instrucción
ocupa una posición en la memoria de programa, así que, podemos poner hasta 8.192
instrucciones.
La RAM de uso general (mas los registros) trae 368 bytes con un ancho de 8 bit (B'11111111',
o H'FF'). Esto quiere decir, que tenemos 368 posiciones para nuestro uso.
La EEPROM trae 256 bytes con un ancho de 8 bits. Tenemos 256 posiciones para nuestro
uso.
www.ucontrol.com.ar Página 6
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Registro STATUS
Si entendieron hasta acá, se acordará que los registros poseen un ancho de 8 bit. Cada
bit, puede contener un 1 o 0.
www.ucontrol.com.ar Página 7
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Este registro, tiene 3 Bit dedicado para las operaciones matemáticas, 3 bit dedicado al
cambio de banco de memoria y 2 bit dedicado para saber que o quién produjo un Power
Up (despertar del micro). Y se puede leer y escribir en él (cambiar datos).
Los analizamos desde el más significativo (MSB) hasta el menos significativo (LSB).
BIT 7:
1 = Banco 2 y 3
0 = Banco 0 y 1
BIT 6 y BIT 5
00 = Banco 0
01 = Banco 1
10 = Banco 2
11 = banco 3
BIT 4
Se llama TO (neg). Este bit se utiliza para saber quién despertó al PIC.
1 = Después que despierta (power up) o por las instrucciones CLRWDT o SLEEP, se pone
a 1 este bit.
0 = Se pone a 0 cuando el wachtdog o en castellano perro guardián (WDT) despierta al
PIC.
BIT 3
Se llama PD (neg). Este bit se utiliza para saber si el pic estaba durmiendo.
BIT 2
Se llama Z y al igual que los dos bytes anteriores, es una bandera. Nos indica el resultado
de una operación aritmética y lógica.
www.ucontrol.com.ar Página 8
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
BIT 1
Se llama DC. Digit carry/borrow (dígito llevar/prestar). Es afectado por las instrucciones
ADDWF; ADDLW; SUBLW; SUBWF (Para la resta, la polaridad es inversa).
BIT 0
Se llama C carry/borrow. Es afectado por las mismas instrucciones que afectan al bit DC.
1 = Hubo un acareo del bit más significativo (Bit 7) o sea cuando se excede de H'FF'
0 = No hubo acareo del bit más significativo
www.ucontrol.com.ar Página 9
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Cada instrucción tiene una ancho de 14 Bits, es por eso que la memoria de programa
tiene el mismo ancho. Justamente para poder alojar cada instrucción.
www.ucontrol.com.ar Página 10
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
OPCODE (Código)
DESTINATION (Destino)
FILE REGISTER ADDRESS (Dirección del archivo de registro)
La constante que nos indica esto es la letra d. Si esta letra es 0, la operación se guardará
en el registro W. EN cambio si vale 1, la operación se guardará en el registro o posición
de memoria que estemos trabajando al momento de usar una instrucción.
Hay instrucciones, como veremos más adelante, que no es necesario indicar dónde
queremos guardar la operación, ya que se hace en forma automática. Y hay otras
instrucciones que si no se indica el destino, nos puede dar un error al compilar o el
compilador lo elegirá el y por ende, nos puede ejecutar mal el programa.
Y por último, tenemos el FILE REGISTER ADDRESS que se carga con la dirección
del registro a ser guardado. Está formada por los bit 6 al 0. La constante que nos indica
esto, es la letra f
OPCODE (Código)
BIT ADDRESS (Bit de dirección)
FILE REGISTER ADDRESS (Dirección del archivo de registro)
OPCODE es igual al primer grupo. Está formado por los bits 13 al 10.
El BIT ADDRESS, se utiliza para direccionar la operación. Está formado por los bits 9
al 7. Como pueden observar, se sacrificó bit del opcode para dárselo al bit address. La
constante que nos indica esto es la letra b
www.ucontrol.com.ar Página 11
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Y por último tenemos FILE REGISTER ADDRESS, que es igual al primer grupo. Está
formado por los bit 6 al 0. Igual que en el primer grupo. la constante que nos indica esto
es la letra f.
OPCODE
LITERAL
OPCODE es igual que en el primer grupo. Está compuesta por los bits 13 al 8. Excepto
para las instrucciones CALL y GOTO que está compuesta por los bit 13 al 11 (prestar
mucha atención a esto, cuando veamos estas dos instrucciones entenderán la
importancia).
Y el LITERAL que puede ser un valor, por ejemplo para sumar, para restar, para cargar
al registro W, en fin, un número decimal, binario o hexadecimal. O puede ser un valor
de dirección a dónde apuntar para las instrucciones CALL y GOTO.
Está compuesta por los bits 7 al 0. Excepto para las instrucciones CALL y GOTO que
está compuesta por los bit 10 al 0 (prestar mucha atención a esto, cuando veamos estas
dos instrucciones entenderán la importancia).
www.ucontrol.com.ar Página 12
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
www.ucontrol.com.ar Página 13
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Las instrucciones
Les voy a arruinar el momento de alegría. Las instrucciones hay que estudiarlas de
memoria. Si, leyeron bien, de memoria. Lo que tienen que saber sobre las instrucciones,
es como se escriben, que hace cada instrucción y lo más importante que bit del
REGISTRO afecta.
Vamos a ir viéndolo por orden alfabético. Y otra cosita más, como es de esperarse, están
en INGLES o son abreviaturas pero en INGLES.
ADDLW
Ejemplo
ADDLW .128
Si W tenía cargado un valor = .5, después de la instrucción W tiene cargado el valor .133
Afecta a:
Z Se pone a 1 si la operación es 0
DC Se pone a 1 si hubo un acarreo del bit 3 al 4
C Se pone a 1 si hubo desbordamiento, o sea, cuando se supera H'FF'
ADDWF
Suma el valor del registro W con el valor de un registro cualquiera. El destino de esta
suma, lo elige el programador.
Ejemplo:
ADDWF TEMP,W
Si W tenía guardado .133 y la posición de la RAM llamada TEMP tenía el valor cargado
con .2, W vale .135 y TEMP continúa valiendo .2
www.ucontrol.com.ar Página 14
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
NOTA: Para indicar la dirección de dónde se guarda, también se puede poner 0 o 1 en vez
de W o F. 0, corresponder guardarlo en el registro W y 1 en el registro TEMP (para este
caso).
Afecta a:
Z Se pone a 1 si la operación es 0
DC Se pone a 1 si hubo un acarreo del bit 3 al 4
C Se pone a 1 si hubo desbordamiento, o sea, cuando se supera H'FF'
ANDWF
Ejemplo:
ANDWF TEMP,F
Afecta a:
Z Se pone a 1 si la operación es 0
www.ucontrol.com.ar Página 15
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
BCF
Ejemplo:
BCF TEMP,2
BSF
Ejemplo:
BSF TEMP,0
BTFSC
Salta un línea si el bit de un registro es cero. El bit debe ser indicado por el programador.
Ejemplo:
BTFSC TEMP,5
BCF PORTA,0
BSF PORTB,0
Caso 1:
TEMP vale B'00011110'. El CP analizará solo el Bit 5 del registro TEMP, como es 0, salta la
www.ucontrol.com.ar Página 16
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
instrucción BCF PORTA,0 y ejecuta la siguiente línea que es BSF PORTB,0 y continua
haciendo la instrucción.
Caso 2:
TEMP vale B'00111000'. El CP analizará solo el Bit 5 del registro TEMP, como es 1 no salta
la instrucción y hará la instrucción BCF PORTA,0 y luego continua con la instrucción
BSF PORTB,0
BTFSS
Salta una línea si el bit de un registro es 1. EL bit debe ser indicado por el programador.
Ejemplo:
BTFSS TEMP,3
ADDWF PORTC
ANDWF NODO
Caso 1:
TEMP vale B'01101100'. El CP analizará solo el Bit 3 del registro TEMP, como es 1, salta la
instrucción ADD PORTC y ejecuta la siguiente línea que es ANDWF NODO y continua
haciendo la instrucción.
Caso 2:
TEMP vale B'11110000'. El CP analizará solo el Bit 3 del registro TEMP, como es 0 no salta
la instrucción y hará la instrucción ADD PORTC y luego continúa con la instrucción
AND NODO.
www.ucontrol.com.ar Página 17
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
CALL
Ejemplo :
CALL ESC_PORTB
-----------------------------------------------------------------------------------------------------------
-------------------
Hacemos una excepción con respecto a ver las instrucciones por orden alfabético y
veremos la instrucción GOTO.
-----------------------------------------------------------------------------------------------------------
-------------------
GOTO
Ejemplo:
GOTO INICIO
Para recordar GO TO es ir a.
Extendiendo la explicación.
Vamos a hablar del PC para entender bien sobre estas instrucciones. La excelente
explicación que continua, por desgracia no es mía (ojalá fuera mi explicación), son de las
personas Maunix y BrunoF (del foro todopic)
www.ucontrol.com.ar Página 18
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
El PC es de 13 bits en este caso (8kwords). 14 son los bits de cada "word" o instrucción
que se graban en cada posición de la FLASH (memoria de programa).
El PC se reparte en: sus 8 bits de menor peso en el registro PCL, y los 5 restantes en el
registro PCLATH.
Los pics al tener un set de instrucciones reducido no puede en una sola instrucción
meter todos los bits necesarios para direccionar toda su memoria.
El STACK (pila) tiene toda la dirección, no solo parcial. Si haces un call desde la pagina 0
a la página 3 y luego un return el código SI volverá a la página 0, pero el PCLATH sigue
apuntando a la página 3, entonces si usas otro goto o call, debes tener en cuenta de
modificar el PCLATH.
Al ejecutar un call o un goto, se copian del 0 al 10, y los otros 2 bits se copian del registro
PCLATH. El pclath solo estará allí para esa situación.
www.ucontrol.com.ar Página 19
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
En un return o retfie la microelectrónica del PIC, pega la dirección del PC que estaba
guardada.
1.
STACK = vacío
PC = 0x00A0
PCLATH = 0b000011000
Ejecutas un CALL 0x230
4. Viene un RETURN.
La microelectrónica del PIC copiará el stack tal cual en el program counter + 1
Valor STACK 0x00A0 + 1 --> PC = 0x00A1
5. EL código sigue ejecutándose en la página 0 pero hay que tener en cuenta que el
PCLATH apunta a la página 3 por ello si harás otro CALL o GOTO, deberás cambiar de
nuevo el PCLATH si la subrutina no está en la página 3.
Vamos a entrar a todo detalle en el Program Counter(PC) para que se vayan todas las
dudas ya que es muy importante. Vayamos al tema tema del PC, computed goto(lo que
algunos llaman "tabla"), call, returns y goto.
Ahora, hay dos situaciones posibles en las que el PC debe ser cargado de manera distinta:
una es cuando queremos trabajar con tablas y otra cuando realizamos un call o un goto
www.ucontrol.com.ar Página 20
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
La tabla es una situación de uso del PC en la que se afecta directamente al registro PCL.
Cuando se afecte directamente al PCL mediante una instrucción, es necesario que el
usuario asegure que PCLATH tenga sus 5 bits pre-cargados adecuadamente.
Hago un ejemplo:
Mal:
org 0x000
movlw 0x01
call tabla
org 0x300
tabla
addwf PCL,F
retlw 0x03
retlw 0x01
retlw 0x0F
.....
Bien:
org 0x000
movlw 0x03
movwf PCLATH
movlw 0x01
call tabla
org 0x300
tabla
addwf PCL,F
retlw 0x03
retlw 0x01
retlw 0x0F
.....
Mejor:
org 0x000
pageselw tabla
movlw 0x01
www.ucontrol.com.ar Página 21
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
call tabla
org 0x300
tabla
addwf PCL,F
retlw 0x03
retlw 0x01
retlw 0x0F
.....
Pageselw es una instrucción del MPASM que genera dos instrucciones: un movlw literal
y un movwf PCLATH. El valor del literal es automáticamente seleccionado por el
ensamblador según la etiqueta(o posición de memoria) que se le especifique. En el caso
anterior pageselw tabla generaría estas dos instrucciones:
movlw 0x03
movwf PCLATH
Si no aseguramos que los 5 bits del PCLATH estén correctamente seteados al momento
de afectar al PCL mediante alguna instrucción (generalmente es la addwf, pero puede
usarse subwf y muchas otras) entonces el programa saltará a una posición indeseada.
F2 F1 F0 K10 K9 K8 K7 K6 K5 K4 K3 K2 K1 K0
Donde las F indican cuál instrucción es la que debe ejecutarse (100 para la CALL 101 para
la GOTO), y las k corresponden a la dirección a la cual queremos llamar (con un CALL) o
saltar(con un GOTO).
Entonces, dijimos que el PC contiene 13 bits de longitud. 13 bits son hasta 8kwords (una
word es en esta familia un conjunto de 14 bits que conforman una instrucción la cual se
www.ucontrol.com.ar Página 22
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
aloja en la memoria FLASH del µC). Un CALL o un GOTO sólo contienen los 11 bits de
menor peso de la dirección a la cual ir, por lo que los 2 bits restantes deberán ser pre-
cargados en los bits 4 y 3 del registro PCLATH por el usuario programador.
Cabe mencionar que el µC carga a PC<10:0> con el valor pasado por los 11 bits de K, y a
PC<12:11> con el valor de los bits PCLATH<4:3>. El registro PCLATH no es modificado de
ninguna manera. Sólo se leen esos dos bits.
Por ejemplo, en un µC de 8kWords hay 4 páginas. Una página cada 2048 words. Si se está
en una página y se quiere ir a otro es necesario precargar antes dichos bits del PCLATH
para poder hacerlo.
Si ocurre al menos uno de esos dos casos, es suficiente con asegurar que los bits
PCLATH<4:3> se encuentren ambos en cero.
Mal:
Bien:
www.ucontrol.com.ar Página 23
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
call cruzo
Mejor:
Pagesel es una instrucción del MPASM que genera dos instrucciones: un bcf/bsf
PCLATH,3 y un bcf/bsf PCLATH,4. El software ensamblador selecciona automáticamente
la instrucción bcf o bsf según el banco en el cual se encuentra la etiqueta(o posición de
memoria) que se le especifique. En el caso anterior pagesel cruzo generaría estas dos
instrucciones:
bsf PCLATH,3
bcf PCLATH,4
Para más información, ver el esquema sección 2.3 del datasheet de los PIC16F87XA que
habla de cómo cargar al PC según cada situación.
www.ucontrol.com.ar Página 24
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
CLRF
Ejemplo:
CLRF PORTB
Afecta a:
Z Se pone a 1
CLRW
Borra al registro W. La forma en que lo hace, pone en 0 los 8 bit del registro.
Ejemplo:
CLRW
Afecta a:
Z Se pone a 1
CLRWDT
www.ucontrol.com.ar Página 25
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Ejemplo:
CLRWDT
Para recordar CLeaR es limpiar Watch Dog es perro guardián Timer es contador.
Afecta a:
TO (neg) Se pone a 1
PD (neg) Se pone a 1
NOTA: El WDT o el contador perro guardián, sirve para destrabar al PIC. Cada vez que
se desborda, o sea, cada vez que pasa de H'FF' a H'00', produce un reset, y como es un
reset, se dirige a la posición 0h de la memoria de programa.
La forma de trabajar con el, es ir poniendo en lugares estratégicos la instrucción ya
explicada, de esta manera evitamos el desborde del contador. Si el CP se traba en algún
bucle o algo similar, al no limpiar el contador, el WDT desbordará y llevará al CP a la
posición 0h de la memoria de programa.
Muchas veces se evita de usar esta herramienta por no tener que calcular por todo el
programa dónde y cuando limpiar al WDT. Es recomendable su uso.
www.ucontrol.com.ar Página 26
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
COMF
Afecta a:
Z Se pone a 1 si la operación da 0
DECF
DECF DECENA,W
Afecta a:
Z se pone a 1 si la operación es 0
DECFSZ
www.ucontrol.com.ar Página 27
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
GOTO LOOP
BCF PORTB,0
NOTA: Esta instrucción, también hay que elegirle el destino. En el caso que no se
exprese, como en este caso, el MPLAB dará por sentado que el resultado se guardará en
el registro F y no en W.
Para recordar DECrement es decremento File es registro Skip es salto Zero que es cero.
INCF
INCF INDF,F
Si antes de la instrucción INDF vale H'29', después de la instrucción INDF vale H'2A'.
Nótese que también podemos elegir el destino. Si hubiéramos elegido W, después de la
instrucción W vale H'2A' y INDF vale H'29'.
Afecta a:
Z se pone a 1 si el resultado es 0
INCFSZ
www.ucontrol.com.ar Página 28
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
NOTA: Esta instrucción, también hay que elegirle el destino. En el caso que no se
exprese, como en este caso, el MPLAB dará por sentado que el resultado se guardará en
el registro F y no en W.
Para recordar INCrement es decremento File es registro Skip es salto Zero que es cero.
IORLW
Afecta a:
Z se pone a 1 si la operación da 0
www.ucontrol.com.ar Página 29
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
IORWF
IORWF PORTC,F
Afecta a:
Z se pone a 1 si el resultado es 0
MOVLW
Carga al registro W con un literal elegido por el programador para luego hacer una
operación matemática o moverlo a otro registro como veremos más adelante. Sin duda
alguna, una de las instrucciones más usadas en la programación ASM.
MOVLW .255
MOVF
MOVF RETARDO,W
www.ucontrol.com.ar Página 30
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Afecta a:
Z Se pone a 1 si la operación es 0
MOVWF
MOVWF ADCON0
NOP
NOP
www.ucontrol.com.ar Página 31
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
RETFIE
Carga al CP con el valor de la parte alta de la pila para volver al lugar dónde se
encontraba el CP antes de atender la interrupción. Al mismo tiempo, pone a 1 el bit GIE
para activar de nuevo las interrupciones.
RETFIE
RETLW
Carga al CP con el valor de la parte alta de la pila para volver al lugar dónde se
encontraba el CP desde dónde se llamó a la subrutina y al retornar, lo hace con un literal
cargado en W especificado por el programador. Esta instrucción, se utilizan en las tablas
(para más detalle, ver la explicación del GOTO y CALL).
Ejemplo:
RETLW 'L'
Extendiendo el ejemplo:
www.ucontrol.com.ar Página 32
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Este es un ejemplo sencillo de como utilizar RETLW. Para interpretar este código
empezamos desde PAGESELW, supongamos que el CP está en esta instrucción (que está
explicado que hace) luego pasa a la instrucción MOVFW contador y suponemos que
tiene cargado 3 en decimal, por lo que W pasará a tener 3 en decimal. El CP continua con
CALL TABLA, el CP saltará por encima a todas las demás instrucciones y se dirige a la
etiqueta TABLA y ejecuta la instrucción ADDWF PCL,F En el código hablamos que le
suma 3 al PCL, por lo que saltará al RETLW '3' cargando a W con el código ASCII 3.
Retorna justo debajo del CALL TABLA, o sea retorna a CALL LCD_DATO y ejecuta la
rutina correspondiente, cuando termina, regresa al NOP (que puede ser cualquier
instrucción que necesite el programador.
Si en cambio, contador hubiera tenido cargado 4 en decimal cuando llegue a la tabla y le
sume al PCL este apuntará a RETLW 'T' cargando en W el código correspondiente ASCII.
RETURN
Carga al CP con el valor de la parte alta de la pila para volver al lugar dónde se
encontraba el CP cuando se llamó a la rutina o subrutina.
La diferencia con RETLW es que RETURN regresa sin cambiar a W. Este se utiliza para
terminar una rutina y no se necesite ningún dato. Por ejemplo en la rutina CALL
LCD_DATO no nos sirve que vuelva con ningún valor ya que es una rutina para enviar
datos a un LCD, así que esta rutina tendrá implementada RETURN
Por ejemplo:
RETURN
www.ucontrol.com.ar Página 33
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
RLF
Rota hacia la izquierda los bit de un registro seleccionado por el programador. El destino
de la operación se puede elegir. Cada rotación equivale a multiplicar por 2 si el bit C del
registro STATUS es 0.
Ejemplo:
RLF PORTC,F
Afecta a:
RRF
Rota hacia la derecha los bits de un registro seleccionado por el programador. El destino
de la operación se puede elegir. Cada rotación equivale a dividir por 2 si el bit C del
registro STATUS es 0.
Ejemplo
RRF PORTB,F
Afecta a:
www.ucontrol.com.ar Página 34
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
A la hora de utilizar estas dos instrucciones, hay que prestarle atención al bit C del
registro STATUS. La razón de esto, es porque la rotación se hace a través del bit C.
BIT C = 0
TEMP = B'00010000'
BIT C = 1
TEMP = B'00010000'
Vemos como rota los bit dependiendo del valor del bit C. Pero anteriormente, h abíamos
dicho que estas dos instrucciones afectan al bit C. La actualización del bit C, lo hace
después de la rotación. Lo vemos con un ejemplo:
MOVLW B'10001001'
MOVWF temp
BCF STATUS,C ;PONEMOS A 0 AL BIT C
RLF temp,F ;ROTAMOS A LA IZQUIERDA
TEMP = B'00010010'
BIT C = 1
www.ucontrol.com.ar Página 35
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
MOVLW B'00000001'
MOVWF temp
BCF STATUS,C ;PONEMOS A 0 AL BIT C
RLF temp,F ;ROTAMOS A LA IZQUIERDA
TEMP = B'00000010'
BIT C = 0
Algo que me había olvidado de mencionar pero que MIGSANTIAGO del foro de
TODOPIC estuvo atento es que estás dos instrucciones, nos sirve para enviar datos en
forma serial utilizando el bit C que lo veremos más adelante.
Recordemos que, para utilizar estas instrucciones para multiplicar o dividir, debemos
asegurarnos de que el bit C, esté en 0.
SLEEP
SLEEP
Afecta a:
TD se pone a 1
PD se pone a 1
SUBLW
SUBLW .20
www.ucontrol.com.ar Página 36
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Afecta a:
Z se pone a 1 si el resultado es 0
DC se pone a si hay acarreo del bit del 4 al 5 bit del registro (recordemos que en
la resta, es distinto a la suma, por eso, se pone a 0 si hubo acarreo).
C se pone a 0 si hubo acarreo (recordemos que en la resta, es distinto a la suma,
por eso, se pone a 0 si hubo acarreo).
SUBWF
Ejemplo:
SUBWF MINUENDO,W
Afecta a:
Z se pone a 1 si el resultado es 0
DC se pone a 0 si hubo un acarreo del 4 bit al 5 bit (recordemos que en la resta,
es distinto a la suma, por eso, se pone a 0 si hubo acarreo).
C se pone a 0 si hubo acarreo del 7 bit. (recordemos que en la resta, es distinto a
la suma, por eso, se pone a 0 si hubo acarreo).
www.ucontrol.com.ar Página 37
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
SWAPF
Intercambia los bits de un mismo registro elegido por el programador. Los 4 bit de
menor peso, pasan a ser lo 4 bits de mayor peso, y los 4 bits de mayor peso, pasan a ser
los 4 bits de menor peso. El destino puede ser seleccionado.
Cabe pensar que puede ser una instrucción de muy poco uso, pero todo lo contrario si se
utilizan con las interrupciones. Microchips recomienda su utilización a la hora de salvar
el contexto y restaurarlo en una interrupción ya que no modifica el registro STATUS.
Cuando trabajemos con las interrupciones, se verá que es muy recomendable salvar el
registro STATUS y W en la RAM para luego restaurarlos. Si utilizamos la instrucción
MOVF, es afectado el bit Z, perdiendo su estado original en el momento de la
interrupción. Esto se soluciona, utilizando la instrucción SWAPF. No se preocupen si no
lo entiende por ahora. Lo entenderán cuando veamos ejemplo de interrupciones.
Ejemplo:
SWAPF STATUS,W
XORLW
Ejemplo:
XORLW B'11000101'
Afecta a:
www.ucontrol.com.ar Página 38
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Z se pone a 1 si la operación es 0
XORWF
Ejemplo:
XORWF PORTB,F
Afecta a:
Z se pone a 1 si la operación es 0
www.ucontrol.com.ar Página 39
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Una vez que vimos todas las instrucciones y asumiendo que ya se la saben de
memoria (tiempo tuvieron de sobra) y si no lo han echo, es hora de hacerlo,
empecemos a escribir programas muy sencillos. Pero ¿cómo?. Si se están asiendo
esta pregunta, es hora de leer desde el primer mensaje. Tienen que acordarse las
posiciones de las cuatro columnas.
Recuerden que vamos a escribir los programas en el MPLAB, por lo que si aún no
lo tienen, es hora de descargarlo de la página de Microchip en forma gratuita e
instalarlo en la PC. Lamentablemente, este programa trabaja solo bajo Windows,
por los que tienen Mac o Linux, no lo podrán hacer si no es por un emulador de
Windows y aún así, no se si funcione correctamente.
Empezaremos bien desde el principio y para ello, voy a explicar cosas nuevas.
Todo programa tiene un encabezado que se repite en cada programa nuevo y que
varía según el PIC a utilizar y las prestaciones del programa a escribir. Muchas de
las personas crean plantillas nuevas para ahorrarse el trabajo. Yo soy una de ellas
y aquí les doy una plantilla que pueden utilizar sin problemas y modificarlas
según su necesidad.
LIST P=16F877A
INCLUDE <P16F877A.INC>
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
;
;---------------------------------------------------------------
;VARIABLES.
;---------------------------------------------------------------
;
CBLOCK H'20'
ENDC
;
RESET ORG H'00'
GOTO INICIO
ORG H'04' ;VECTOR INTERRUPCIÓN
INTERRUP
;
INICIO
;
END
Primera línea:
LIST P=16F877A
www.ucontrol.com.ar Página 40
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Esta línea, sirve solo para el MPLAB y le indica que el PIC a utilizar es el 16F877A.
Se debe actualizar según sea necesario.
Segunda línea:
INCLUDE <P16F877A.INC>
Esta línea sirve a la hora de compilar ya que dentro de este archivo que viene
incluido dentro del MPLAB, le indica al ensamblador dónde están ubicados cada
registro y el nombre de cada bits del PIC a utilizar así, nos ahorra de hacerlo
nosotros mismos. Si desean abrir el archivo, lo pueden hacer con el notepad o
cualquier editor de texto. Se debe actualizar según sea necesario.
Tercera línea:
www.ucontrol.com.ar Página 41
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
LIST P=16F877A
INCLUDE <P16F877A.INC>
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
;
;---------------------------------------------------------------
;VARIABLES.
;---------------------------------------------------------------
;
CBLOCK H'20'
ENDC
;
RESET ORG H'00'
GOTO INICIO
ORG H'04' ;VECTOR
INTERRUPCIÓN
INTERRUP
;
INICIO
;
END
www.ucontrol.com.ar Página 42
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
Cuarta línea:
;
;---------------------------------------------------------------
;VARIABLES.
;---------------------------------------------------------------
;
Este no es más que un pequeño encabezado. El ensamblador omitirá estas líneas y solo
porque empieza con ";". Recuerden que, toda línea que empiece con ";" es comentario y
el ensamblador la omitirá.
Justo por debajo de este encabezado, penemos las variables. ¿a que le llamo variables? a
posiciones de memorias o nombre de bit que yo quiera darle personalmente.
Por ejemplo, dentro del archivo P16F877A.INC a la posición de memoria 0x05 le llama
PORTA pero si yo quiero llamarlo PUERTO_A, es aquí dónde le indico al ensamblador.
¿Cómo se hace?
LED6 EQU 6
Supongamos que quiero encender el LED 6 que está en el Puerto a bit 6, y este se activa
con un 1 lógico, ponemos esta instrucción:
BSF PUERTO_A,LED6
Quinta línea:
CBLOCK H'20'
ENDC
A estas dos líneas las unifique porque van juntas. Entre ellas van los nombres de cada
posición de la RAM que nosotros queramos nombrar, o cada Registro que queramos
renombrar.
Recuerden que los registros están implementados en la RAM y que la posición de la RAM
que puede utilizar el usuario para guardar cosas, empieza desde una posición que está
www.ucontrol.com.ar Página 43
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
indicada en el datasheet. Para el caso de 16F877 empieza desde la posición 0x20 como lo
ven en la figura siguiente.
CBLOCK H'20'
temperatura
demora1
demora2
ENDC
Sexta línea:
He unificado estas líneas porque por lo general así se escribe en la mayoría de nuestros
programas. Vemos con más detalles estas líneas.
ORG H'00' indica que se empieza a escribir desde la posición 0x00 por lo que la siguiente
instrucción, quedará alojada en la posición 0x00. ORG es una directiva, y solo sirve para
el ensamblador. Esta línea, SIEMPRE debe estar y no se puede modificar, salvo la
www.ucontrol.com.ar Página 44
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
etiqueta.
Siguiente línea es GOTO INICIO, esta instrucción queda alojada en la posición 0x00 y es
un salto a la etiqueta INICIO. Este salto tiene que estar, porque en las siguientes
posiciones de memoria de programa, está la interrupción, externa e interna del PIC. Por
eso es necesario hacer el salto.
Siguiente línea nos encontramos con ORG H'04', como se dieron cuenta, es una
directiva. Esta posición de memoria, indica el vector de interrupción. Cuando estén
habilitadas las interrupciones y una de ella se activa, el CP apuntará aquí, a la posición
0x04.
Siguiente línea nos encontramos con la etiqueta INTERRUP. Si trabajamos con las
interrupciones, aquí es donde escribiremos lo que necesitamos hacer con ellas.
Séptima línea:
;
INICIO
;
Vemos la etiqueta INICIO. Aquí vendrá el CP cuando halla un reset gracias al GOTO
INICIO ubicado en la posición 0x00 de la memoria de programa. De esta manera,
saltamos un montón de instrucciones que no debemos ejecutar antes. Como por ejemplo
las interrupciones si hubiese.
Por ende, a partir de esta etiqueta, estará nuestro programa principal. Configuraremos
los puertos, las interrupciones y empezaremos a darle trabajo al CP.
Octava línea:
END
Esta es una directiva y solo sirve para el ensamblador indicando que después de esta
directiva, se terminó el programa. Instrucciones que estén por debajo de esta línea, no
será tenido en cuenta. Y esta directiva es obligatoria colocarla.
www.ucontrol.com.ar Página 45
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
www.ucontrol.com.ar Página 46
[ENSAMBLADOR DESDE CERO] 18 de marzo de 2009
www.ucontrol.com.ar
www.ucontrol.com.ar Página 47