Rutinas de programacin
Captulo VI
Rutinas de
programacin
La suma
La resta
La rotacin
La multiplicacin
La divisin
Conversin binario a BCD
Suma BCD
Conexin de displays al PIC
79
80
Las rutinas son uno de los recursos ms valiosos cuando se trabaja en programacin; ellas permiten que los programas sean ms simples, debido a que el programa
principal se disminuye cuando algunas tareas se escriben en forma de programas
pequeos e independientes.
En programacin, una rutina se define como un procedimiento independiente
(un bloque), que realiza una labor especfica y a la cual se puede llamar desde cualquier parte del programa principal. Dado que cada rutina realiza una labor en particular, como encender un LED o establecer una base de tiempo de un segundo, por
ejemplo, el programador, cuando est seguro de su funcionamiento, puede mantenerla almacenada y disponible en un banco o librera, para utilizarla en cualquier programa, sin volver a escribir las lneas que realicen lo deseado: slo necesitar copiar el bloque de la rutina o tener el archivo disponible para cuando se realice
la compilacin del programa. Posteriormente, deber hacer el llamado al procedimiento adecuado, en el instante preciso.
Para la elaboracin de cualquier rutina, es necesario conocer ms a fondo las
instrucciones que la forman y cuales son las condiciones o estados que se modifican
ante cada una de ellas. Los estados, banderas o flags son bits que se afectan por
algunas operaciones lgicas o aritmticas y la consulta de estos se utiliza para tomar
decisiones dentro del programa. Debemos tener presente que en el microcontrolador
PIC 16C84, los estados se encuentran localizados en el registro 03, llamado STATUS. Los primeros tres bits de este registro (0 al 2) son los estados sobre los cuales
debemos ejercer una vigilancia, para determinar as los siguientes pasos a ejecutar.
El bit menos significativo (bit 0) es el correspondiente al estado del Carry o acarreo,
el siguiente (bit 1) corresponde al DC o acarreo de dgito y el tercero de ellos (bit 2)
es el correspondiente al estado Z o cero.
Cuando escribimos el programa en un editor de textos, para posteriormente utilizar el ensamblador , debemos recordar que, en el formato de las instrucciones
primero se escribe el registro fuente y a continuacin el registro destino de la operacin que se est realizando. Se llama registro fuente aquel registro que se utiliza
como origen de la informacin y registro destino aquel en el cual se almacena el
resultado de la operacin. Si deseamos que el destino sea el registro W, podemos
optar por escribir en la parte correspondiente, W 0; si deseamos que se haga en el
mismo registro fuente, podemos escribir 1 u omitirlo. Por ejemplo, las siguientes
instrucciones son equivalentes:
comf
xorwf
10,w
15
equivale a
equivale a
comf
xorwf
10,0
15,1
La suma
Esta operacin se implementa en los microcontroladores PIC por una sola instruccin: ADDWF; en la figura 1 se observan sus detalles. Lo ms importante para
considerar en todos los casos son los estados afectados ya que, como lo habamos
Curso Bsico de Microcontroladores PIC
81
mencionado, ellos son los indicadores que se deben utilizar para tomar decisiones
en el programa.
Instruccin:
ADICION
Sintaxis:
ADDWF
f,d
Codificacin:
Cod. Op.
000111 d
Dest. Fuente
fffff
Operacin:
(f) + (W) - d
1001 0011
1010 1011
1010 1011
1100 1101
W
0101 1000
0010 0101
0110 1100
0011 0011
ADDWF Fuente,W
ADDWF Fuente
ADDWF Fuente,0
ADDWF Fuente,1
Despus de la instruccin
Fuente
DC
1001 0011
1101 0000
1010 1011
0000 0000
1110 10110
0010 0101
0001 01110
0011 00111
0
0
1
1
0
1
1
1
0
0
1
1
La resta
De manera similar a la suma, esta operacin se implementa con una sola instruccin: SUBWF; en la Figura 3 se observan sus detalles ms importantes.
Instruccin:
RESTA
Sintaxis:
SUBWF
Codificacin:
Operacin:
(f) - (W) - d
f,d
Fuente
fffff
1
2
3
4
Fuente
1011 1001
1011 1001
1011 1001
1011 1001
0100 0010
0100 1100
1110 0011
1011 1001
Instruccin
SUBWF Fuente,W
SUBWF Fuente
SUBWF Fuente,0
SUBWF Fuente,1
Despus de la instruccin
Fuente
DC
1011 1001
0110 1101
1011 1001
0000 0000
0111 0111
0100 1100
1101 0110
1011 1001
0
0
0
1
1
0
1
1
1
1
0
1
83
Por ltimo, el estado Z slo se activar cuando ambas cantidades sean iguales y
el resultado de la operacin, por lo tanto, sea cero, siendo ste el valor que se almacena en el registro destino.
La rotacin
En los microcontroladores PIC se encuentran dos instrucciones de rotacin: una
hacia la izquierda y otra hacia la derecha; ambas incluyen el carry dentro de la
operacin. Ya que la diferencia entre las dos rotaciones est slo en el sentido en que
se realiza, slo mostraremos los detalles de una de ellas, figura 5.
Instruccin:
ROTACION A LA IZQUIERDA
Sintaxis:
RLF
Codificacin:
Operacin:
f,d
Fuente
fffff
Estados afectados: C
Descripcin:
Carry
Registro Fuente
INSTRUCCION RRF
Carry
Registro Fuente
Figura 6. Rotaciones
84
La multiplicacin
Esta rutina se desarrolla con base en las instrucciones anteriormente descritas; aqu se
implementa la multiplicacin de dos cantidades, de un byte cada una. El diagrama de flujo
correspondiente se muestra en la figura 7 y el programa respectivo en la figura 8. Los
comentarios hechos en el programa informan sobre cada uno de los pasos desarrollados.
EMPEZAR
Contador = 8
Byte Alto = Byte Bajo = 0
W Multiplicando
Limpiar Carry
Rotar a la derecha
Multiplicador a travs
del Carry
SI
es
Carry = 1
?
Byte Alto =
Byte Alto + W
NO
NO
es
Contador
=1
?
SI
RETORNAR
Figura 7. Diagrama de
flujo de la multiplicacin
85
;=============================================================
;
Multiplicacin 8 x 8
;
El resultado (de 16 bits) es guardado en 2 bytes
;_____________________________________________________________
STATUS
CARRY
mulcnd
mulplr
H_byte
L_byte
count
Multip
loop
equ
equ
equ
equ
equ
equ
equ
03
00
19
10
12
13
14
;Registro de estados
;Bandera de acarreo
;Contiene Multiplicando
;Contiene Multiplicador
;Byte alto del resultado
;Byte bajo del resultado
;Contador del loop
org
goto
clrf
clrf
movlw
movwf
movf
bcf
rrf
btfsc
addwf
00
main
H_byte
L_byte
8
count
mulcnd,w
STATUS,CARRY
mulplr
STATUS,CARRY
H_byte
rrf
rrf
decfsz
H_byte
L_byte
count
goto
retlw
loop
0
;_____________________________________________________________
;
Programa de Prueba de la rutina
;_____________________________________________________________
main
movlw
0BA
;
movwf
mulplr
;
movlw
078
;
movwf
mulcnd
queda
call
Multip
goto
queda
END
La divisin
Esta es una operacin ampliamente utilizada en los microcontroladores y los
microprocesadores; permite la conversin de bases numricas de diverso tipo. El
diagrama de flujo se muestra en la figura 9 y el programa respectivo en la figura 10.
86
W DIVISOR
Dividendo = Dividendo W
Incrementar cociente
es
Carry = 1
?
SI
NO
Dividendo = Dividendo +W
RETORNAR
87
;==============================================================
;***
DIVIDE UN NUMERO DE UN BYTE ENTRE OTRO
***
; Divide un nmero binario existente en la posicin
; Divndo, entre otro localizado en posicin Divsor.
; El cociente se almacena en la misma posicin de memoria
; RAM del divisor y el residuo se guarda en
; la del dividendo.
;______________________________________________________________
STATUS
CARRY
Divndo
Divsor
Cocinte
Resduo
Div
Repite
SUM1
equ
equ
equ
equ
equ
equ
org
goto
movf
clrf
subwf
btfss
goto
incf
goto
addwf
RETLW
3
0
18
19
19
18
00
main
Divsor,w
Cocinte
Resduo
STATUS,CARRY
SUM1
Cocinte
Repite
Resduo
0
;Registro de estados
;Bit de acarreo
;Contiene nmero a dividir
;Contiene divisor
;Guarda el resultado
;Se almacena el residuo
;Restarle el divisor
;Verificar el carry
;Si cero, dejar de restar
;Si uno, incrementa cociente
;y repite resta divisor
;Sumarle divisor al residuo
; Regresa con 0`
;-------------------------------------------------------------;
PROGRAMA DE PRUEBA
;--------------------------------------------------------------
main
movlw
movwf
movlw
movwf
call
.254
Divndo
.10
Divsor
Div
queda
goto
queda
;Cargar
;el dividendo
;Cargar
;el divisor
;Llamar la subrutina
;El cociente es 19hex
;y el residuo 4hex
;Quedar en un loop infinito
END
;==============================================================
Cargar a
W con 100
Nmero = Nmero - W
Carry =1
?
SI
Incrementar
INC CENT
Centenas
NO
SUMAR 100
Cargar a
W con 10
Nmero = Nmero - W
Carry =1
?
SI
Incrementar
Decenas
NO
Sumar 10
TERMINAR
89
equ
equ
equ
equ
equ
equ
equ
3
0
1
18
19
1A
1B
;Registro de estados
;Bit de acarreo
;Bit de acarreo de dgito
;Para almacenar unidades
;Para almacenar decenas
;Registro para centenas
;Registro auxiliar
Bin_BCD
org
goto
clrf
clrf
movlw
00
main
Decena
Centena
.100
;Limpiar decenas
;Limpiar centenas
;Cargar a W con decimal 100
Otra
subwf
btfss
goto
incf
goto
Unidad
STATUS,CARRY
SUM
Centena
Otra
SUM
addwf
movlw
subwf
btfss
goto
incf
goto
Unidad
.10
Unidad
STATUS,CARRY
SUM1
Decena
Repite
;Sumarle 100
;cargar a W con 10
;Restarle al valor digital 10
;Verificar estado del carry
;Si cero, dejar de restar 10
;Si uno, incrementa decenas
;y repite la resta de 10
addwf
RETLW
Unidad
0
Repite
SUM1
;_____________________________________________________________
;
Programa de Prueba
;_____________________________________________________________
main
movlw
.254
;Cargar valor a convertir
movwf
Unidad
;el registro Unidad
queda
call
Bin_BCD
;Llamar la subrutina
;Centenas = 2
;Decenas = 5
;Unidades = 4
goto
queda
END
Realizar suma
C1 = Carry
es
DC = 1?
NO
es
LSD > 9
NO
SI
SI
SUMAR 6 a LSD
SUMAR 6 a MSD
C2 = Carry
es
C1 = 1
o
C2 = 1
?
NO
RETLW 0
SI
RETLW 1
91
movlw
addwf
6
Sum2
AdMSD
movlw
60
;Ajuste Binario-BCD para MSD
addwf
Sum2
;Sumar al resultado
btfsc
STATUS,CARRY
;Consultar carry
retlw
1
;si 1, retornar con 1
btfsc
Sum1,0
;si 0, probar carry inicio
retlw
1
;si hubo, retornar con 1
subwf
Sum2
;MSD < 9, retorna valor
RETLW
0
;Regresa con 0
;
;
Programa de Prueba
;
main
movlw
99
movwf
Sum1
;Sum1 = 99 (mximo nmero BCD)
movlw
99
movwf
Sum2
;Hacer Sum2 = 99
call
SumaBCDA
;Despus de suma, Sum2 = 98
movwf
Sum1
;y Sum1 = 01 (99+99 = 198)
queda
goto
queda
END
LEER TECLADO
NO
TECLA
PRESIONADA
?
SI
Nuestro teclado se encuentra conectado a las cuatro lneas del puerto A del microcontrolador, como se puede observar en las figuras 19 y 20. Para obtener el estado de las teclas, bastar con leer el puerto correspondiente y realizar un pequeo
tratamiento al dato ledo. En esta configuracin, para leer el teclado se realiza la
siguiente instruccin:
movf
Puerto_A,w
0
0
1
1
0
1
0
1
A .XOR. B
0
1
1
0
93
XOR
A la cantidad original (el hexadecimal 0A7h) se le realiza inicialmente la operacin XOR con el cdigo deseado (en este caso 76h) y al resultado (0D1h) se le
realiza de nuevo la operacin XOR con el mismo cdigo, dando como resultado el
valor original (el hexadecimal 0A7h); el lector puede intentar realizar esta operacin con cualquier nmero y observar que esto siempre se cumple.
Esta caracterstica se utiliza en sistemas en los cuales se necesita codificar o
encriptar una informacin, de tal manera que solamente el usuario original tenga
acceso a ella, ocultndola a los intrusos. La condicin para encriptar la informacin
es realizarle la operacin XOR (o la XNOR) con el cdigo de nuestro inters; la
decodificacin posterior exige realizarle de nuevo la operacin en cuestin con el
cdigo correspondiente. Este cdigo puede tener la longitud que desee el usuario.
En esta oportunidad, la operacin XOR la utilizaremos con el propsito de comparar dos cantidades, ya que cuando en los PICs resultan ser iguales, el operando
destino ser cero; por lo tanto, esta condicin activa (coloca en uno) la bandera de
Cero (Zero Flag), que corresponde al bit 2 del registro STATUS o de estados.
Existen dos versiones para esta instruccin en la familia de los microcontroladores PIC: XORWF y XORLW. En la Figura 17 se observan los detalles de las dos
instrucciones; ambas utilizan el registro de trabajo W y son muy convenientes para
consultar el estado de un registro, averiguando el momento en el cual se obtiene un
determinado valor. Consideremos los ejemplos para la instruccin XORWF que se
muestran en la figura 2: cuando los dos valores resultan ser iguales, el registro destino efectivamente se hace cero y la bandera Z se coloca en uno.
La instruccin XORLW acta de manera similar, con la salvedad que no acta
sobre dos registros, sino entre el registro de trabajo W y una constante de 8 bits que
reside en la memoria de programa; el destino siempre ser el registro de trabajo W.
Antes de la instruccin
Fuente
1
2
3
4
Instruccin
1001 0011
1010 1011
1010 1001
1101 1101
1001 0011
1010 1011
0110 1100
0001 0011
Despus de la instruccin
Fuente
XORWF Fuente,W
XORWF Fuente
XORWF Fuente,0
XORWF Fuente,1
1001 0011
0000 0000
1010 1001
1100 1110
0000 0000
1010 1011
1100 0101
0001 0011
1
1
0
0
En nuestro caso, la instruccin XOR nos servir para leer el teclado, ya que haremos la operacin OR Exclusiva con el nmero 0FF. Como se puede observar en las
figuras 19 y 20, al no presionar ninguna tecla la lectura que se obtiene del puerto es el
nmero binario 1111b, ya que las teclas normalmente estn colocadas a un nivel alto
a travs de resistencias de 10K. Cuando una tecla se presiona, se conectar a masa y
la lectura que se realice en ese momento ser un 0 lgico por el bit respectivo. Por lo
tanto, realizada la lectura del teclado y despus de guardar el valor en un registro o
posicin de la memoria RAM del microcontrolador, podemos realizar una operacin
XOR entre el valor ledo y 0FF. Si el resultado de la operacin es cero, significa que
ambas cantidades eran iguales (ninguna de las teclas se presion), la bandera de cero
se activar y este es el indicador que verificamos para determinar el siguiente paso a
seguir, como se puede observar en el diagrama de flujo del programa, figura 15.
Instruccin:
Sintaxis:
Codificacin:
Operacin:
Estados afectados:
Descripcin:
Instruccin:
Sintaxis:
Codificacin:
Operacin:
Estados afectados:
Descripcin:
OR Exclusiva
XORWF f,d
Cod. Op. dest Fuente
000110 d
fffff
(W .XOR. f) d
Z
Se realiza la operacin OR Exclusiva
entre el registro de trabajo W y el
registro fuente. Si d es cero, el resultado se almacena en el registro de
trabajo W; si d es uno, el resultado
se almacena en el registro fuente.
OR Exclusiva
XORLW k
Cod. Op.
Fuente
1111
kkkkkkkk
(W .XOR. k) W
Z
Al contenido del registro W se le reali
za la operacin OR Exclusiva con el
literal k de 8 bits. El resultado se
almacena en el registro de trabajo W.
95
+5V
+5V
5,1K
14
10K
16
18
17
RB6
OSC1
RB5
PIC 16C84
20 pF
RA3
RA2
RA1
RB3
RB2
RB0
VSS
11
10
RB4
RB1
RA0
12
8
10
9
1
7
330 x 7
g
f
e
d
c
b
a
DISPLAY DE ANODO
COMUN
Valor,w
Puerto_B
Para el control directo de los displays, se precisa un tratamiento diferente y debemos establecer nuestro propio decodificador por programa. En este caso, debemos tomar el valor binario del registro de inters y acudir a una tabla que contenga
los cdigos correspondientes para manejar cada uno de los LEDs del display de
siete segmentos. Las instrucciones respectivas seran algo como lo siguiente:
96
movf
call
movwf
Valor,w
tabla
Puerto_B
+5V
+5V
+5V
3
14
4
3
16
10K
8
18
17
OSC1
PIC 16C84
20 pF
RA3
RA2
RB3
RB2
RB1
RB0
9
8
7
6
6
2
1
7
16
LT
VCC RBIN
g
f
D
C
B
A
74LS47
5,1K
e
d
c
b
RA1
RA0
Gnd
VSS
5
8
10
g
15
9
f
9
1
e
10
2
d
11
4
c
12
6
b
13
7
a
330 x 7
DISPLAY DE ANODO
COMUN
14
addwf pc
retlw b11000000'
retlw b11111001'
retlw b10100100'
retlw b10110000'
retlw b10011001'
retlw b10010010'
retlw b10000010'
retlw b11111000'
retlw b10000000'
retlw b10011000'
;PC = PC + W
;cdigo para el 0
;cdigo para el 1
;cdigo para el 2
;cdigo para el 3
;cdigo para el 4
;cdigo para el 5
;cdigo para el 6
;cdigo para el 7
;cdigo para el 8
;cdigo para el 9
97
;============================================================
; La tabla establece en trminos de UNOS Y CEROS*
; el dato que se va a sacar por el display
*
; La tabla se considera para lgica negativa
*
; (Display de nodo comn)
*
;____________________________________________________________
cero
equ 2
PC
equ 2
Status
equ 3
Puerto_A
equ 5
Puerto_B
equ 6
dato
equ 18
tabla
98
org 00
goto inicio
;
;
addwf pc
;datos: .gfedcba
retlw b11000000'
retlw b11111001'
retlw b10100100'
retlw b10110000'
retlw b10011001'
retlw b10010010'
;PC = PC + W
;orden de los segmentos
;cdigo para el 0
;cdigo para el 1
;cdigo para el 2
;cdigo para el 3
;cdigo para el 4
;cdigo para el 5
Curso Bsico de Microcontroladores PIC
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
b10000010'
b11111000'
b10000000'
b10011000'
b10001000'
b10000011'
b11000110'
b10100001'
b10000110'
b10001110'
;cdigo
;cdigo
;cdigo
;cdigo
;cdigo
;cdigo
;cdigo
;cdigo
;cdigo
;cdigo
para
para
para
para
para
para
para
para
para
para
el
el
el
el
la
la
la
la
la
la
6
7
8
9
A
b
c
d
E
F
;____________________________________________________________
;*
ESTE ES EL PROGRAMA EN SI
*
;____________________________________________________________
inicio
movlw 00
;configurar puerto B como
tris puerto_B
;salidas
call tabla
;llama rutina
movwf puerto_B
;para mostrar 0 en display
movlw 0ff
;configura
tris puerto_A
;puerto A como entradas
leer
movf puerto_A,w
;lee estado de las teclas
movwf dato
;guardar dato
xorlw 0
;consultar si tecla
btfsc Status,cero
;presionada
goto leer
;si no tecla, vuelve y lee
movf dato,w
;si hubo, recupera valor
call tabla
;llama a rutina
movwf puerto_B
;Enva dato a LEDs
goto leer
;y vuelve a leer
end
99
100