Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Club 153
Club 153
PIC
PROGRAMACIÓN BÁSICA
Docentes de la
Escuela Superior de Cómputo (ESCOM)
Instituto Politécnico Nacional (IPN)
México
CONTENIDO
CONTENIDO ........................................................................................................................ 2
CAPÍTULO I. RUTINAS BÁSICAS..................................................................................... 3
1.1 CONFIGURACIÓN DE LOS PUERTOS COMO ENTRADA O SALIDA ...................... 3
1.2 LECTURA DE DATOS DE UN PUERTO ........................................................................... 5
1.3 ESCRITURA DE DATOS EN UN PUERTO ..................................................................... 11
1.4 ASIGNACIÓN DE DATOS A UN REGISTRO ................................................................. 16
1.5 INCREMENTO Y DECREMENTO DE DATOS DE LOS REGISTROS ...................... 23
1.5.1 Incremento o Decremento del dato de un registro en una unidad ....................................................23
1.5.2 Incremento o Decremento del dato de un registro en valores diferentes a la unidad .......................24
1.6 DISEÑO DE UN CONTADOR ............................................................................................ 25
1.6.1 Contador Ascendente .......................................................................................................................27
1.6.2 Contador Descendente .....................................................................................................................30
1.7 DISEÑO DE UN RETARDO BÁSICO POR BUCLES ..................................................... 32
1.8 SUMA ARITMÉTICA .......................................................................................................... 40
1.9 RESTA ARITMÉTICA ........................................................................................................ 51
1.10 MULTIPLICACIÓN ARITMÉTICA ............................................................................... 64
1.11 DIVISIÓN ARITMÉTICA ................................................................................................. 68
CAPÍTULO II. RUTINAS INTERMEDIAS ...................................................................... 73
2.1 FUNCIÓN LÓGICA AND Y SUS APLICACIONES........................................................ 73
2.2 FUNCIÓN LÓGICA OR Y SUS APLICACIONES .......................................................... 77
2.3 FUNCIÓN LÓGICA XOR Y SUS APLICACIONES ....................................................... 82
2.4 FUNCIONES LÓGICAS DE COMPARACIÓN ENTRE REGISTROS (=, <, >) .......... 85
2.4.1 Comparación IGUAL (=) ó DIFERENTE (≠) .................................................................................86
2.4.2 Comparación MENOR QUE (<) ó MAYOR O IGUAL QUE (≥)...................................................92
2.4.3 Comparación MAYOR QUE (>) ó MENOR O IGUAL QUE (≤)...................................................98
2.5 LECTURA DE UN TECLADO MATRICIAL................................................................. 103
2.6 CONFIGURACIÓN DE LAS INTERRUPCIONES ....................................................... 114
2.7 IMPLEMENTACIÓN DE UN RETARDO POR TIMER .............................................. 120
2.7.1 El TIMER de 8 bits (TMR0) ..........................................................................................................122
2.7.2 El TIMER de 16 bit s (TMR1) .......................................................................................................128
2.8 CONFIGURACIÓN DE LA USART ................................................................................ 136
2.8.1 USART en modo Transmisión (Tx) ..............................................................................................138
2.8.2 USART en modo Recepción (Rx) .................................................................................................146
2
CAPÍTULO I. RUTINAS BÁSICAS
3
A continuación describiremos la manera en que tienen que ser configurados los
puertos de un microcontrolador PIC, y para ello, nos basaremos en 4
microcontroladores PIC de diferentes tamaños, los cuales tomaremos como
modelo y a partir de estos, podremos realizar cualquier aplicación, no importando
la cantidad de terminales que posean los microcontroladores, ya que lo importante
es aprender a configurarlos y obtener el máximo beneficio de sus herramientas
internas.
Cabe aclarar, que los microcontroladores que cuentan con un solo puerto como
es el caso del PIC12F629, el registro de configuración de su puerto
correspondiente, tan solo recibe el nombre de ―tr
isio‖, ya que no es necesario
especificarle de que puerto se trata, por el hecho de que solo posee uno.
2
Matrícula Registro de Configuración
del PIC trisa trisb trisc Trisd trise trisio
PIC12F629 ---- ---- ---- ---- ---- 85h
PIC16F628A 85h 86h ---- ---- ---- ----
PIC16F876 85h 86h 87h ---- ---- ----
PIC16F877 85h 86h 87h 88h 89h ----
Tabla 1. Ubicación de los registros de configuración de algunos
microcontroladores PIC.
Todos los registros tris (configuración de puertos) de los diferentes puertos que
poseen los microcontroladores PIC, se encuentran conformados por 8 bits, los
cuales dependiendo del estado lógico en el que se encuentren, será la forma de
como se configure su correspondiente puerto, ya sea como entrada o salida.
3
un puerto ya sea como entrada o como salida, si no dependiendo de la aplicación
un mismo puerto puede ser configurado por ejemplo mitad como entrada y mitad
como salida, por lo tanto el registro tris podría quedar como:
Para acceder a cualquiera de los registros tris se tiene que apuntar en primera
instancia al banco 1 del mapa de memoria de datos, para ello se tienen que
manipular los bits rp0 y rp1 del registro ―stat
us‖. Por otra parte suponga que se
requiere configurar al puerto A como entrada y en el puerto B el nible superior
como entrada y el nible inferior como salida. A continuación se muestra a
manera de sugerencia el código para realizar las acciones antes descritas, sobre
microcontroladores que cuentan con más de un puerto.
4
Aunque todos los registros de configuración tris son de 8 bits, en el PIC12F629
solo son empleados los 6 bits de más bajo peso, por lo que los bits 6 y 7 los
colocamos en ―0‖ (de todas maneras son colocados en el estado lógico ―0‖ de
manera automática).
5
; Programa de prueba para leer el puerto B
LIST P=PIC16F876 ;Aquí se coloca la matricula del microcontrolador
;que vaya a emplearse
;=============================================================
; Declaración de registros
;=============================================================
portb equ 0x06
status equ 0x83
trisb equ 0x86
temporal equ 0x20
;=============================================================
; Declaración de bits
;=============================================================
rp0 equ 0x05
rp1 equ 0x06
;=============================================================
; Vector del reset
;=============================================================
reset
org 0
goto inicio
;=============================================================
; Inicio del programa principal
;=============================================================
inicio
bsf status,rp0 ;cambia al banco 1
bcf status,rp1
movlw b’11111111’ ;configura al puerto B como entrada
movwf trisb
bcf status,rp0 ;cambia al banco 0
bcf status,rp1
movf portb,0 ;el dato del puerto es cargado al registro W
movwf temporal ;el valor del registro W se aloja en el registro
;temporal.
goto inicio
6
; Programa de prueba para leer el puerto A ; Programa de prueba para leer el puerto A
LIST P=PIC16F628A ;Aquí se coloca la matricula del microcontrolador LIST P=PIC16F876 ;Aquí se coloca la matricula del microcontrolador
;que vaya a emplearse ;que vaya a emplearse
;============================================================= ;=============================================================
; Declaración de registros ; Declaración de registros
;============================================================= ;=============================================================
porta equ 0x05 porta equ 0x05
cmcon equ 0x1f status equ 0x83
status equ 0x83 trisa equ 0x85
trisa equ 0x85 adcon1 equ 0x9f
temporal equ 0x20 temporal equ 0x20
;============================================================= ;=============================================================
; Declaración de bits ; Declaración de bits
;============================================================= ;=============================================================
rp0 equ 0x05 rp0 equ 0x05
rp1 equ 0x06 rp1 equ 0x06
;============================================================= ;=============================================================
; Vector del reset ; Vector del reset
;============================================================= ;=============================================================
reset reset
org 0 org 0
goto inicio goto inicio
;============================================================= ;=============================================================
; Inicio del programa principal ; Inicio del programa principal
;============================================================= ;=============================================================
inicio inicio
bsf status,rp0 ;cambia al banco 1 bsf status,rp0 ;cambia al banco 1
bcf status,rp1 bcf status,rp1
movlw b’11111111’ ;configura al puerto A como entrada movlw b’11111111’ ;configura al puerto A como entrada
movwf trisa movwf trisa
bcf status,rp0 ;cambia al banco 0 movlw b’00000111’ ;selecciona 0 (cero) comparadores en el
bcf status,rp1 movwf adcon1 ;registro adcon1 (deshabilita los ADC)
movlw b’00000111’ ;selecciona 0 (cero) comparadores en el bcf status,rp0 ;cambia al banco 0
movwf cmcon ;registro cmcon (deshabilita los bcf status,rp1
;comparadores) movf porta,0 ;el dato del puerto es cargado al registro W
movf porta,0 ;el dato del puerto es cargado al registro W movwf temporal ;el valor del registro W se aloja en el registro
movwf temporal ;el valor del registro W se aloja en el registro ;temporal.
;temporal. goto inicio
goto inicio
Todos los registros port se encuentran constituidos por 8 bits, los cuales
indican el estado lógico en que se encuentran las terminales físicas del puerto en
cuestión del microcontrolador PIC. Para leer todos los bits de un puerto se
puede emplear el comando de lectura de un registro, indicando en la instrucción el
puerto que tendrá que ser intervenido, para una mayor referencia observe el
7
ejemplo que se ilustra en la tabla 2. Este código es valido para todos los
puertos exceptuando al puerto A de los microcontroladores PIC, por otra parte
también se indica el direccionamiento del banco donde se encuentran los registros
que serán empleados, actividad que se implementa por medio de la manipulación
de los bits ―r
p0‖ y ―r
p1‖ del registro ―stat
us‖.
Hasta este punto hemos revisado de qué manera se leen los puertos A ó B ó
C, etc., de microcontroladores que poseen más de un puerto (el PIC16F628A
cuenta con 2 puertos y el PIC16F876 cuenta con 3 puertos) como entrada, pero
también podemos encontrarnos con microcontroladores que posean tan solo un
puerto único, por lo tanto debemos de ser capaces de poder trabajar con el
microcontrolador de un solo puerto.
8
; Programa de prueba para leer el puerto de un PIC de 8 terminales
LIST P=PIC12F629 ;Aquí se coloca la matricula del microcontrolador
;que vaya a emplearse
;=============================================================
; Declaración de registros
;=============================================================
w equ 00h
status equ 0x03
gpio equ 0x05
cmcon equ 0x19
trisio equ 0x85
osccal equ 0x90
var1 equ 0x20
;=============================================================
; Declaración de Bits
;=============================================================
c equ 0 ;carry (acarreo)
z equ 2 ;bit del cero
rp0 equ 5 ;registro de selección de banco
;=============================================================
; Inicio
;=============================================================
reset org 0
goto inicio
;=============================================================
; programa principal
;=============================================================
inicio
bcf status,rp0 ;cambiar al banco 0
movlw b’00000111’ ;selecciona 0 (cero) comparadores en el
movwf cmcon ;registro cmcon (deshabilita los comparadores)
bsf status,rp0 ;cambiar al banco 1
movlw b'00111111' ;configura los bits 0, 1, 2 , 3, 4 y 5 del puerto GPIO
movwf trisio ;como entradas (solo contiene 6 bits).
movlw b'11111100' ;configura el oscilador interno en su velocidad
movwf osccal ;máxima (4 Mhz).
ciclo
bcf status,rp0 ;cambiar al banco 0
movf gpio,w
movwf var1
goto ciclo
Tabla 4. Utilización del puerto GPIO de un PIC de 8 terminales para
leer datos.
Dentro de los microcontroladores PIC, uno de los que cuenta con un solo
puerto es el que se identifica por medio de la matricula PIC12F629, el cual posee
8 terminales de las cuales 2 son para alimentación, por lo que sobra un puerto de
tan solo 6 bits. En este caso se trata de un microcontrolador que podemos
considerar como ―e
nano‖ pero no por ello restringido en su operación, por el
contrario todo depende de la aplicación que queramos realizar, y si esta no
9
requiere de muchas terminales de entrada, el PIC12F629 es muy adecuado.
Por último se tiene que recordar que para interactuar con algún registro, se
10
tiene que direccionar al banco adecuado. El PIC12F629 solo cuenta con 2
bancos, por lo tanto basta con manipular el bit ―r
p0‖ del registro status para
acceder al banco adecuado.
Sin tomar en cuenta la cantidad de bits que conforman a los puertos de los
microcontroladores PIC, estos pueden ser configurados para que se pueda
―
escribir‖ algún dato hacia el exterior del microcontrolador, para ello, una vez que
se tiene el correspondiente circuito de aplicación debidamente configurado, se
graba en el microcontrolador PIC el programa por medio del cual realizara la tarea
de enviar un dato digital hacia el exterior del microcontrolador.
11
; Programa de prueba para escribir en el puerto B
LIST P=PIC16F876 ;Aquí se coloca la matricula del microcontrolador
;que vaya a emplearse
;=============================================================
; Declaración de registros
;=============================================================
portb equ 0x06
status equ 0x83
trisb equ 0x86
temporal equ 0x20
;=============================================================
; Declaración de bits
;=============================================================
rp0 equ 0x05
rp1 equ 0x06
;=============================================================
; Vector del reset
;=============================================================
reset
org 0
goto inicio
;=============================================================
; Inicio del programa principal
;=============================================================
inicio
bsf status,rp0 ;cambia al banco 1
bcf status,rp1
movlw b’00000000’ ;configura al puerto B como salida
movwf trisb
bcf status,rp0 ;cambia al banco 0
bcf status,rp1
movf temporal,0 ;el dato del registro temporal es cargado a W
movwf portb ;escribe el dato de W en el puerto B
goto inicio
Tabla 5. Utilización del puerto B de cualquier microcontrolador PIC
para escribir datos.
Para escribir un dato en todos los bits de un puerto se puede emplear el
comando de escritura sobre un registro, indicando en la instrucción el puerto que
tendrá que ser intervenido, para una mayor referencia observe el ejemplo que se
ilustra en la tabla 5. El código de la tabla 5 es valido para intervenir todos los
puertos de un microcontrolador PIC exceptuando al puerto A de los PIC, por otra
parte también se indica el direccionamiento del banco donde se encuentran los
registros que serán empleados, por medio de la manipulación de los bits ―r
p0 y
rp1‖ del registro ―
status‖, que de acuerdo al banco donde se ubiquen los diferentes
registros de configuración, se tendrá que colocar la combinación adecuada en los
bits rp0 y rp1.
12
; Programa de prueba para escribir un dato en el puerto A ; Programa de prueba para escribir un dato en el puerto A
LIST P=PIC16F628A ;Aquí se coloca la matricula del microcontrolador LIST P=PIC16F876 ;Aquí se coloca la matricula del microcontrolador
;que vaya a emplearse ;que vaya a emplearse
;============================================================= ;=============================================================
; Declaración de registros ; Declaración de registros
;============================================================= ;=============================================================
porta equ 0x05 porta equ 0x05
cmcon equ 0x1f status equ 0x83
status equ 0x83 trisa equ 0x85
trisa equ 0x85 adcon1 equ 0x9f
temporal equ 0x20 temporal equ 0x20
;============================================================= ;=============================================================
; Declaración de bits ; Declaración de bits
;============================================================= ;=============================================================
rp0 equ 0x05 rp0 equ 0x05
rp1 equ 0x06 rp1 equ 0x06
;============================================================= ;=============================================================
; Vector del reset ; Vector del reset
;============================================================= ;=============================================================
reset reset
org 0 org 0
goto inicio goto inicio
;============================================================= ;=============================================================
; Inicio del programa principal ; Inicio del programa principal
;============================================================= ;=============================================================
inicio inicio
bsf status,rp0 ;cambia al banco 1 bsf status,rp0 ;cambia al banco 1
bcf status,rp1 bcf status,rp1
movlw b’00000000’ ;configura al puerto A como salida movlw b’00000000’ ;configura al puerto A como salida
movwf trisa movwf trisa
bcf status,rp0 ;cambia al banco 0 movlw b’00000111’ ;selecciona 0 (cero) comparadores en el
bcf status,rp1 movwf adcon1 ;registro adcon1 (deshabilita los ADC)
movlw b’00000111’ ;selecciona 0 (cero) comparadores en el bcf status,rp0 ;cambia al banco 0
movwf cmcon ;registro cmcon (deshabilita los bcf status,rp1
;comparadores) movf temporal,0 ;el dato del registro temporal es cargado a W
movf temporal,0 ;el dato del registro temporal es cargado a W movwf porta ;escribe el dato de W en el puerto A
movwf porta ;escribe el dato de W en el puerto A goto inicio
goto inicio
13
Para realizar la actividad de deshabilitación de ADC ó comparadores, basta
con seleccionar 0 (cero) ADC’s ó 0 (cero) comparadores de voltaje, tal como se
ilustra en los fragmentos de código de los programas de la tabla.
Dentro de la familia de los microcontroladores PIC, uno de los que cuenta con
un solo puerto es el que se identifica por medio de la matricula PIC12F629, el cual
posee 8 terminales de las cuales 2 son para que sea energizado (terminales Vdd y
Vss), por lo que sobra un puerto de tan solo 6 bits. En este caso se trata de un
microcontrolador pequeño que pudiera ser considerado como restringido en
cuanto a su cantidad de terminales, pero no en su operación, por el contrario todo
depende de la aplicación que se tenga que realizar, ya que si esta no requiere de
muchas terminales de salida, el PIC12F629 es un microcontrolador muy
adecuado.
14
;Programa de prueba para escribir datos en un PIC de 8 terminales
LIST P=PIC12F629 ;Aquí se coloca la matricula del microcontrolador
;que vaya a emplearse
;=============================================================
; Declaración de registros
;=============================================================
w equ 00h
status equ 0x03
gpio equ 0x05
cmcon equ 0x19
trisio equ 0x85
osccal equ 0x90
var1 equ 0x20
;=============================================================
; Declaración de Bits
;=============================================================
c equ 0 ;carry (acarreo)
z equ 2 ;bit del cero
rp0 equ 5 ;registro de selección de banco
;=============================================================
; Inicio
;=============================================================
reset org 0
goto inicio
;=============================================================
; programa principal
;=============================================================
inicio
bcf status,rp0 ;cambiar al banco 0
movlw b’00000111’ ;selecciona 0 (cero) comparadores en el
movwf cmcon ;registro cmcon (deshabilita los comparadores)
bsf status,rp0 ;cambiar al banco 1
movlw b'00001000' ;configura todos los bits (con excepción del 3) del
movwf trisio ;puerto como salidas (solo contiene 6 bits).
movlw b'11111100' ;configura el oscilador interno en su velocidad
movwf osccal ;máxima (4 Mhz).
ciclo
bcf status,rp0 ;cambiar al banco 0
movf var1,w
movwf gpio
goto ciclo
Tabla 7. Utilización del puerto GPIO de un PIC de 8 terminales para
escribir datos.
15
registro ―g
pio‖ para enviar hacia el exterior del microcontrolador algún dato, para
que se refleje en las terminales del microcontrolador. Para emplear la totalidad
de las terminales del PIC12F629, es necesario habilitar al oscilador interno del
PIC, para que se puedan emplear las 2 terminales dedicadas al oscilador como
salidas discretas (GP4 y GP5), además de deshabilitar la terminal del reset
externo denominado MCLR, para contar con la terminal GP3 exclusivamente como
―
entrada‖. Por otra parte, cuando se habilita al oscilador interno, se tiene que
seleccionar la frecuencia de operación, por lo que en el registro ―oscca
l‖ se ingresa
el valor binario ―11
111100‖ que selecciona la frecuencia máxima de operación que
es de 4 Mhz. El PIC12F629 en las terminales identificadas como GP0 y GP1
cuentan a la vez con comparadores de voltaje, mismos que tienen que ser
deshabilitados para emplear dichas terminales como salidas digitales, siendo
mediante la carga del valor binario ―00
000111‖ en el registro ―cm
con‖.
Por último se debe de tomar en cuenta que para interactuar con algún registro,
se tiene que direccionar al banco adecuado. El PIC12F629 solo cuenta con 2
bancos, por lo tanto, basta con manipular el bit ―r
p0‖ del registro status para
acceder al banco adecuado.
16
Para comenzar a trabajar con los registros, la primera actividad a desarrollar es
la que lleva por nombre ―de
claración‖ de registros, o sea se le tiene que indicar al
programa editor (que en el caso de los microcontroladores PIC es el MPLAB) que
se va emplear por ejemplo el registro ―tr
isa‖.
w equ 00h
status equ 0x03
trisa equ 0x85
trisb equ 0x86
porta equ 0x05
portb equ 0x06
cmcon equ 0x1f
var1 equ 0x20
var2 equ 0x21
var3 equ 0x22
var4 equ 0x23
var5 equ 0x24
var6 equ 0x25
var7 equ 0x26
var8 equ 0x27
var9 equ 0x28
var10 equ 0x29
var11 equ 0x2a
var12 equ 0x2b
var13 equ 0x2c
var14 equ 0x2d
var15 equ 0x2e
var16 equ 0x2f
var17 equ 0x30
Tabla 8. Declaración de registros, para su empleo posterior.
Recordemos que se pueden clasificar de forma general en 2 conjuntos los
registros que emplearemos, los cuales conocemos como registros de
configuración y registros de propósito general, estos últimos también tienen la
tarea de almacenar datos ya que se trata de registros que se encuentran
implementados sobre memoria RAM. A continuación marcaremos un mayor
énfasis sobre los registros de propósito general, sin olvidar a los registros de
configuración.
Una vez que fueron declarados los registros con los que trabajaremos, ya los
podemos emplear para escribirles o leerles el dato que contengan, por lo tanto, en
el ejemplo que se muestra sobre un listado en el fragmento de programa descrito
en la tabla 8, se declaran los registros que serán empleados, resaltando de
17
una manera particular a los registros de propósito general que son los que
funcionaran como localidades de memoria RAM. De la tabla 8 se observa que
se tienen que declara una serie de registros que se denominan ―v
ar1‖, ―
var2‖,
―v
ar3‖, etc. Lo importante es que ocupan las localidades de los registros que
van de la 20h a la 30 h, además de que son localidades continuas. Se debe de
tener en cuenta que si por alguna razón se requiere insertar un nuevo registro por
ejemplo entre los identificados como var7 y var8, posteriormente se tienen que
enumerar nuevamente las localidades recorriendo los números de registro que a
cada una le corresponde de tal manera, que de nueva cuenta queden ordenadas.
w equ 00h
status equ 0x03
trisa equ 0x85
trisb equ 0x86
porta equ 0x05
portb equ 0x06
cmcon equ 0x1f
CBLOCK 0x20 ;Define donde comienza la declaración de registros
var1
var2
var3
var4
var5
var6
var7
var8
var9
var10
var11
var12
var13
var14
var15
var16
var17
ENDC ;Define donde termina la declaración de registros
Tabla 9. Declaración de un bloque de registros, para asignación
automática de localidades.
18
―eq
u‖ la localidad que le corresponde a cada registro. Tan solo tenemos que
enumerar a todos los registros que tenemos que emplear y al comienzo del bloque
le colocamos el comando ―C
BLOCK‖, indicándole cual será la primera localidad
que tendrá que ocuparse, tal como se muestra en la ejemplo ―C
BLOCK 0x20‖, tal
como aparece en la tabla 9.
19
dentro del bloque y de manera automática le proporcionara una localidad.
20
;==========================================
LIST P=PIC16F628A ; Programa principal
;========================================= ;==========================================
; Declaración de registros inicio
;========================================= bcf status,rp1 ;Direcciona el banco 1
w equ 0x00 bsf status,rp0
indf equ 0x00 movlw 0xff
status equ 0x03 movwf trisa ;Los bits del Puerto a como entradas
fsr equ 0x04 movlw 0x00
porta equ 0x05 movwf trisb ;Los bits del Puerto b como salidas
portb equ 0x06 bcf status,rp1 ;Direcciona el banco 0
trisa equ 0x85 bcf status,rp0
trisb equ 0x86 movlw 0x07
cmcon equ 0x1f movwf cmcon
CBLOCK 0x20 ;Define donde comienza la declaración de otro
registros bcf status,rp1 ;Direcciona el banco 0
var1 bcf status,rp0
var2 movlw 0x20 ;indica la primera localidad a manipular
var3 movwf fsr
var4 ciclo
var5 movf porta,w ;lee un dato del puerto a
var6 movwf indf ;aloja el dato en el registro indirecto
var7 movlw 0x30 ;verifica si se trata del ultimo registro
var8 xorwf fsr,w
var9 btfsc status,z
var10 goto otro
var11 incf fsr,1
var12 goto ciclo
var13 end
var14
var15
var16
var17
ENDC ;Define donde termina la declaración de registros
;==========================================
; Declaración de bits
;==========================================
z equ 0x02
rp0 equ 0x05
rp1 equ 0x06
;==========================================
; Vector del Reset
;==========================================
org 0x00
goto inicio
21
que será escrita o leída de la localidad de memoria RAM que se esta
direccionando por medio del registro FRS. Para una mejor comprensión observe
la figura 2, en la cual se muestra que con los bits del 0 al 6 del registro FSR se
direcciona una localidad de memoria RAM, mientras que la combinación generada
mediante los bits 7 del registro FSR y el bit IRP del registro STATUS se puede
acceder a cualquiera de los 4 bancos de memoria que posee un microcontrolador
PIC.
22
memoria de registros del microcontrolador PIC, que para el registro ―i
ndf‖ se trata
de la localidad 00h, y para el registro ―
fsr‖ de la localidad 04h.
23
a) incf registroX,1 ;Incrementa en una unidad el dato del registro X
alojando el resultado final dentro del mismo registro X1.
1
Refiérase a la explicación de las instrucciones que se encuentra en el capitulo ―i
nstrucciones orientadas al
control de registros dentro del Modulo I.
24
unidad, se tienen las instrucciones de suma o resta respectivamente, las cuales se
muestran junto con su sintaxis completa:
2
Refiérase a la explicación de las instrucciones que se encuentra en el capitulo ―i
nstrucciones orientadas al
control de registros dentro del Modulo I.
25
que revisar que no se haya rebasado la cantidad de eventos a realizarse, por lo
que ahora, la actividad siguiente es la de comparar el valor que se encuentra
dentro del registro contador, con el valor máximo de eventos que tienen que
realizarse. Si el valor que se encuentra alojado en el registro contador, aun no
alcanza el valor máximo, entonces el proceso tiene que repetirse una vez más, por
lo tanto, se tendrá que realizar nuevamente el evento de la actividad que se esta
controlando. De otra manera, si el valor del registro contador es igual al valor
máximo de los eventos que tienen que realizarse, entonces el programa tendrá
que realizar una actividad diferente de la que estaba controlado con el contador,
dando por terminado el contador y accediendo a un nuevo proceso.
26
estructura del contador es la misma que se ha mostrado previamente, y a
continuación se muestra la estructura de los distintos tipos de contador.
27
LIST P=PIC16F628A LIST P=PIC16F628A
;========================================= ;=========================================
; Declaración de registros ; Declaración de registros
;========================================= ;=========================================
w equ 0x00 w equ 0x00
status equ 0x03 status equ 0x03
porta equ 0x05 porta equ 0x05
portb equ 0x06 portb equ 0x06
trisa equ 0x85 trisa equ 0x85
trisb equ 0x86 trisb equ 0x86
cmcon equ 0x1f cmcon equ 0x1f
contador equ 0x20 contador equ 0x20
;========================================= ;==========================================
; Declaración de bits ; Declaración de bits
;========================================= ;==========================================
z equ 0x02 z equ 0x02
rp0 equ 0x05 rp0 equ 0x05
rp1 equ 0x06 rp1 equ 0x06
;========================================= ;==========================================
; Vector del Reset ; Vector del Reset
;========================================= ;==========================================
org 0x00 org 0x00
goto inicio goto inicio
;========================================= ;==========================================
; Programa principal ; Programa principal
;========================================= ;==========================================
inicio inicio
bcf status,rp1 ;Direcciona el banco 1 bcf status,rp1 ;Direcciona el banco 1
bsf status,rp0 bsf status,rp0
movlw 0xff movlw 0xff
movwf trisa ;Los bits del Puerto a como entradas movwf trisa ;Los bits del Puerto a como entradas
movlw 0x00 movlw 0x00
movwf trisb ;Los bits del Puerto b como salidas movwf trisb ;Los bits del Puerto b como salidas
bcf status,rp1 ;Direcciona el banco 0 bcf status,rp1 ;Direcciona el banco 0
bcf status,rp0 bcf status,rp0
movlw 0x07 movlw 0x07
movwf cmcon movwf cmcon
otro otro
bcf status,rp1 ;Direcciona el banco 0 bcf status,rp1 ;Direcciona el banco 0
bcf status,rp0 bcf status,rp0
movlw 0x00 ;inicia el registro contador movlw 0x00 ;inicia el registro contador
movwf contador movwf contador
conteo conteo
movf porta,w ;lee un dato del puerto a movf porta,w ;lee un dato del puerto a
movwf portb movwf portb
incf contador,1 ;incrementa registro contador movlw 0x01
movlw 0x05 ;verifica el valor máximo del contador addwf contador,1 ;incrementa registro contador
xorwf contador,w movlw 0x05 ;verifica el valor máximo del contador
btfsc status,z xorwf contador,w
goto otro btfsc status,z
goto conteo goto otro
end goto conteo
end
28
―i
ncrementar‖ el dato del valor del registro contador aun no es igual al valor
máximo, entonces se tiene que aplicar un nuevo incremento al registro contador, y
así sucesivamente hasta que alcance su valor total.
29
1.6.2 CONTADOR DESCENDENTE
30
instrucciones ―de
cf‖ o ―sub
wf‖ respectivamente.
31
decrementa unidad por unidad (decf), mientras que en el segundo programa el
decremento se realiza mediante una instrucción de resta (subwf), en la cual se
puede definir el valor del decremento, mediante un dato que se guarda
previamente en el registro de trabajo W.
32
cual esta implementado el retardo.
33
el microcontrolador se quedara cautivo realizando la actividad de controlar al
temporizador.
34
movlw 0x02
movwf contador
bucle
decfsz contador,1 ; 1 ó 2 ciclos.
goto bucle ; 2 ciclos.
instrucciones de un proceso siguiente
.
.
.
end
Tabla 15. Cantidad de ciclos que consumen las instrucciones de un
temporizador.
La instrucción ―de
cfsz‖ lleva a cabo el decremento del valor de un registro, y
mientras no llegue a cero el valor del registro decrementado, se ejecuta la
instrucción que se encuentra expresada debajo de decfsz, consumiendo esta
actividad 1 ciclo. Pero si al ejecutar la instrucción decfsz el valor del registro
decrementado alcanzo el valor de cero, se provoca un brinco, por lo tanto, el
microcontrolador omitirá la ejecución de la instrucción siguiente, pasando a la que
se encuentra en segundo término después de decfsz, teniéndose en esta actividad
el consumo de 2 ciclos.
35
―con
tador‖ es 02h, por lo que después de ejecutar la instrucción, el valor que ahora
se encontrara en el registro contador será el de 01h; como el resultado en el
registro contador no fue cero, la ejecución de la instrucción ―d
ecfsz contador,1‖
será de 1 ciclo; posteriormente se lleva a cabo la ejecución de ―g
oto bucle‖, esta
instrucción consume 2 ciclos, y provoca que se lleve a cabo un brinco al lugar
donde se encuentra la etiqueta bucle, preparando una nueva secuencia en el
control del temporizador; de manera acumulada en esta etapa se tiene un total de
3 ciclos.
PASO 1 PASO 2
36
terminado el proceso del temporizador; el paso 2 proporciona un total de 2 ciclos.
La suma de los ciclos totales del paso 1 con los del paso 2, dan un total de 5
ciclos que son los que se consumen en el temporizador, observe la tabla 16.
Para determinar el tiempo que se consumió con la ejecución de los 5 ciclos del
programa temporizador, se debe calcular el tiempo que consume cada ciclo de
manera independiente, para ello nos basaremos en las relaciones que son
mostradas en la tabla 17.
Foscilador
Ciclo de instrucción o ciclo =
4
Si la frecuencia del oscilador es de 4 MHz, entonces:
4Mhz
Ciclo de instrucción o ciclo = = 1 MHz.
4
1
El tiempo que tarda cada ciclo de instrucción es =
Ciclo _ de _ instrucció n
1
El tiempo de cada ciclo es = = 1 μseg.
1MHz
Por lo tanto para 5 ciclos se tiene un tiempo de: (5 Ciclos) * (1 μseg) = 5 μseg.
37
instrucción goto. Esto último significa que los 3 ciclos resultantes se repetirán
165 veces, porque el dato que esta guardado en el registro ―
contador‖ se estará
decrementando unidad por unidad, comenzando por valor de 16610 hasta llegar a
110. En la tabla 18 se muestra en la parte correspondiente al paso 1 la
cantidad de ciclos que se acumulan mientras en valor en el registro ―con
tador‖ es
mayor que cero.
PASO 1 PASO 2
Para calcular el tiempo en el que se ejecutan los 497 ciclos, se hace referencia
a las relaciones matemáticas de la tabla 17, por lo que supongamos que se tiene
un oscilador de 4 Mhz, con el que nos arrojara un término de 1 μseg, para cada
ciclo que es ejecutado, por lo tanto, los 497 ciclos son ejecutados en 497 μseg,
que a su vez es un valor muy cercano a 500 μseg, que también puede
38
interpretarse como 0.5 mseg. El tiempo de 0.5 mseg lo podemos tomar como
base para a partir de este valor generar temporizadores más grandes, tal como se
muestra en los ejemplos de la tabla 19.
EJEMPLO 1 EJEMPLO 2
movlw .08 ;repite 8 veces la base de tiempo. movlw .255 ;repite 255 veces la temporIzación
movwf var2 movwf var3 ;de 4 mseg.
ciclo_2 ciclo_3
movlw .166 movlw .08
movwf var1 movwf var2
ciclo_1 ciclo_2
decfsz var1,1 ;base de tiempo de 0.5 mseg. movlw .166
goto ciclo_1 movwf var1
decfsz var2,1 ciclo_1
goto ciclo_2 decfsz var1,1 ;base de 0.5 mseg.
….…. goto ciclo_1
otras instrucciones decfsz var2,1
goto ciclo_2
0.5 mseg * 8 veces = 4 mseg decfsz var3,1
goto ciclo_3
….….
otras instrucciones
Por último, se recomienda que para implementar una rutina con temporizador
dentro de un programa, se realice por medio de la invocación de una subrutina,
para que cuando esta agote el tiempo que ha sido establecido mediante el cálculo
correspondiente, el programa continué con la secuencia normal en cuanto a la
ejecución de las instrucciones, y cuando nuevamente requiera ser empleada la
rutina del temporizador, nuevamente sea llamada mediante un servicio de
subrutina.
39
LIST P=PIC16F628A movlw b'00000111'
;------------------------------------------------------------ movwf cmcon
; Declaración de Registros Ciclo
;------------------------------------------------------------ bcf status,rp0 ;cambiar al banco 0
w equ 00h bcf status,rp1
status equ 0x03 btfsc porta,1
porta equ 0x05 goto sipresionado
portb equ 0x06 goto nopresionado
trisa equ 0x85 nopresionado
trisb equ 0x86 bcf portb,2
cmcon equ 0x1f call temporizador
var1 equ 0x20 goto ciclo
var2 equ 0x21 sipresionado
var3 equ 0x22 bsf portb,2
;------------------------------------------------------------ call temporizador
; Declaración de Bits goto ciclo
;------------------------------------------------------------ ;---------------------------------------------
c equ 0 ;carry (acarreo) ;Subrutina
z equ 2 ;bit del cero ;---------------------------------------------
rp0 equ 5 ;registro de selección de banco temporizador ;Retardo de 1 segundo
rp1 equ 6 ; movlw .255
;------------------------------------------------------------ movwf var1
; Inicio ciclo_3
;------------------------------------------------------------ movlw .08
reset org 0 movwf var2
goto inicio ciclo_2
;------------------------------------------------------------ movlw .166
; programa principal movwf var3
;------------------------------------------------------------ ciclo_1
inicio decfsz var3,1 ;0.5 milisegundos
bsf status,rp0 ;cambiar al banco 1 goto ciclo_1
bcf status,rp1 decfsz var2,1
movlw 0xff ;Puerto A como entradas goto ciclo_2
movwf trisa decfsz var1,1
movlw 0x00 ;Puerto B como salidas goto ciclo_3
movwf trisb return
bcf status,rp0 ;cambiar al banco 0 end
bcf status,rp1
40
algún microcontrolador, motivo por el cual en primera instancia comenzaremos
con la operación de la suma aritmética, y para ello recordaremos la manera en
como aprendimos a realizarla en nuestros estudios primarios, ya que para efectos
de programación en un microcontrolador se hace de la misma manera.
EJEMPLO 1 EJEMPLO 2
2 1 Digito 5 1 Digito
+ 3 1 Digito + 6 1 Digito
============= =============
= 0 5 1 Digito = 1 1 2 Dígitos
Resultado Resultado
Acarreo Acarreo
Tabla 21. Ejemplos de una suma aritmética con números decimales.
Del ejemplo 1 mostrado en la tabla 21, se observa la suma de 2 números cuya
magnitud es de un digito respectivamente (2 + 3), el resultado de la suma se
expresa de igual manera mediante un solo digito (5), por lo tanto se asume que al
―cab
er‖ el resultado en un digito, el acarreo que se generó en la suma es igual a
cero. Ahora observemos el ejemplo 2 de la misma tabla 21, en donde de
nueva cuenta se realiza una suma de 2 números con magnitud de 1 digito en cada
uno de ellos (5 + 6), el resultado en esta oportunidad es un número que ocupa 2
dígitos (11), por lo tanto, el resultado no se puede expresar en un solo digito ya
que no cabe, para este caso el resultado final se descompone generando un
resultado de un digito (el valor 1) y un acarreo (el valor decimal 1), para que se le
de continuidad al número de dígitos que se esta empleando.
41
ya que de acuerdo a las cantidades que se sumen se pueden generar acarreos,
mismos que deben de tomarse en cuenta para obtener un resultado real, de otra
manera seria erróneo el resultado.
EJEMPLO 1 EJEMPLO 2
42
con el valor de un registro f (registro de memoria RAM) dejando el resultado de la
suma ya sea en el registro de trabajo W o en el registro f, dependiendo del valor
que adquiera d (para una mejor referencia consulte el capitulo ―i
nstrucciones
orientadas al control de registros‖ e ―i
nstrucciones orientadas al control de
literales‖, ambos temas pertenecientes al modulo I).
43
El fragmento de código mostrado en la tabla 23 es el correspondiente al de una
suma entre registros de 8 bits, pero si el resultado de la suma produce un acarreo,
significa que el dato resultante de la suma fue mayor a 8 bits, por lo tanto, se debe
de tomar en cuenta el bit de acarreo tal como se ilustra en el diagrama de flujo de
la figura
44
LIST P=PIC16F628A
;------------------------------------------------------------
; Declaración de Registros
;------------------------------------------------------------
w equ 0x00
status equ 0x03
var1 equ 0x20
var2 equ 0x21
var3 equ 0x22
acarreo equ 0x23
;------------------------------------------------------------
; Declaración de Bits
;------------------------------------------------------------
c equ 0 ;bandera del acarreo
z equ 2 ;bandera del cero
rp0 equ 5 ;bit para seleccionar banco
rp1 equ 6 ;bit para seleccionar banco
;------------------------------------------------------------
; Inicio
;------------------------------------------------------------
reset org 0
goto inicio
;------------------------------------------------------------
; programa principal
;------------------------------------------------------------
inicio
bcf status,rp0 ;cambiar al banco 0
bcf status,rp1
bcf status,c
movf var1,0 ;carga el dato del registro var1 al registro de trabajo W.
addwf var2,0 ;suma el dato del registro var2 con el del registro W, dejando el
;resultado en el mismo registro W.
movwf var3 ;el dato del registro W lo guarda en el registro var3.
btfsc status,c
goto siaca
goto noaca
siaca
incf acarreo,1
noaca
siguiente proceso
.
.
.
end
Tabla 24. Programa que suma 2 registros de 8 bits.
45
acarreo se encuentra ubicado dentro del registro ―stat
us‖, por lo que el bit de
acarreo es una bandera que indica cualquiera de los siguientes estados:
Si el bit de acarreo ―C
‖ es igual con 0 significa que el resultado de una suma es
igual o menor a los 8 bits de los registros a sumarse.
Si el bit de acarreo ―C
‖ es igual con 1 significa que el resultado de una suma es
mayor de los 8 bits de los registros a sumarse.
46
como el byte más significativo.
47
la suma de los registros de menor peso de los operandos), el resultado de esta
segunda suma se guarda en el registro ―r
eg5‖.
48
Figura 10. Diagrama de flujo de una suma entre datos de 16 bits.
49
LIST P=PIC16F628A
;------------------------------------------------------------
; Declaración de Registros
;------------------------------------------------------------
w equ 0x00
status equ 0x03
reg1 equ 0x20
reg2 equ 0x21
reg3 equ 0x22
reg4 equ 0x23
reg5 equ 0x24
reg6 equ 0x25
acarreo equ 0x26
;------------------------------------------------------------
; Declaración de Bits
;------------------------------------------------------------
c equ 0 ;bandera del acarreo
z equ 2 ;bandera del cero
rp0 equ 5 ;bit para seleccionar banco
rp1 equ 6 ;bit para seleccionar banco
;------------------------------------------------------------
; Inicio
;------------------------------------------------------------
reset
org 0
goto inicio
;------------------------------------------------------------
; programa principal
;------------------------------------------------------------
inicio
bcf status,rp0 ;cambiar al banco 0
bcf status,rp1
bcf status,c ;limpia la bandera del acarreo.
movf reg2,0 ;carga el dato del registro reg2 al registro de trabajo W.
addwf reg4,0 ;suma el dato del registro reg4 con el del registro W, dejando el
;resultado en el mismo registro W.
movwf reg6 ;el dato del registro W lo guarda en el registro reg6.
btfsc status,c ;pregunta si existió acarreo en la suma.
goto siaca1
goto noaca1
siaca1
incf reg1,1 ;sí existe acarreo se incrementa en una unidad el registro reg1.
noaca1
bcf status,c ;limpia la bandera del acarreo.
movf reg1,0 ;carga el dato del registro reg1 al registro de trabajo W.
addwf reg3,0 ;suma el dato del registro reg3 con el del registro W, dejando el
;resultado en el mismo registro W.
movwf reg5 ;pregunta si existió acarreo en la suma.
btfsc status,c
goto siaca2
goto noaca2
siaca2
incf acarreo,1 ;sí existe acarreo se incrementa en una unidad el registro acarreo.
noaca2
siguiente proceso
.
.
.
end
Por último, para que el resultado final de la suma sea correcto, debe
contemplarse además de los registros donde se colocará el resultado (reg5 y
50
reg6), un registro más para que ahí se aloje el acarreo que se origine con la
segunda adición entre los registros de mayor peso de los operandos, de otra
manera, si existiera un acarreo y no se tomará en cuenta, el resultado total de la
suma seria completamente erróneo, en la tabla 26 se muestra el código para un
programa en donde se suman 2 datos de 16 bits.
EJEMPLO 1 EJEMPLO 2
6 1 Digito 6 1 Digito
- 4 1 Digito - 9 1 Digito
============= =============
= + 2 1 Digito = - 3 1 Dígito
Resultado Resultado
Positivo Negativo
51
Tabla 27. Ejemplos de una suma aritmética con números decimales.
52
con el de un valor literal dejando el resultado en el registro de trabajo W,
modificando su valor con respecto del que tenia anteriormente. El dato del
registro de trabajo W como el del valor literal son de 8 bits.
53
====================== Acarreo = 0 resultado es negativo
= - 00101011 Resultado Acarreo = 1 resultado es positivo
Negativo Como el acarreo fue igual con 0, el resultado 11010101
se complementa a 2.
54
que la resta entre si de 2 registros de memoria RAM, no puede realizarse de
manera directa, por lo que es necesario cargar uno de los datos al registro W, y
después aplicar la instrucción de la resta necesaria, a manera de ejemplo se
muestra una sustracción en el fragmento de diagrama de flujo de la figura 11.
55
Figura 12. Diagrama de flujo de una resta de registros de 8 bits.
En la tabla 30 se muestra un fragmento de código para realizar una resta entre
2 datos de 8 bits, en el cual no se toma en cuenta el posible resultado negativo o
positivo, motivo el cual, para que el dato que se obtenga de la resta este correcto y
con la debida interpretación, se tiene que realizar el procedimiento que se muestra
en el diagrama de flujo de la figura 12, en el cual se toma en cuenta si el resultado
de la sustracción fue negativo o positivo, mediante la comparación del bit que
indica el estado de la bandera del acarreo del registro ―stat
us‖. El bit de la
bandera del acarreo nos indica si un resultado fue positivo o negativo, después de
haber ejecutado una instrucción de una resta de acuerdo a lo siguiente:
a) Si el bit de la bandera del acarreo (c) del registro status es igual con 0
(cero), el resultado de la resta fue negativo.
56
es igual con 1 (uno), el resultado de la resta fue positivo.
57
LIST P=PIC16F628A
;------------------------------------------------------------
; Declaración de Registros
;------------------------------------------------------------
w equ 0x00
status equ 0x03
var1 equ 0x20
var2 equ 0x21
var3 equ 0x22
negativo equ 0x23
;------------------------------------------------------------
; Declaración de Bits
;------------------------------------------------------------
c equ 0 ;bandera del acarreo
rp0 equ 5 ;bit para seleccionar banco
rp1 equ 6 ;bit para seleccionar banco
;------------------------------------------------------------
; Inicio
;------------------------------------------------------------
reset org 0
goto inicio
;------------------------------------------------------------
; programa principal
;------------------------------------------------------------
inicio
bcf status,rp0 ;cambiar al banco 0
bcf status,rp1
bcf status,c
movf var2,0 ;carga el dato del registro var2 al registro de trabajo W.
subwf var1,0 ;resta al dato del registro var1 el del registro W, dejando el resultado en W.
movwf var3 ;el dato del registro W lo guarda en el registro var3.
btfsc status,c ;verifica la bandera del acarreo para determinar si el resultado
goto pos ;es positivo o negativo.
goto neg
pos
movlw 0x00 ;limpia el registro del resultado negativo.
movwf negativo
goto sigproceso
neg
comf var3,1 ;complementa a 2 el resultado del registro var3 que es donde
incf var3,1 ;se encuentra el resultado negativo de la resta.
movlw 0xff ;coloca indicación de un resultado negativo, en el registro negativo.
movwf negativo
sigproceso
siguiente proceso
.
.
.
end
Tabla 31. Programa que resta 2 registros de 8 bits.
Para realizar las restas de 16 bits se tienen que reservar dos registros de 8
bits, para cada uno de los operandos que pertenecerán a la sustracción, por lo que
cada operando tendrá que acomodarse de acuerdo con el peso específico de
58
cada uno de los bits que lo compone, en la tabla 32 se ilustra la estructura de una
resta con datos de 16 bits.
59
tanto, estos operandos no existen en el código del programa, pero si los registros
que los conforman, y por lo tanto los operandos se encuentran representados por
los registros que los integran, en la figura 13 se muestra la operación de una resta
aritmética con datos de 16 bits, la cual es el reflejo de la operación realizada en la
tabla 32.
Por último se realiza la sustracción de los registros de mayor peso de cada uno
de los operandos identificados como minuendo y sustraendo (tomando en cuenta
el acarreo, si es que lo hubo, en la resta de los registros de menor peso de los
operandos), el resultado de esta segunda resta se guarda en el registro ―r
eg5‖.
60
Figura 14. Diagrama de flujo de una resta de datos de 16 bits.
Para realizar el complemento a 2 de un número de 16 bits se sigue el mismo
procedimiento que se emplea para un número de 8 bits, por lo tanto en primer
instancia se tienen que sustituir los 1’s por 0’s y los 0’s por 1’s, para
posteriormente sumarle una unidad al registro de 8 bits que compone la parte
61
baja del dato de 16 bits, se debe de tomar en cuenta que al sumar la unidad se
puede generar un acarreo que puede afectar al registro de 8 bits que conforma la
parte alta de los 16 bits (recurra al capitulo de la suma aritmética que se encuentra
antes del capitulo presente), en la tabla 33 se muestra un ejemplo en donde se
realiza una resta de 2 datos de 16 bits, siendo el resultado final negativo, y la
aplicación del complemento a 2 del resultado final, para obtener la magnitud de la
resta.
62
LIST P=PIC16F628A acarreo
;------------------------------------------------------------ decf reg1,1 ;decrementa en una unidad a reg1.
; Declaración de Registros sigresta
;------------------------------------------------------------ bcf status,c ;limpia la bandera del acarreo.
w equ 0x00 movf reg3,0 ;carga el dato del registro reg3 al
status equ 0x03 ;registro de trabajo W.
reg1 equ 0x20 subwf reg1,0 ;resta al dato del registro reg1 el
reg2 equ 0x21 ;del registro W, dejando el
reg3 equ 0x22 ;resultado en W.
reg4 equ 0x23 movwf reg5 ;el dato del registro W lo guarda
reg5 equ 0x24 ;en el registro reg6.
reg6 equ 0x25 btfsc status,c ;verifica la bandera del acarreo
negativo equ 0x26 goto positivo ;para determinar si el resultado
;------------------------------------------------------------ ;total es positivo o negativo.
; Declaración de Bits neg
;------------------------------------------------------------ comf reg5,1 ;complementa a 2 el resultado de la
c equ 0 ;bandera del acarreo comf reg6,1 ;resta que se encuentra en los
rp0 equ 5 ;bit para seleccionar banco movlw 0x01 ;registros reg5 y reg6.
rp1 equ 6 ;bit para seleccionar banco movwf reg6,1
;------------------------------------------------------------ btfss status,c
; Inicio goto noaca
;------------------------------------------------------------ incf reg5,1
reset org 0 noaca
goto inicio movlw 0xff ;coloca indicación de un resultado
;------------------------------------------------------------ movwf negativo ;negativo, en el registro negativo.
; programa principal goto sigproceso
;------------------------------------------------------------ positivo
inicio movlw 0x00 ;limpia el registro del
bcf status,rp0 ;cambiar al banco 0 movwf negativo ;resultado negativo.
bcf status,rp1 sigproceso
bcf status,c ;limpia la bandera del acarreo. siguiente proceso
movf reg4,0 ;carga el dato del registro reg4 al .
;registro de trabajo W. .
subwf reg2,0 ;resta al dato del registro reg2 el .
;del registro W, dejando el end
;resultado en W.
movwf reg6 ;el dato del registro W lo guarda
;en el registro reg6.
btfsc status,c ;verifica la bandera del acarreo
goto sigresta ;para determinar si el resultado
;parcial es positivo o negativo.
Para terminar el presente capitulo diremos que el método para realizar restas
de datos con mas de 16 bits, es prácticamente el mismo que con 16 bits, ya que
de requerir números más grandes, tan solo se deben de contemplar todos los
registros de 8 bits, que se requieran para conformar a los datos que
63
intervendrán en la resta, además de también contemplar al bit de acarreo para
determinar si los resultados parciales o el resultado final fue positivo o negativo.
32 es el resultado de la multiplicación
64
el término multiplicando, tantas veces como el valor expuesto en el operando
multiplicador.
65
Figura 15 Diagrama de flujo de una multiplicación con datos de 8 bits.
Del diagrama de flujo de la figura 15 se observa que los registros identificados
como ―r
es0‖ y ―
res1‖, son lo que se encuentran destinados para alojar el resultado
de la multiplicación, por lo tanto se debe definir el peso específico de cada unos
ellos, quedando el registro res1 como el de mayor peso, mientras que el registro
res0 es el de menor peso. En los registros identificados como ―m
ultiplicando‖y
―m
ultiplicador‖ se encuentran los datos que van a ser multiplicados. Por último el
registro identificado como ―co
ntador‖ es el encargado de llevar el control del
66
número de veces que se realiza la operación de la suma. Los registros res0,
res1 y contador deber inicializados con un valor igual con 0 (cero) al inicio de una
operación de multiplicación.
67
tiene que verificar si el resultado genero un acarreo, porque si es así, también
tiene que incrementarse una unidad al valor del registro resg1.
68
EJEMPLO Serie de restas para realizar la Se multiplica el residuo por 10
división. 01
21 x 10
- 5 ====
==== 10 Se toma el valor de 10 para
16 1 vez se ha restado el 5 Continuar con la serie de restas.
4.2 Cociente
- 5
10
Divisor 5 21 Dividendo ====
- 5
11 2 veces se ha restado el 5
10 - 5 ====
==== 05 1 vez se ha restado el 5
0 Residuo 06 3 veces se ha restado el 5 - 5
- 5 ====
==== 00 2 veces se ha restado el 5
01 4 veces se ha restado el 5
4.2 Es el resultado de la división con un residuo igual con 0.
Cuando no existe una instrucción para realizar divisiones, tal como es el caso
de un microcontrolador PIC, tenemos que recurrir a un procedimiento como el
ilustrado en el ejemplo de la tabla 37, en el cual la operación básica es una resta,
por lo tanto, se tiene que aplicar dicha metodología para encontrar el resultado de
la operación de la división.
Para comenzar una división por medio del empleo de restas, se toma el valor
que se encuentra en el ―div
idendo‖, al cual se le resta la magnitud que se localiza
en el ―div
isor‖, el resultado de la resta debe contener un valor mayor que el del
divisor para que sea aplicada una nueva resta; mientras se van aplicando las
restas, estas se van contabilizando. Cuando el resultado de la resta es menor
que el valor del divisor, entonces el número de restas es igual al valor entero del
―cocien
te‖ (resultado de la división), si el ―
residuo‖ (resultado de la última resta)
obtuvo un valor igual con cero, entonces hemos terminado con la división, pero si
el residuo tiene un valor diferente de cero pero menor que el del divisor, entonces
se considera que se coloca un punto decimal en el cociente, por lo que se toma el
valor que se encuentra en el residuo para multiplicarlo por 10 (equivale a bajar un
cero, tal como se ilustra en el ejemplo de la tabla 37), posteriormente el resultado
de la multiplicación es asignado nuevamente al termino dividendo, para que se
reanude la aplicación de las restas, tomando el divisor como el valor que
69
será restado al nuevo dividendo. Este procedimiento se repetirá tantas veces
como decimales se quieran obtener, solo que para encontrar el siguiente decimal,
el residuo tendrá que multiplicarse por 100, y después por 1000 y así
sucesivamente.
70
LIST P=PIC16F628A fraccion
;------------------------------------------------------------ movf divisor,w ;reintegra el valor que
; Declaración de Registros addwf dividendo,w ; fue sustraído en la
;------------------------------------------------------------ movwf dividendo ;última resta.
w equ 0x00 movwf dividendo_dec ;prepara la
status equ 0x03 movlw 0x10 ; multiplicación
divisor equ 0x20 movwf multiplicador
dividendo equ 0x21 movlw 0x01
cociente_ent equ 0x22 movwf contador
cociente_dec equ 0x23 multiplica ;realiza la multiplicación
residuo equ 0x24 movf dividendo,w ;del residuo por 10.
;------------------------------------------------------------ addwf dividendo_dec,1
; Declaración de Bits incf contador,1
;------------------------------------------------------------ movf contador,w
c equ 0 ;bandera del acarreo xorwf multiplicador,w
rp0 equ 5 ;bit para seleccionar banco btfss status,z
rp1 equ 6 ;bit para seleccionar banco goto multiplica
;------------------------------------------------------------ movf dividendo_dec,w
; Inicio movwf dividendo
;------------------------------------------------------------ bcf status,c
reset org 0 division_1 ;repite el proceso de las restas
goto inicio movf divisor,w ;para encontrar el valor
;------------------------------------------------------------ subwf dividendo,1 ;después del punto
; programa principal btfss status,c ; decimal.
;------------------------------------------------------------ goto fraccion_1
inicio incf cociente_dec,1
bcf status,rp0 ;cambiar al banco 0 goto division_1
bcf status,rp1 fraccion_1
bcf status,c movf divisor,w
clrf cociente_ent addwf dividendo,w
clrf cociente_dec movwf residuo
clrf residuo siguientes instrucciones
division .
movf divisor,w ;realiza la resta del .
subwf dividendo,1 ;dividendo menos el .
;divisor. end
btfss status,c
goto fraccion
incf cociente_ent,1
goto division
Tabla 38. Programa que realiza divisiones.
71
registro ―stat
us‖. La importancia de la bandera radica en el hecho de saber si
un resultado después de realizar una resta es igual con menor que el divisor (si el
resultado de la resta, es menor que el divisor significa que ha terminado una fase
de la división). Mientras el resultado de la resta sea mayor que el divisor, se
contabilizan las restas que se vayan realizando, pasando este dato a ser parte del
valor del cociente.
72
CAPÍTULO II. RUTINAS INTERMEDIAS
Para implementar las funciones lógicas en los microcontroladores PIC, tan solo
se tiene que hacer uso de sus respectivas instrucciones, teniendo en cuenta las
posibilidades existentes en cuanto a la manipulación de los datos, esto es, los
diferentes tipos de operandos que pueden emplearse.
La función lógica Y (AND en inglés) tiene una aplicación como una máscara,
dejando pasar los estados lógicos de los bits que nos interesan de un registro,
colocando los restantes bits en estado lógico ―0‖, independientemente del valor
que tuvieran antes de realizar la operación.
73
pueden adquirir los términos identificados como ―D
ato 1‖ y ―
Dato 2‖, generándose
en total 4 diferentes combinaciones de estos, teniendo como factor común que en
cualquiera de los datos de ingreso que se tenga un ―0‖ lógico, el resultado será ―0‖
(cero). Mientras que cuando ambos datos de entrada adquieren el valor de ―1‖
lógico, el resultado será ―1‖ (uno), siendo este el motivo del nombre que posee
esta función lógica, ya que para generar un ―1‖ lógico se requiere que el Dato 1 ―Y
‖
el Dato 2 se encuentren en estado lógico de ―
1‖.
b7 b6 b5 b4 b3 b2 b1 b0
0 0 0 0 1 1 1 1 Registro 1
& (AND)
0 1 0 1 1 0 0 1 Registro 2
======================
0 0 0 0 1 0 0 1
Tabla 40. Ejemplo de aplicación entre 2 registros de la función lógica
AND.
74
De acuerdo con el ejemplo anterior, podemos establecer un filtro de datos de
acuerdo a los bits de un registro que necesitamos operar, y regresando al ejemplo
si consideramos al registro 2 como el filtro, podemos decir que en los bits donde
se le fijaron ceros lógicos, el resultado fue ―
0‖ lógico independientemente de los
valores que tengan los bits del registro 1, mientras que si lo bits del filtro fueron
establecidos como ―1‖ lógico, el resultado depende del correspondiente estado
lógico del bit del registro 1.
b7 b6 b5 b4 b3 b2 b1 b0
1 0 1 0 1 0 1 0 Dato
&
0 0 0 0 1 1 1 1 Filtro
======================
0 0 0 0 1 0 1 0
Tabla 41. Aplicación de la función lógica AND como filtro.
75
esta, la de fijar de manera predeterminada un ―0‖ lógico en los bits donde sea
necesario, permitiendo que en los demás bits se aloje el estado lógico que tenia
antes de la aplicación de la función lógica AND. Para una mejor comprensión
observe el ejemplo de la tabla 41, en el cual se muestra que necesitamos que los
bits del nible superior del registro dato pasen a ser ―0´s‖ en el resultado, mientras
que los datos contenidos en los bits del nible inferior del registro dato se trasladan
de manera integra al resultado.
a) andlw k.- Función lógica AND del dato que se encuentra en el registro de
trabajo W con el de un valor literal dejando el resultado en el registro de trabajo W,
modificando su valor con respecto del que tenia anteriormente. El dato del
registro de trabajo W como el del valor literal son de 8 bits.
b) andwf f,d.- Función lógica AND del dato que se encuentra en el registro de
trabajo W con el valor de un registro f (registro de memoria RAM) dejando el
resultado de la función AND ya sea en el registro de trabajo W o en el registro f,
dependiendo del valor que adquiera d (para una mejor referencia consulte el
capitulo ―i
nstrucciones orientadas al control de registros‖ e ―i
nstrucciones
orientadas al control de literales‖, ambos temas pertenecientes al modulo I).
76
ejemplo demuestra la forma en que puede ser empleada la función lógica AND.
LIST P=PIC16F628A
;------------------------------------------------------------
; Declaración de Registros
;------------------------------------------------------------
w equ 0x00
status equ 0x03
var1 equ 0x20
var2 equ 0x21
;------------------------------------------------------------
; Declaración de Bits
;------------------------------------------------------------
c equ 0 ;bandera del acarreo
z equ 2 ;bandera del cero
rp0 equ 5 ;bit para seleccionar banco
rp1 equ 6 ;bit para seleccionar banco
;------------------------------------------------------------
; Inicio
;------------------------------------------------------------
reset org 0
goto inicio
;------------------------------------------------------------
; programa principal
;------------------------------------------------------------
inicio
bcf status,rp0 ;cambiar al banco 0
bcf status,rp1
bcf status,c
movf var1,0 ;carga el dato del registro var1 al registro de trabajo W.
andlw 0x0f,0 ;función AND con de W con el filtro 0F, dejando el
;resultado en el mismo registro W.
movwf var2 ;el dato del registro W lo guarda en el registro var2.
siguiente proceso
.
.
.
end
Tabla 42. Ejemplo de aplicación de la función lógica
AND.
La función lógica O (OR en inglés) también puede emplearse para generar una
máscara, solo que a diferencia de la función lógica AND, con la función lógica OR
se fijan ―0´s‖ lógicos, en el o los bits que nos interesan de un registro, y por otra
parte podremos filtrar los estados lógicos de los bits que nos interesan de
77
un determinado registro, colocando los restantes bits en el estado lógico de ―
1‖,
independientemente del valor que tuvieran antes de realizar la operación de la
función lógica OR.
FUNCIÓN LÓGICA OR
Entrada 1 Entrada 2 Resultado
0 0 0
0 1 1
1 0 1
1 1 1
Tabla 43. Tabla de verdad de la función lógica AND.
78
EJEMPLO DE LA FUNCIÓN LÓGICA OR
b7 b6 b5 b4 b3 b2 b1 b0
1 1 1 1 0 0 0 0 Registro 1
| (OR)
1 0 1 0 0 1 1 0 Registro 2
======================
1 1 1 1 0 1 1 0
Tabla 44. Ejemplo de aplicación entre 2 registros de la función lógica
OR.
A partir del ejemplo ilustrado en la tabla 44, nos percatamos que al ejecutar la
función lógica OR ( | ) entre los datos alojados en ―R
egistro 1‖ y ―R
egistro 2‖, esta
se aplica bit a bit de acuerdo con su respectiva tabla de verdad, por ejemplo, se
tiene como dato un ―
0‖ lógico en el bit ―b
0‖ de ambos registros, arrojando el
resultado de ―
0‖ lógico. Además, en el correspondiente bit ―b
1‖ se encuentra
un ―
0‖ lógico en el registro 1 y un ―
1‖ lógico en el registro 2, quedando como
resultado un ―
1‖ lógico; y así sucesivamente se tienen que seguir aplicando las
operaciones, de la función lógica OR tomando los correspondientes bits de los
registros en cuestión.
79
EJEMPLO DE LA FUNCIÓN LÓGICA OR
b7 b6 b5 b4 b3 b2 b1 b0
0 1 0 1 0 1 0 1 Dato
&
1 1 1 1 0 0 0 0 Filtro
======================
1 1 1 1 0 1 0 1
Tabla 45. Aplicación de la función lógica OR como filtro.
80
Para poder hacer uso de la función lógica OR entre 2 registros en un
microcontrolador PIC, se pueden emplear una de dos instrucciones de acuerdo a
la forma en como se requieran aplicar; las instrucciones de la función lógica OR
con las que cuentan los microcontroladores PIC se describen a continuación:
81
refiérase a los capítulos ―
configuración de los puertos como entrada o salida‖,
―Le
ctura de datos de un puerto‖, ―escri
tura de datos en un puerto‖ y ―
asignación de
datos a un registro‖, ambos temas pertenecientes al presente modulo II.
LIST P=PIC16F628A
;------------------------------------------------------------
; Declaración de Registros
;------------------------------------------------------------
w equ 0x00
status equ 0x03
var1 equ 0x20
var2 equ 0x21
;------------------------------------------------------------
; Declaración de Bits
;------------------------------------------------------------
c equ 0 ;bandera del acarreo
z equ 2 ;bandera del cero
rp0 equ 5 ;bit para seleccionar banco
rp1 equ 6 ;bit para seleccionar banco
;------------------------------------------------------------
; Inicio
;------------------------------------------------------------
reset org 0
goto inicio
;------------------------------------------------------------
; programa principal
;------------------------------------------------------------
inicio
bcf status,rp0 ;cambiar al banco 0
bcf status,rp1
bcf status,c
movf var1,0 ;carga el dato del registro var1 al registro de trabajo W.
iorlw 0xf0,0 ;función OR con de W con el filtro F0, dejando el
;resultado en el mismo registro W.
movwf var2 ;el dato del registro W lo guarda en el registro var2.
siguiente proceso
.
.
.
end
Tabla 46. Ejemplo de aplicación de la función lógica
OR.
82
dejando su actividad principal en la de poder identificar el contenido de 2 registros,
y reportar si estos son exactamente iguales entre si, por lo tanto, un campo de
acción de la función lógica XOR se encuentra en la comparación de los datos de
registros.
Tal como sucede con las funciones lógicas AND y OR, cuando se aplica la
función lógica XOR entre 2 registros, se realiza operando la función bit a bit entre
los 2 registros involucrados de acuerdo con la tabla de verdad mostrada
anteriormente.
83
función lógica XOR (^), entre los datos alojados en los registros ―R
egistro 1‖ y
―R
egistro 2‖ con sus correspondientes bits b0, el resultado es un ―
0‖ lógico debido
a que ambos datos de entrada se encuentran en ―1‖ lógico. Lo mismo para
cuando se aplica la función lógica XOR a los bits b1 de los registros ―R
egistro 1‖ y
―R
egistro 2‖, como ambos datos de entrada son iguales, la respuesta es
nuevamente ―0‖ lógico, y así sucesivamente al ir aplicando la función lógica cada
uno de los bits, en todos los resultados tendremos un ―0‖ lógico, salvo en los bits
de entrada b3, porque el b3 del ―R
egistro 1‖ se encuentra en ―0‖ lógico, y el del
―R
egistro 2‖ se encuentra en ―
1‖ lógico, dando como resultado un ―1
‖ lógico.
b7 b6 b5 b4 b3 b2 b1 b0
0 1 0 1 0 1 0 1 Registro 1
^ (XOR)
0 1 0 1 1 1 0 1 Registro 2
======================
0 0 0 0 1 0 0 0
Tabla 48 Ejemplo de aplicación entre 2 registros de la función lógica
XOR.
a) xorlw k.- Función lógica XOR del dato que se encuentra en el registro de
84
trabajo W con el de un valor literal dejando el resultado en el registro de trabajo W,
modificando su valor con respecto del que tenia anteriormente. El dato del
registro de trabajo W como el del valor literal son de 8 bits.
b) xorwf f,d.- Función lógica XOR del dato que se encuentra en el registro de
trabajo W con el valor de un registro f (registro de memoria RAM) dejando el
resultado de la función XOR ya sea en el registro de trabajo W o en el registro f,
dependiendo del valor que adquiera d (para una mejor referencia consulte el
capitulo ―i
nstrucciones orientadas al control de registros‖ e ―i
nstrucciones
orientadas al control de literales‖, ambos temas pertenecientes al modulo I).
Igual (=)
85
Menor que (<)
Mayor que (>)
A partir de las comparaciones básicas podemos crear las llamadas
comparaciones complementarias que prácticamente no son otra cosa que eso (de
manera literal); las comparaciones complementarias se muestran a continuación.
86
resta aritmética para determinar sí 2 cantidades numéricas son iguales entre ellas,
obteniéndose 2 posibles resultados, uno de los resultados de la resta puede ser
cero, si es que los valores de los datos fueron iguales entre si, o se puede tener un
resultado diferente de cero en la resta (positivo o negativo), si los valores fueron
de magnitud diferente entre si.
EJEMPLO 1 EJEMPLO 2
5 Dato 1 5 Dato 1
- 5 Dato 2 - 4 Dato 2
=========== ===========
= 0 Resultado = 1 Resultado
Son ―ig
uales‖ entre sí el Dato 1 con Son ―di
ferentes‖ entre sí el Dato 1
el Dato 2 con el Dato 2
Tabla 49. Ejemplos de una comparación de valores realizada a partir de
una resta.
87
ella determinar su 2 valores son iguales o diferentes.
EJEMPLO 1 EJEMPLO 2
Son ―ig
uales‖ entre si el Dato 1 con Son ―di
ferentes‖ entre si el Dato 1
el Dato 2 con el Dato 2
Tabla 50. Ejemplos de una comparación de valores realizada con la
función XOR.
88
respecto de var2, generando a su vez 2 posibles resultados, los cuales nos indican
por medio de una respuesta afirmativa que las magnitudes de los datos de var1 y
var2 son iguales; por otra parte, si la respuesta es ―n
o‖, significa que las
magnitudes de los datos de var1 y var2 son diferentes.
89
18, se presupone que se emplean registros de 8 bits para efectos de una mejor
comprensión, pero si se quisieran comparar valores que aborden más de 8 bits en
su composición, el método sigue siendo el mismo, solamente se tienen que
contemplar restas con registros de más de 8 bits (16, 32, etc.).
90
LIST P=PIC16F628A ;ó P=PIC12F629 ó P=PIC16F874
;------------------------------------------------------------
; Declaración de Registros
;------------------------------------------------------------
w equ 0x00
status equ 0x03
var1 equ 0x20
var2 equ 0x21
;------------------------------------------------------------
; Declaración de Bits
;------------------------------------------------------------
c equ 0 ;bandera del acarreo
z equ 2 ;bandera del cero
rp0 equ 5 ;bit para seleccionar banco
rp1 equ 6 ;bit para seleccionar banco
;------------------------------------------------------------
; Inicio
;------------------------------------------------------------
reset org 0
goto inicio
;------------------------------------------------------------
; programa principal
;------------------------------------------------------------
inicio
bcf status,rp0 ;cambiar al banco 0
bcf status,rp1
bcf status,z
movf var2,w ;se carga var2 en w
subwf var1,w ;resta var1 – w deja el resultado en w
btfsc status,z ;pregunta por el estado de la bandera z del registro status
goto igual
goto diferente
igual
;Código correspondiente cuando
;var1 y var2 son iguales
goto siguienteproceso
diferente
;Código correspondiente cuando
;var1 y var2 son diferentes
goto siguienteproceso
siguienteproceso
end
Tabla 51. Código del programa de comparación: Igual ó Diferentes.
91
status, para saber si el resultado de la resta o función XOR fue 0 o no.
92
resta puede dar un valor positivo (sin importar su magnitud), si es que el valor del
dato 2 fue menor que el valor del dato 1, ó se puede obtener un resultado negativo
después de aplicar la operación de la resta (de igual manera sin importar su
magnitud), si el valor del dato 2 resulto que es mayor que el valor del dato 1, pero
también pudo haber sido cero el resultado de la resta, por lo tanto, sí el resultado
de la resta hubiese sido negativo ó cero se interpretara como que el dato 2 fue
mayor o igual que el dato 1.
EJEMPLO 1 EJEMPLO 2
8 Dato 1 8 Dato 1
- 3 Dato 2 - 9 Dato 2
=========== ===========
= 5 Resultado Positivo = - 1 Resultado Negativo ó Cero
93
Figura 19. Símbolo de la función de comparación: Menor que ó Mayor o
igual.
En la figura 19 se muestra un rombo que es el símbolo de manera general que
se emplea para realizar la comparación entre las magnitudes de los valores de 2
datos, dentro del rombo esta expresada la pregunta mediante la cual se compara
la magnitud de var2 con respecto de var1, generando a su vez 2 posibles
resultados, los cuales nos indican por medio de una respuesta afirmativa que la
magnitud del dato var2 es menor que el dato var1; por otra parte, si la respuesta
es ―no
‖, significa que la magnitud del dato var2 es mayor ó igual que el dato de
var1.
94
Figura 20. Diagrama de flujo de la comparación: Menor que ó Mayor o
igual.
El código que se obtendrá a partir del diagrama de flujo de la figura 20, será
representado por medio de registros de 8 bits, con el único fin de lograr una mejor
comprensión en la explicación siguiente, pero si se quisieran comparar valores
cuyos registros requieran de más de 8 bits en su conformación, el método seguirá
siendo el mismo, solamente se tienen que contemplar restas con registros de más
de 8 bits (16, 32, etc.).
95
acarreo como ―c‖, encontrándose ambas banderas ubicadas dentro del registro
―stat
us‖ del microcontrolador PIC.
96
la figura 20.
97
2.4.3 COMPARACIÓN MAYOR QUE (>) Ó MENOR O IGUAL QUE (≤)
EJEMPLO 1 EJEMPLO 2
9 Dato 1 7 Dato 1
- 5 Dato 2 - 9 Dato 2
=========== ===========
= 4 Resultado Positivo = - 2 Resultado Negativo ó Cero
98
fue mayor que el valor del dato 2, ó se puede obtener un resultado negativo
después de aplicar la operación de la resta (de nueva cuenta sin importar su
magnitud), sí el valor del dato 1 resulto que es menor que el valor del dato 2, pero
también pudo haber sido cero el resultado de la resta, por lo tanto, sí el resultado
de la resta hubiese sido negativo ó cero se interpretara como que el dato 1 fue
menor o igual que el dato 2.
99
con respecto de var2, generando a su vez 2 posibles resultados, los cuales nos
indican por medio de una respuesta afirmativa que la magnitud del dato var1 es
mayor que el dato var2; por otra parte, si la respuesta es ―no
‖, significa que la
magnitud del dato var1 es menor ó igual que el dato de var2.
100
fundamental la operación de la resta aritmética para estar en posibilidades de
tomar una decisión sobre el resultado final de la comparación.
El código que se obtendrá a partir del diagrama de flujo de la figura 22, será
representado por medio de registros de 8 bits, con el único fin de lograr una mejor
comprensión en la explicación que a continuación se dará, pero si se quisieran
comparar valores cuyos registros requieran de más de 8 bits en su conformación,
el método seguirá siendo el mismo, solamente se tienen que contemplar restas
con registros de más de 8 bits (16, 32, etc.).
101
bandera c tenga un estado ―0‖ lógico para tener en cuenta que el resultado de la
resta fue negativo.
102
Sí el resultado de la resta (o dicho de otra manera de la comparación) fue
positivo significa que var1 es mayor que var1 (var2 > var1), y entonces como
consecuencia el control del programa se tiene que dirigir a ejecutar las
instrucciones conducentes con el resultado mostrado; pero sí el resultado de la
resta fue negativo ó igual con cero, significa que como consecuencia de la
comparación se arrojo un resultado que señala que var1 es menor o igual que
var2 (var1 ≤ var2), por lo tanto, de igual manera el control del programa se tiene
que desplazar para ejecutar la serie de instrucciones que corresponden a las
actividades de cuando el resultado de la comparación fue var2 ≤ var1.
103
columnas es suficiente para ingresar la información al microcontrolador, y para
emplear el teclado de 16 teclas solo son necesarias 8 terminales del
microcontrolador (4 de entrada y 4 de salida).
104
implementación en un circuito impreso de una sola cara. Por la manera en
como se acomodaron los botones que se muestran en el diagrama esquemático
de la figura 23, se generan 4 columnas y 4 filas las cuales se forman con la unión
de las respectivas terminales de los botones y lo recomendable es seguir la
conexión expresada en el diagrama esquemático, ya que prácticamente de ahí se
obtiene el circuito impreso. Por ejemplo enfoquemos nuestra atención hacia el
botón identificado como S5, este esta conectado en su parte izquierda con el
borne identificado como ―C
1‖ que se refiere a la columna 1, y por su parte derecha
al borne identificado como ―F
1‖ que se refiere a la fila 1, por lo tanto, sí es
presionado este botón estaremos uniendo la fila 1 con la columna 1. Para todos
los botones se tiene el mismo principio de operación, por lo que se generan
combinaciones de columnas con filas, las cuales son muy fáciles de identificar de
acuerdo al botón que se oprima. El paso siguiente es personalizar cada uno de
los botones, por ejemplo si se tratara de una calculadora se colocarían las teclas
numéricas del 0 al 9 y los botones restantes con las operaciones aritméticas
básicas, ó también se personalizar los botones con letras, etc.
105
restantes se fijaran en estado lógico de ―0‖. El ―1‖ lógico tiene que ser enviado
solo uno a la vez por la salida correspondiente, para que de esa manera se tenga
el control de la fila es la que se esta activando.
Una vez que un ―1‖ lógico se encuentra presente en alguna de las filas del
teclado matricial, se tiene que esperar un tiempo razonable (máximo 10
milisegundos) para que sea presionada una tecla, y dependiendo de cual fue
oprimida, se enviara el ―1‖ lógico a una de 4 terminales del microcontrolador que
previamente tuvieron que ser configuradas como entradas, las terminales de
entrada por el momento serán identificadas como E0, E1, E2 y E3, que
respectivamente corresponden a las columnas C0, C1, C2 y C3.
106
en este ejemplo se esta empleando un teclado matricial de 4X4 simulando una
calculadora básica. En la tabla 56 se muestra el código ASCII (se recomienda
que se asigne código ASCII cuando se trabaja con un teclado) resultante, que será
generado a partir de la combinación de fila y columna que se presente cuando una
tecla sea oprimida.
C0 = E0 C1 = E1 C2 = E2 C3 = E6
F3 = S3 01 30* 0F 2F*
107
tanto, se tiene que comenzar por la primera fila, o sea la identificada como F0.
108
mseg, tiempo suficiente para minimizar el rebote que se genere en el interruptor
una vez que se oprima el teclado, posteriormente cuando termina el tiempo de 10
mseg, se puede dar por hecho que sí fue oprimida una tecla, esta ya se estabilizo
y por lo tanto, ahora se puede acceder al proceso para determinar la tecla que fue
accionada; una vez que se activo la fila 0 del teclado, será a través de una de las 4
columnas que sabemos que tecla se oprimió.
El valor del dato que será alojado en el registro varteclado depende de cual
comparación fue valida, la cual a su vez esta relacionada con la tecla que ha sido
presionada. Para el caso de la fila 0 los valores que pueden ser guardados son:
31H, 32H, 33H ó 2BH, de acuerdo con la tecla que fue activada. Pero sí ninguna
tecla de la fila 0 es accionada, entonces el resultado de las comparaciones será
―no
‖ provocando que como paso siguiente se repita nuevamente el proceso de
identificar la tecla que es accionada, pero ahora en la siguiente fila que se
identifica como F1 (fila 1).
109
De manera básica cuando se pasa a la activación de la fila 1, el proceso es el
mismo que para la fila 0, solo que en esta oportunidad, la salida que se activará
será la identificada en el microcontrolador como S1 (PB1) y que corresponde con
la fila 1, haciéndose esta operación por medio del comando ―b
sf portb,1‖. De
igual manera para evitar los rebotes mecánicos de los interruptores del teclado, es
utilizado un retardo de máximo 10 mseg. Acto seguido dependiendo en que
columna se encuentra la tecla que se oprima, será por donde se reciba el
correspondiente ―1‖ lógico a través de la terminal de entrada, solo que en esta
ocasión las posibles teclas que pueden ser activadas con las identificadas como
―
4‖, ―
5‖, ―
6‖ ó ―
-―,que corresponden con las entradas E0, E1, E2 ó E3. Sí fue
presionada una tecla de la fila 1, se procederá a guardar un dato en el registro
varteclado, que en esta oportunidad utiliza los valores 34H, 35H, 36H ó 2DH. En
caso de que no se oprima tecla alguna de la fila 1, entonces se pasara a revisar sí
en la fila 2 es en donde se presiono una tecla.
La operación que se realiza para las filas 0 y 1 es la misma que se utiliza para
las filas 2 y 3, pero buscando que se oprima cualquiera de las teclas ―
7‖, ―
8‖, ―
9‖ ó
―X
‖ para la fila 2, ó las teclas ―L‖, ―
0‖, ―=
‖ó―
/‖ para la fila 3, todo esto de acuerdo a
como se observa en el diagrama de flujo de la figura 25. Para el presente
ejercicio de aprendizaje en la utilización del teclado, estamos condicionando al
programa del microcontrolador, para que una vez que se presiona una tecla y se le
asigna el valor correspondiente al registro varteclado, se proceda a realizar alguna
otra actividad, mientras que si ninguna tecla se presiona, se tiene que realizar la
búsqueda de alguna tecla mediante la activación de las diferentes filas,
terminando con esta actividad cuando alguna tecla es presionada.
En la fila 3 las teclas L e = las relacionamos con un valor hexadecimal igual con
01 y 0F respectivamente, ya que la tecla L la utilizaremos por ejemplo para limpiar
el valor del registro varteclado, mientras que la tecla = la emplearemos por
ejemplo para registra mostrar un resultado.
110
Figura 26. Conexión de un teclado matricial de 4 X 4.
En el diagrama esquemático de la figura 26 se muestra el circuito básico para
conectar el teclado matricial al microcontrolador, en el cual solo se muestran las
terminales de los puertos A y B que son empleadas, pero debe de tomar en cuenta
que falta la alimentación y el cristal en caso de ser requerido. Mientras que en la
tabla 57 se muestra el programa que tiene que ser cargado al microcontrolador
para que controle la lectura del teclado matricial.
111
LIST P=PIC16F874 te1
;=============================================== bcf status,rp0 ;escribe código ASCII de la tecla 1
; Declaración de Registros bcf status,rp1
;=============================================== movlw 0x31
w equ 0x00 movwf varteclado
status equ 0x03 goto sigproceso
porta equ 0x05 te2
portb equ 0x06 bcf status,rp0 ;escribe código ASCII de la tecla 2
trisa equ 0x85 bcf status,rp1
trisb equ 0x86 movlw 0x32
adcon1 equ 0x9f movwf varteclado
varteclado equ 0x20 goto sigproceso
var1 equ 0x23 t3
var2 equ 0x24 bcf status,rp0 ;escribe código ASCII de la tecla 3
var3 equ 0x25 bcf status,rp1
;=============================================== movlw 0x33
; Declaración de Bits movwf varteclado
;=============================================== goto sigproceso
c equ 0 ;carry / borrow bit temas
rp0 equ 5 ;registrer banck select bit bcf status,rp0 ;escribe código ASCII de la tecla +
rp1 equ 6 ;registrer banck select bit bcf status,rp1
z equ 2 ;bit cero movlw 0x2b
;=============================================== movwf varteclado
; Inicio goto sigproceso
;=============================================== ;===============================================
reset ;pregunta por las teclas 4,5,6,-
org 0 ;===============================================
goto inicio fila01
;=============================================== bcf status,rp0
; programa principal bcf status,rp1
;=============================================== bcf portb,0
inicio bsf portb,1 ;envía 1 a la primera fila 1 de teclas
bsf status,rp0 ;cambiar a banco 1 call retardo
bcf status,rp1 btfsc porta,0 ;¿se trata de la tecla "4"?
movlw 0xff ;configurar el puerto a como entrada goto te4
movwf trisa btfsc porta,1 ;¿se trata de la tecla "5"?
movlw 0x00 ;configurar el puerto b como salida goto te5
movwf trisb btfsc porta,2 ;¿se trata de la tecla "6"?
movlw 0x07 goto te6
movwf adcon1 btfsc porta,3 ;¿se trata de la tecla "-"?
bcf status,rp0 ;cambiar a banco 0 goto temenos
bcf status,rp1 goto fila02
clrf varteclado te4
clrf portb bcf status,rp0 ;escribe código ASCII de la tecla 4
;=============================================== bcf status,rp1
;pregunta por las teclas 1,2,3,+ movlw 0x34
;=============================================== movwf varteclado
fila00 goto sigproceso
bcf status,rp0 te5
bcf status,rp1 bcf status,rp0 ;escribe código ASCII de la tecla 5
bcf portb,3 bcf status,rp1
bsf portb,0 ;envía 1 a la primera fila 0 de teclas movlw 0x35
call retardo movwf varteclado
btfsc porta,0 ;¿se trata de la tecla "1"? goto sigproceso
goto te1 te6
btfsc porta,1 ;¿se trata de la tecla "2"? bcf status,rp0 ;escribe código ASCII de la tecla 6
goto t e2 bcf status,rp1
btfsc porta,2 ;¿se trata de la tecla "3"? movlw 0x36
goto te1 movwf varteclado
btfsc porta,3 ;¿se trata de la tecla "+"? goto sigproceso
goto temas
goto fila01
112
Tabla 57. Código del programa de control de un teclado matricial parte 1.
temenos btfsc porta,2 ;¿se trata de la tecla "="?
bcf status,rp0 ;escribe código ASCII de la tecla - goto teigual
bcf status,rp1 btfsc porta,3 ;¿se trata de la tecla "/"?
movlw 0x2d goto tediv
movwf varteclado goto fila00
goto sigproceso teL
;=============================================== bcf status,rp0 ;escribe código ASCII de la tecla L
;pregunta por las teclas 7,8,9,X bcf status,rp1
;=============================================== movlw 0x01
fila02 movwf varteclado
bcf status,rp0 goto sigproceso
bcf status,rp1 te0
bcf portb,1 bcf status,rp0 ;escribe código ASCII de la tecla 0
bsf portb,2 ;envía 1 a la primera fila 2 de teclas bcf status,rp1
call retardo movlw 0x30
btfsc porta,0 ;¿se trata de la tecla "7"? movwf varteclado
goto te7 goto sigproceso
btfsc porta,1 ;¿se trata de la tecla "8"? teigual
goto te8 bcf status,rp0 ;escribe código ASCII de la tecla =
btfsc porta,2 ;¿se trata de la tecla "9"? bcf status,rp1
goto te9 movlw 0x0f
btfsc porta,3 ;¿se trata de la tecla "X"? movwf varteclado
goto tepor goto sigproceso
goto fila03 tediv
te7 bcf status,rp0 ;escribe código ASCII de la tecla /
bcf status,rp0 ;escribe código ASCII de la tecla 7 bcf status,rp1
bcf status,rp1 movlw 0x2f
movlw 0x37 movwf varteclado
movwf varteclado goto sigproceso
goto sigproceso ;===============================================
te8 ; rutina para desplegar los valores del teclado
bcf status,rp0 ;escribe código ASCII de la tecla 8 ;===============================================
bcf status,rp1 sigproceso
movlw 0x38 ;Instrucciones pertenecientes al siguiente proceso
movwf varteclado .
goto sigproceso .
te9 .
bcf status,rp0 ;escribe código ASCII de la tecla 9 ;===============================================
bcf status,rp1 ; Subrutina
movlw 0x39 ;===============================================
movwf varteclado retardo
goto sigproceso bcf status,rp0 ;cambiar a pagina 0
tepor bcf status,rp1
bcf status,rp0 ;escribe código ASCII de la tecla X movlw .01
bcf status,rp1 movwf var1
movlw 0x2a ciclo_3
movwf varteclado movlw .100
goto sigproceso movwf var2
;=============================================== ciclo_2
;pregunta por las teclas L,0,=,/ movlw .166
;=============================================== movwf var3
fila03 ciclo_1
bcf status,rp0 decfsz var3,1
bcf status,rp1 goto ciclo_1
bcf portb,2 decfsz var2,1
bsf portb,3 ;envía 1 a la primera fila 3 de teclas goto ciclo_2
call retardo decfsz var1,1
btfsc porta,0 ;¿se trata de la tecla "L"? goto ciclo_3
goto teL return
btfsc porta,1 ;¿se trata de la tecla "0"? end
goto te0
113
2.6 CONFIGURACIÓN DE LAS INTERRUPCIONES
114
marcha, ejecutando sus respectivas instrucciones, mientras la causa de alguna
interrupción que haya sido habilitada no se haga presente. Cuando una
interrupción es activada, el microcontrolador deja de ejecutar las instrucciones del
programa principal, accediendo a una región de la memoria de programa que es
donde se encuentra el código de un programa que corresponde con el servicio de
la interrupción solicitada.
115
encuentran los bits que activan a las interrupciones, para mayor referencia
observe la imagen de la figura 28, en donde se describe con detalle la ubicación
de los bits que componen al registro ―i
ntcon‖ (para una mejor referencia consulte el
capitulo ―
reset interrupciones y watchdog‖ y ―
descripción de los registros‖, ambos
temas pertenecientes al modulo I). De los 8 bits que contiene el registro
―i
ntcon‖ solo nos interesan por el momento los que se identifican como ―GIE
‖ y
―PEI
E‖.
El bit PEIE sirve para activar las interrupciones del microcontrolador que son
originadas por dispositivos periféricos, esto es, además de activar todas las
interrupciones por medio del bit GIE, es necesario activar el bit PEIE si es que la
interrupción que se habilitará pertenece a un dispositivo periférico al
microcontrolador PIC. Entendiéndose por dispositivos periféricos, todos aquellos
que de manera externa al microcontrolador son necesarios para que se haga
llegar información al PIC, por ejemplo la comunicación serial asíncrona, la
conversión por medio del ADC, etc. Para activar el bit PEIE se necesita colocarlo
en estado lógico ―1‖.
Nuevamente indicamos que el bit GIE es el primero que tiene que ser activado,
para que cualquier interrupción surta efecto, y posteriormente tomar en cuenta sí
la interrupción que requerimos es originada por un dispositivo periférico, o por
activación interna al microcontrolador. Sí la interrupción se genera a través de un
dispositivo periférico, entonces tiene que hacerse uso del bit PEIE,
116
mientras que en caso contrario (si es originada de manera interna) se tendrá que
buscar cual es el bit que tiene que activarse.
LIST P=PIC16F874
;***************************************************************************************************************
; Declaración de Registros
;***************************************************************************************************************
Aquí se colocara la declaración de los registros que serán empleados
;***************************************************************************************************************
; Declaración de Bits
;***************************************************************************************************************
Aquí se colocara la declaración de los bits que serán empleados
;***************************************************************************************************************
; Inicio
;***************************************************************************************************************
reset
org 0 ;vector del reset
goto progprin
org 4
bcf status,rp0 ;cambiar al banco 0
bcf status,rp1
btfsc intcon,toif ;Pregunta si una interrupción se ha producido, a través del bit
;que hace la indicación al colocarse en estado lógico ―1 ‖ (bit bandera)
goto intertempo ;Si la respuesta es afirmativa accede al código de la Interrupción
retfie
;***************************************************************************************************************
; Inicio de la interrupción por uso del TIMER
;***************************************************************************************************************
intertempo
bcf status,rp0 ;cambiar al banco 0
bcf status,rp1
bcf intcon,gie ;desactiva al habilitador general de interrupciones.
bcf intcon,toie ;desactiva el bit que habilita la interrupción específica.
Aquí se colocan las líneas de código del programa de la interrupción que se tiene que ejecutar.
bcf intcon,toif ;limpia el bit bandera para preparar la siguiente interrupción
bsf intcon,toie ;activa el bit que habilita la interrupción específica.
bsf intcon,gie ;activa al habilitador general de interrupciones.
retfie ;comando que indica que el servicio de la interrupción ha terminado
;***************************************************************************************************************
; programa principal
;***************************************************************************************************************
progprin
Instrucciones generales para configurar la operación del microcontrolador
;----------------------------------------------------------------------------------------------------------------------------------
;Configuración de la interrupción
;----------------------------------------------------------------------------------------------------------------------------------
Instrucciones que configuran los detalles de la interrupción
bcf status,rp0 ;cambiar al banco 0
bcf status,rp1
bsf intcon,gie ;activa al habilitador general de interrupciones.
bsf intcon,toie ;activa el bit que habilita la interrupción específica.
Demás instrucciones
end
Tabla 59. Plantilla de ejemplo para configurar una interrupción.
117
En el código que muestra como ejemplo en la tabla 59, se muestra que para
configurar una interrupción se hace uso de los siguientes comandos:
118
tenga el bit bandera de la interrupción, y si este se encuentra en estado lógico ―1‖
significa que se ha identificado el origen de la interrupción, por lo tanto, ahora el
microcontrolador tiene que ejecutar el código de la rutina de interrupción. Se
debe de tomar en cuenta que existen aplicaciones en las que se requiere activar a
mas de una interrupción, y para ello tenemos que identificar perfectamente donde
se encuentran los bits bandera de cada una de las interrupciones.
119
Por último diremos que para un microcontrolador PIC, se tienen contempladas
diversas fuentes que pueden dar origen a una interrupción, por lo que se tiene que
revisar el manual del microcontrolador PIC que se vaya a utilizar para determinado
proyecto, las fuentes de interrupción más comunes en los microcontroladores PIC
son las siguientes:
120
puede morir! Es aquí donde toma importancia el empleo de los timers con los
que cuente el microcontrolador, ya que mientras se controla el conteo de tiempo,
en el mismo momento el microcontrolador puede estar realizando alguna otra
tarea.
El timer que sea activado le avisa al microcontrolador PIC por medio de una
interrupción que ha terminado con un conteo de tiempo. Aunque de manera
rigurosa, lo que cuentan los timer son los ciclos de ejecución de las instrucciones
de un programa en un microcontrolador, pero a la vez la ejecución de una
instrucción consume un tiempo, el cual sabemos su valor, por lo tanto, de manera
indirecta sabremos el tiempo total que se consumió al llevar a un contador desde
el valor de 00H al valor de FFH.
121
acontezca una interrupción.
El registro principal que se tiene que intervenir para configurar al timer de 8 bits
también conocido como timer0 en el microcontrolador PIC, es el identificado como
―OPT
ION REG‖ (option) y en el se configuran los bits que se describen a
continuación:
El bit 5 del registro OPTION REG se coloca en estado lógico ―0‖ ó ―1‖, de
acuerdo de donde se quiera tomar la fuente que da origen al incremento del
conteo que se realiza en el registro contador del timer, tomando en
122
cuenta que la manipulación del conteo se puede dar a través del pulso que
entregue un circuito oscilador externo, conectado a la terminal del
microcontrolador identificada como RA4/T0CKI, o el conteo también se puede dar
empleando el circuito de reloj interno que posee el microcontrolador. El bit 5 del
registro OPTION REG se identifica como T0CS (Bit selector del origen del reloj del
TMR0), a continuación se expresan las posibilidades de configuración del bit 5:
A través del bit 3 del registro OPTION REG se configura el destino del
prescaler, que tiene como función la de establecer cuantos ciclos de instrucción
deben de ejecutarse para que se tenga un incremento de una unidad en el registro
contador del timer. El bit 3 se identifica como PSA (Bit de asignación del
Prescaler), el cual se coloca en estado lógico ―0‖ ó ―1‖, dependiendo de las
siguientes posibilidades:
Los bits 2, 1 y 0 del registro OPTION REG se identifican como PS2, PS1 y PS0
(Bits selectores del rango Prescaler) respectivamente, tienen la tarea de fijar el
número de ciclos de instrucción que se deben ejecutar para que se incremente en
una unidad el valor del registro contador del timer, para ello en la tabla 60, se
muestran las combinaciones binarias que pueden adquirir los bits PS2, PS1 y PS0
generando las diferentes posibilidades de configuración de las cuales se tiene que
seleccionar la mas adecuada en función del valor de la temporización que sea
necesario habilitar.
123
Combinación binaria Rango Rango
PS2, PS1, PS0 TMR0 WDT
000 1:2 1:1
001 1:4 1:2
010 1:8 1:4
011 1 : 16 1:8
100 1 : 32 1 : 16
101 1 : 64 1 : 32
110 1 : 128 1 : 64
111 1 : 256 1 : 128
Tabla 60. Configuración del Prescaler del Timer0.
Los bits restantes del registro OPTION REG que no han sido descritos se
deben de colocar en estado lógico ―0‖ para que el timer0 sea completamente
configurado, por otra parte, el detalle de este registro se muestra de manera
completa en la imagen de la figura 29.
124
Cada vez que se desborda el registro TMR0 se tiene que producir una
interrupción para ―av
isar‖ que se ha completado un ciclo de tiempo bien
establecido, para lo cual en primera instancia se realizan las siguientes
operaciones:
1 1
Tiempo del ciclo de instrucción = = = 1 μseg
Ciclodeins trucción 1MHz
Esto quiere decir que cada 16.38 mseg se produce una interrupción, por lo que
para establecer un tiempo base de 1 segundo tenemos que determinar el número
de interrupciones que se requieren a través de la siguiente operación:
1segundo
Número de Interrupciones = = 61.035 interrupciones
16.38mseg
3
Considerando un circuito de reloj oscilador de 4MHz.
125
; Declaración de Registros retfie
;********************************************************* ;*********************************************************
w equ 0x00 ; programa principal
tmr0 equ 0x01 ;*********************************************************
status equ 0x03 progprin
portc equ 0x07 bsf status,rp0 ;cambiar al banco 1
intcon equ 0x0b bcf status,rp1
pir1 equ 0x0c movlw 0x00 ;configurar pines del
opsion equ 0x81 movwf trisc ;puerto C como salida
trisc equ 0x87 ;======================================
segundo equ 0x20 ;Configuración del timer
;********************************************************* ;======================================
; Declaración de Bits bsf status,rp0 ;cambiar al banco 1
;********************************************************* bcf status,rp1
ps0 equ 0 bcf opsion,tocs
ps1 equ 1 bcf opsion,psa
z equ 2 bsf opsion,ps0
ps2 equ 2 bcf opsion,ps1
toif equ 2 bsf opsion,ps2
psa equ 3 bcf status,rp0 ;cambiar al banco 0
toie equ 5 bcf status,rp1
tocs equ 5 bsf intcon,gie ;activación de
rp0 equ 5 bsf intcon,toie ;interrupciones
rp1 equ 6 clrf portc
peie equ 6 clrf tmr0
gie equ 7 ;======================================
;********************************************************* enciendeleds
; Inicio ;======================================
;********************************************************* clrf segundo
reset movlw 0xff
org 0 movwf portc
goto progprin mantenerencendido
org 4 movlw .61
bcf status,rp0 ;cambiar al banco 0 xorwf segundo,w
bcf status,rp1 btfss status,z
btfsc intcon,toif goto mantenerencendido
goto intertempo ;======================================
retfie apagaleds
;********************************************************* ;======================================
;Inicio de la interrupción del TIMER de 8 bits clrf segundo
;********************************************************* movlw 0x00
intertempo movwf portc
bcf status,rp0 ;cambiar al banco 0 mantenerapagado
bcf status,rp1 movlw .61
bcf intcon,gie ;desactivación de xorwf segundo,w
bcf intcon,toie ; interrupciones btfss status,z
incf segundo,1 goto mantenerapagado
bcf intcon,toif ;limpia la bandera goto enciendeleds
bsf intcon,toie ;activa las interrupciones end
Tabla 61. Programa para controlar los bits de un puerto por medio del
timer de 8 bits.
126
no genera exactamente 1 segundo, pero es muy cercano.
El bit 7 del registro INTCON que se identifica como GIE (Habilitación Global de
las Interrupciones), se debe de colocar en estado lógico ―1‖, para que sean
habilitadas todas las interrupciones, mientras que si es colocado un ―0‖ lógico en el
bit GIE, implicará que las interrupciones sean inhabilitadas. A continuación se
muestra de manera resumida lo expresado.
Los bits restantes del registro INTCON que no se emplean para el timer0,
deben de permanecer en estado lógico ―0‖. El detalle del registro INTCON se
muestra en la imagen de la figura 30.
127
Figura 30. Detalle del registro INTCON.
La bandera que indica que ha sido activada la interrupción, por
desbordamiento en el conteo del registro TMR0, esta implementada en el bit 2 del
registro INTCON el cual se identifica como TOIF, siendo el estado lógico de este
bit el que indica que se genero una interrupción, cuando esto suceda el bit TOIF
se colocará en el estado lógico ―1‖.
El primer registro que tiene que ser intervenido para configurar al timer de 16
bits (también conocido como timer1) en el microcontrolador PIC, es el identificado
como ―
T1CON‖ y en el se configuran los bits que se describen a continuación:
128
entre los 2 bits, para generar un valor que a su vez corresponde con el número de
ciclos de instrucción que se deben ejecutar para que se incremente en una unidad
el valor del registro contador del timer, en la tabla 62 se muestran las 4
combinaciones binarias que se pueden formar a partir de los bits T1CKPS1 y
T1CKPS0, generando las diferentes posibilidades de configuración, de las cuales
se tiene que seleccionar la mas adecuada, en función del valor de la
temporización o el número de eventos que sea necesario contabilizar.
El bit 3 del registro T1CON que se identifica como T1OSCEN (Bit de control del
oscilador del timer1), tiene la función de habilitar 2 terminales del microcontrolador
PIC para que a través de ellas se reciba la información de un disparo externo, que
a su vez alimenta a un oscilador interno en el microcontrolador. El oscilador
interno es empleado para sincronizar la señal externa con el proceso posterior que
realiza el timer1, contribuyendo con la generación de una señal apropiada
tomando en cuenta de que el disparo externo puede ser de no muy buena calidad,
por lo que el oscilador interno además posee de un circuito disparador de Smith.
El disparo externo puede emplearse para contabilizar tiempo o número de
eventos. Las terminales que son habilitadas en el microcontrolador por medio del
bit T1OSCEN, se identifican como RXX/T1OSI/XXX y RYY/T1OSO/T1CKI/XXX
(los términos RXX, RYY, XXX e YYY dependen del microcontrolador que se este
empleando, por lo tanto se les recomienda consultar el manual del
microcontrolador PIC correspondiente), estas terminales quedan configuradas
como entradas, por lo que los 2 bits relacionados en el registro TRIS de
configuración del determinado puerto son ignorados.
129
1 = Oscilador habilitado.- Esta configuración se emplea para configurar a las
terminales T1OSI y T1OSO/T1CKI como entradas.
0 = Oscilador apagado.- Por medio de esta configuración se deshabilita al
oscilador interno, quedando las terminales T1OSI y
T1OSO/T1CKI para otras aplicaciones.
El bit 2 del registro T1CON que se identifica como T1SYNC (Bit de control de
sincronización del disparo externo), tiene la tarea de sincronizar o no el disparo
externo del timer1, con el oscilador interno del microcontrolador. Cuando se
configura el timer1 para trabajar en el modo sincronizado, el microcontrolador no
se debe colocar en el modo de ahorro de energía (modo sleep), mientras que por
otra parte, cuando se configura el timer1 para funcionar en el modo no
sincronizado, no importa que el microcontrolador se encuentre en el modo de
ahorro de energía, porque el timer seguirá trabajando y aun así producirá su
respectiva interrupción, provocando que el microcontrolador se ―de
spierte‖. La
configuración del bit T1SYNC, a su vez depende del estado que se tenga en el bit
TMR1CS que también se encuentra dentro del registro T1CON. A continuación
se expresan las posibilidades de configuración del bit 2.
El bit 1 del registro T1CON que se identifican como TMR1CS (Bit que controla
la selección del origen del oscilador), tiene la tarea de seleccionar la fuente que
origina la generación de la señal de reloj con la que el timer realizara su función.
Se cuenta con 2 posibilidades de configuración para por medio de la señal de
reloj, incrementar el valor de los registros del timer 1, estas opciones se
encuentran entre el empleo del reloj interno (equivalente a dividir la frecuencia del
oscilador entre 4) del microcontrolador PIC, y la utilización de un circuito oscilador
externo, el cual se conectaría a la terminal identificada como …/T1OSO/T1CKI/…
aclarando que con la presente configuración, el incremento de los registros del
130
timer 1 se darán cuando se presente el flanco de ascenso en la oscilación externa.
El bit 0 del registro T1CON que se identifica como TMR1ON (bit que enciende
la timer 1), tiene la misión de activar la operación del timer 1.
1 = Activa el Timer 1
0 = Detiene el Timer 1
131
colocados en estado lógico ―0‖ los bits identificados como T1OSCEN, T1SYNC y
TMR1CS, mientras que el bit TMR1ON se debe fijar en el estado lógico ―1‖ para
encender al timer 1; recuerde que estos bits se encuentran dentro del registro
T1CON.
1 1
Tiempo del ciclo de instrucción = = = 1 μseg
Ciclodeins trucción 1MHz
4
Considerando un circuito de reloj oscilador de 4MHz.
132
se tiene que contabilizar el número de interrupciones que son necesarias, y para
calcularlas lo hacemos mediante la siguiente operación:
1segundo
Número de Interrupciones = = 3.81 interrupciones
262.14mseg
133
LIST P=PIC16F874 clrf tmr1l
;********************************************************* clrf tmr1h
; Declaración de Registros bcf pir1,tmr1if ;limpia la bandera que provoco la interrupción
;********************************************************* bsf status,rp0 ;cambiar al banco 1
w equ 0x00 bcf status,rp1
tmr0 equ 0x01 bsf pie1,tmr1ie ;activa la interrupción del timer 1
status equ 0x03 bcf status,rp0 ;cambiar al banco 0
portc equ 0x07 bcf status,rp1
intcon equ 0x0b bsf intcon,gie ;activación general de interrupciones.
pir1 equ 0x0c retfie
tmr1l equ 0x0e ;*********************************************************
tmr1h equ 0x0f ; programa principal
t1con equ 0x10 ;*********************************************************
rcsta equ 0x18 progprin
cmcon equ 0x1f bsf status,rp0 ;cambiar al banco 1
opsion equ 0x81 bcf status,rp1
trisc equ 0x87 movlw 0x00 ;configurar pines del puerto
pie1 equ 0x8c movwf trisc ;C como salida
continte equ 0x20 ;*********************************************************
;********************************************************* ;Configuración del timer, y declaración de variables
; Declaración de Bits ;*********************************************************
;********************************************************* bcf status,rp0 ;cambiar al banco 0
c equ 0 bcf status,rp1
tmr1if equ 0 bcf t1con,t1ckps0
tmr1ie equ 0 bsf t1con,t1ckps1
tmr1on equ 0 bcf t1con,t1oscen
tmr1cs equ 1 bcf t1con,t1sync
z equ 2 bcf t1con,tmr1cs
t1sync equ 2 bsf t1con,tmr1on
t1oscen equ 3 bsf intcon,gie ;activar habilitador general de interrupciones.
t1ckps0 equ 4 bsf intcon,peie
t1ckps1 equ 5 bsf status,rp0 ;cambiar al banco 1
rp0 equ 5 bcf status,rp1
rp1 equ 6 bsf pie1,tmr1ie ;activa la interrupción del timer 1
peie equ 6 bcf status,rp0 ;cambiar al banco 0
gie equ 7 bcf status,rp1
;********************************************************* clrf portc
; Inicio otro
;********************************************************* clrf tmr1l
reset clrf tmr1h
org 0 clrf continte
goto progprin verinterrup ;verifica que se efectúen 3 interrupciones
org 4 movlw 0x03
bcf status,rp0 ;cambiar al banco 0 xorwf continte,w
bcf status,rp1 btfss status,z
btfsc pir1,tmr1if goto verinterrup
goto intertempo verpartealta ;verifica que en la parte alta del registro
retfie movlw 0xcf ;de 16 bits se tenga el valor CF
;********************************************************* xorwf tmr1h,w
;Inicio de la interrupción por uso del TIMER 1 btfss status,z
;********************************************************* goto verpartealta
intertempo verpartebaja ;verifica que en la parte baja del registro
bcf status,rp0 ;cambiar al banco 0 movlw 0x5c ;de 16 bits se tenga el valor 5C
bcf status,rp1 xorwf tmr1l,w
bcf intcon,gie ;desactivación general de interrupciones. btfss status,z
bsf status,rp0 ;cambiar al banco 1 goto verpartebaja
bcf status,rp1 incsegundo ;incrementa el conteo en el puerto C
bcf pie1,tmr1ie ;desactiva la interrupción del timer 1 inca portc,1
bcf status,rp0 ;cambiar al banco 0 clrf continte
bcf status,rp1 goto otro
Inca continte,1 ;incrementa el contador de interrupciones end
Tabla 63. Programa para controlar los bits de un puerto por medio del
timer de 16 bits.
134
Para que se active la interrupción originada por el desbordamiento en el conteo
del valor que se encuentra dentro de los registros TMR1H y TMR1L, es necesario
que sean intervenidos los bits 7 y 6 que se encuentran contenidos en el registro
identificado como ―IN
TCON‖, además del bit 0 del registro ―PIE
1‖, de acuerdo con
lo siguiente.
El bit 7 del registro INTCON que se identifica como GIE (Bit de habilitación
Global de las Interrupciones), se debe de colocar en estado lógico ―1‖, para que
sean habilitadas todas las interrupciones, mientras que si un ―0‖ lógico es colocado
en el bit GIE, todas las interrupciones serán inhabilitadas. A continuación se
muestra un resumen de lo expresado.
El bit 6 del registro INTCON que se identifica como PEIE (Bit que Habilita las
interrupciones por periférico), se debe colocar en estado lógico ―
1‖, para que la
interrupción por desbordamiento en el conteo de los registros TMR1H y TMR1L
surta efecto, ya que el timer 1 se encuentra clasificado como elemento periférico.
Los bits restantes del registro INTCON que no se emplean para el timer1,
deben de permanecer en estado lógico ―0‖. El detalle del registro INTCON se
muestra en la imagen de la figura 32.
135
detalle del registro PIE1 se muestra en la imagen de la figura 33.
136
La USART trabaja mediante el protocolo de comunicación serial conocido
como RS-232, en el cual se establece que la transmisión de datos se realiza a
través de un hilo conductor, enviando un solo bit cada vez, esto quiere decir que sí
el dato se encuentra conformado por 8 bits, se estará transmitiendo bit por bit
hasta completar la transferencia de los 8 bits.
137
Para dar por terminada la transmisión de un dato, el equipo transmisor le
―i
nforma‖ al receptor que ha terminado con el envío, por medio del empleo de un
bit identificado como de paro, el cual puede estar implementado por un solo bit o
por 2 de acuerdo con el protocolo RS-232.
138
referencia con respecto de cualquier otro PIC.
139
bsf status,rp0 ;cambiar al banco 1
bcf status,rp1
movlw b'X0XXXXXX' ;configura el bit 6 como salida, los demás bits no importan de momento
movwf trisc ;enviar configuración al registro del puerto C
El bit 7 del registro TXSTA que se identifica como CSRC (Bit que controla el
origen de la señal de reloj), tiene la tarea de seleccionar un modo de operación del
microcontrolador (como maestro o esclavo), si es que su módulo USART se
encuentra configurado en el modo de operación ―sí
ncrona‖. De manera contraria,
sí el modulo USART se configuro para operar de manera ―así
ncrona‖, este bit
tiene que ser ignorado no importando su estado lógico.
El bit 6 del registro TXSTA que se identifica como TX9 (bit que habilita la
transmisión de 9 bits), se debe colocar en estado lógico ―1‖, para que surta efecto
el envío de 9 bits que conformarán al dato que será transmitido, mientras que al
colocar el bit TX9 en estado lógico ―0‖, configura a la USART para que se
transmitan datos compuestos por 8 bits.
140
de la transmisión por medio del módulo USART.
Por medio del bit 4 del registro TXSTA que se identifica como SYNC (bit que
selecciona el modo de operación de la USART), se determina el modo de
operación del módulo USART, teniéndose la posibilidad de seleccionar entre la
operación síncrona o asíncrona.
1 = Modo Síncrono.
0 = Modo Asíncrono.
El bit 2 del registro TXSTA que se identifica como BRGH (bit de selección de
alta taza de transferencia), tiene la tarea de seleccionar entre las posibilidades de
transmitir a baja o alta velocidad, si es que su módulo USART se encuentra
configurado en el modo de operación ―
asíncrona‖. De manera contraria, sí el
modulo USART se configuro para operar de manera ―sí
ncrona‖, este bit no se
emplea, por lo que no importa su estado lógico.
El bit 1 del registro TXSTA que se identifica como TRMT (bit que configura el
estado de la transmisión), se emplea para configurar la indicación de cuando un
dato sea transmitido, esto es, se generara un aviso cuando el dato sea transmitido
completamente (TSR vacío) o cuando el dato aun no comience a transmitirse
(TSR lleno).
1 = TSR vacío.
0 = TSR lleno.
El bit 0 del registro TXSTA que se identifica como TX9D (bit que conforma al
noveno bit de datos o también puede ser el bit de paridad), se utiliza
141
solamente cuando se configura al módulo USART para que transmita 9 bits de
datos, o cuando se habilita el empleo del bit de paridad. Si el modulo USART se
configura para transmitir 8 bits de datos, sin bit de paridad, el bit TX9D no se
emplea y por lo general se le carga el estado lógico ―0‖.
142
Baud FOSC = 20 MHz SPBRG FOSC = 16 MHz SPBRG FOSC = 10 MHz SPBRG
Rate valor valor valor
(k) KBAUD ERROR (decimal) KBAUD ERROR (decimal) KBAUD ERROR (decimal)
0.3 NA — — NA — — NA — —
1.2 NA — — NA — — NA — —
2.4 NA — — NA — — NA — —
9.6 NA — — NA — — 9.766 +1.73% 255
19.2 19.53 +1.73% 255 19.23 +0.16% 207 19.23 +0.16% 129
76.8 76.92 +0.16% 64 76.92 +0.16% 51 75.76 -1.36% 32
96 96.15 +0.16% 51 95.24 -0.79% 41 96.15 +0.16% 25
300 294.1 -1.96 16 307.69 +2.56% 12 312.5 +4.17% 7
500 500 0 9 500 0 7 500 0 4
HIGH 5000 — 0 4000 — 0 2500 — 0
LOW 19.53 — 255 15.625 — 255 9.766 — 255
Baud FOSC = 7.15909 MHz SPBRG FOSC = 5.0688 MHz SPBRG FOSC = 4 MHz SPBRG
Rate valor valor valor
(k) KBAUD ERROR (decimal) KBAUD ERROR (decimal) KBAUD ERROR (decimal)
0.3 NA — — NA — — NA — —
1.2 NA — — NA — — NA — —
2.4 NA — — NA — — NA — —
9.6 9.622 +0.23% 185 9.6 0 131 9.615 +0.16% 103
19.2 19.24 +0.23% 92 19.2 0 65 19.231 +0.16% 51
76.8 77.82 +1.32 22 79.2 +3.13% 15 75.923 +0.16% 12
96 94.20 -1.88 18 97.48 +1.54% 12 1000 +4.17% 9
300 298.3 -0.57 5 316.8 5.60% 3 NA — —
500 NA — — NA — — NA — —
HIGH 1789.8 — 0 1267 — 0 100 — 0
LOW 6.991 — 255 4.950 — 255 3.906 — 255
Baud FOSC = 3.579545 MHz SPBRG FOSC = 1 MHz SPBRG FOSC = 32.768 KHz SPBRG
Rate valor valor valor
(k) KBAUD ERROR (decimal) KBAUD ERROR (decimal) KBAUD ERROR (decimal)
0.3 NA — — NA — — 0.303 +1.14% 26
1.2 NA — — 1.202 +0.16% 207 1.170 -2.48% 6
2.4 NA — — 2.404 +0.16% 103 NA — —
9.6 9.622 +0.23% 92 9.615 +0.16% 25 NA — —
19.2 19.04 -0.83% 46 19.24 +0.16% 12 NA — —
76.8 74.57 -2.90% 11 83.34 +8.51% 2 NA — —
96 99.43 +3.57% 8 NA — — NA — —
300 298.3 0.57% 2 NA — — NA — —
500 NA — — NA — — NA — —
HIGH 894.9 — 0 250 — 0 8.192 — 0
LOW 3.496 — 255 0.9766 — 255 0.032 — 255
Tabla 64. Tasa de transferencia para el modo Síncrono.
143
transmitidos los datos (Kbaud), y por ende el error involucrado.
Baud FOSC = 20 MHz SPBRG FOSC = 16 MHz SPBRG FOSC = 10 MHz SPBRG
Rate valor valor valor
(k) KBAUD ERROR (decimal) KBAUD ERROR (decimal) KBAUD ERROR (decimal)
0.3 NA — — NA — — NA — —
1.2 1.221 +1.73% 255 1.202 +0.16% 207 1.202 +0.16% 129
2.4 2.404 +0.16% 129 2.404 +0.16% 103 2.404 +0.16% 64
9.6 9.469 -1.36% 32 9.615 +0.16% 25 9.766 +1.73% 15
19.2 19.53 +1.73% 15 19.23 +0.16% 12 19.53 +1.73% 7
76.8 78.13 +1.73% 3 83.33 +8.51% 2 78.13 +1.73% 1
96 104.2 +8.51% 2 NA — — NA — —
300 312.5 +4.17% 0 NA — — NA — —
500 NA — — NA — — NA — —
HIGH 312.5 — 0 250 — 0 156.3 — 0
LOW 1.221 — 255 0.977 — 255 0.6104 — 255
Baud FOSC = 7.15909 MHz SPBRG FOSC = 5.0688 MHz SPBRG FOSC = 4 MHz SPBRG
Rate valor valor valor
(k) KBAUD ERROR (decimal) KBAUD ERROR (decimal) KBAUD ERROR (decimal)
0.3 NA — — 0.31 +3.13% 255 0.3005 -0.17% 207
1.2 1.203 +0.23% 92 1.2 0 65 1.202 +1.67% 51
2.4 2.380 -0.83% 46 2.4 0 32 2.404 +1.67% 25
9.6 9.322 -2.90% 11 9.9 +3.13% 7 NA — —
19.2 18.64 -2.90% 5 19.8 +3.13% 3 NA — —
76.8 NA — — 79.2 +3.13% 0 NA — —
96 NA — — NA — — NA — —
300 NA — — NA — — NA — —
500 NA — — NA — — NA — —
HIGH 111.9 — 0 79.2 — 0 62.500 — 0
LOW 0.437 — 255 0.3094 — 255 3.906 — 255
Baud FOSC = 3.579545 MHz SPBRG FOSC = 1 MHz SPBRG FOSC = 32.768 KHz SPBRG
Rate valor valor valor
(k) KBAUD ERROR (decimal) KBAUD ERROR (decimal) KBAUD ERROR (decimal)
0.3 0.301 +0.23% 185 0.300 +0.16% 51 0.256 -14.67% 1
1.2 1.190 -0.83% 46 1.202 +0.16% 12 NA — —
2.4 2.432 +1.32% 22 2.232 -6.99% 6 NA — —
9.6 9.322 -2.90% 5 NA — — NA — —
19.2 18.64 -2.90% 2 NA — — NA — —
76.8 NA — — NA — — NA — —
96 NA — — NA — — NA — —
300 NA — — NA — — NA — —
500 NA — — NA — — NA — —
HIGH 55.93 — 0 15.63 — 0 0.512 — 0
LOW 0.2185 — 255 0.0610 — 255 0.0020 — 255
Tabla 65. Tasa de transferencia para el modo Asíncrono cuando BRGH
= 0.
144
Baud FOSC = 20 MHz SPBRG FOSC = 16 MHz SPBRG FOSC = 10 MHz SPBRG
Rate (k) valor valor valor
KBAUD ERROR (decimal) KBAUD ERROR (decimal) KBAUD ERROR (decimal)
9600 9.615 +0.16% 129 9.615 +0.16% 103 9.615 +0.16% 64
19200 19.230 +0.16% 64 19.230 +0.16% 51 18.939 -1.36% 32
38400 37.878 -1.36% 32 38.461 +0.16% 25 39.062 +1.7% 15
57600 56.818 -1.36% 21 58.823 +2.12% 16 56.818 -1.36% 10
115200 113.636 -1.36% 10 111.111 -3.55% 8 125 +8.51% 4
250000 250 0 4 250 0 3 NA — —
625000 625 0 1 NA — — 625 0 0
1250000 1250 0 0 NA — — NA — —
Baud FOSC = 7.15909 MHz SPBRG FOSC = 5.0688 MHz SPBRG FOSC = 4 MHz SPBRG
Rate (k) valor valor valor
KBAUD ERROR (decimal) KBAUD ERROR (decimal) KBAUD ERROR (decimal)
9600 9.520 -0.83% 46 9598.485 0.016% 32 9615.385 0.160% 25
19200 19.454 +1.32% 22 18632.35 -2.956% 16 19230.77 0.160% 12
38400 37.286 -2.90% 11 39593.75 3.109% 7 35714.29 -6.994% 6
57600 55.930 -2.90% 7 52791.67 -8.348% 5 62500 8.507% 3
115200 111.860 -2.90% 3 105583.3 -8.348% 2 125000 8.507% 1
250000 NA — — 316750 26.700% 0 250000 0.000% 0
625000 NA — — NA — — NA — —
1250000 NA — — NA — — NA — —
Baud FOSC = 3.579545 MHz SPBRG FOSC = 1 MHz SPBRG FOSC = 32.768 KHz SPBRG
Rate (k) valor valor valor
KBAUD ERROR (decimal) KBAUD ERROR (decimal) KBAUD ERROR (decimal)
9600 9725.543 1.308% 22 8.928 -6.994% 6 NA NA NA
19200 18640.63 -2.913% 11 20833.3 8.507% 2 NA NA NA
38400 37281.25 -2.913% 5 31250 -18.620% 1 NA NA NA
57600 55921.88 -2.913% 3 62500 +8.507% 0 NA NA NA
115200 111243.8 -2.913% 1 NA — — NA NA NA
250000 223687.5 -10.525% 0 NA — — NA NA NA
625000 NA — — NA — — NA NA NA
1250000 NA — — NA — — NA NA NA
Tabla 66. Tasa de transferencia para el modo Asíncrono cuando BRGH
= 1.
Con este último paso ha quedado configurado el módulo USART para que
transmita datos, por lo que ahora se tiene que cargar el valor del dato que se
quiere transmitir, en el registro llamado ―T
XREG‖ (buffer de transmisión).
Cuando se guarda un dato en el registro TXREG, de inmediato se comienza a
transferir enviando bit a bit (obviamente de manera previa se configuro y activo la
USART) hacia la terminal del microcontrolador identificada como Tx.
145
un siguiente dato cuando no ha terminado con el anterior. Para esto último se
cuenta con 2 posibilidades de configuración. En la primera de ellas se puede
activar el aviso por medio de una interrupción, por medio de fijar el estado lógico
―1‖ en el bit TXIE que se encuentra en el registro PIE1; teniendo su respectiva
bandera en el bit TXIF que se encuentra en el registro PIR1, la cual se colocara en
estado lógico ―1‖ cuando el dato que se esta transmitiendo haya sido
completamente transferido, o dicho de otra manera, cuando el dato que se alojo
en el registro TXREG se ha enviado completamente. La segunda manera de
indicar que un dato ha sido transmitido, es simplemente esperar a que sean
enviados todos los bits que componen al dato, por medio de la instrucción ―
btfss
pir1,txif‖, en la cual también se puede ocupar a la bandera TXIF del registro PIR1,
para saber en que momento se ha vaciado el buffer de transmisión. En la tabla
67 se muestra una propuesta de código para configurar a la USART en el modo de
transmisión asíncrona.
Una vez que han sido identificados los pines del microcontrolador que
contienen las terminales de transmisión y recepción de datos mediante el modulo
USART, sabremos como configurar dichos pines. Se muestra en la imagen de la
figura 35 para una mejor referencia, un ejemplo típico de la ubicación de las
146
terminales en 3 microcontroladores PIC diferentes.
147
que se vaya a emplear a la USART en el modo full duplex (recepción y transmisión
de datos al mismo tiempo). La explicación del detalle de los bits CSRC, SYNC y
BRGH se encuentra en el apartado ―U
SART en modo transmisión‖, y el detalle de
la composición del registro TXSTA se muestra en la figura 36.
Otro registro que también debe ser manipulado es el identificado como ―spb
rg‖,
siendo a través de este registro el medio para determinar el valor de la tasa de
trasferencia de los datos (baud rate), con la cual serán recibidos por el
microcontrolador PIC. Los distintos valores de tasa de trasferencia se
encuentran indicados en las tablas 64, 65 y 66, recordando que la tasa de
trasferencia en un microcontrolador PIC, depende de valor que se tenga en el
circuito oscilador del PIC.
El bit 7 del registro RCSTA que se identifica como SPEN (Bit que habilita al
puerto serie del PIC), tiene como actividad principal la de habilitar tanto a la
terminal identificada como Tx y Rx, para que realicen la función de comunicar de
manera serial al microcontrolador, por lo que una vez que ha sido activado este
bit, se establecen los niveles eléctricos correspondientes sobre las terminales Tx y
Rx.
El bit 6 del registro RCSTA que se identifica como RX9 (bit que habilita la
recepción de 9 bits), se debe colocar en estado lógico ―1‖, para que surta efecto la
recepción de 9 bits que conformarán al dato que será recepcionado, mientras que
al colocar el bit TX9 en estado lógico ―0‖, configura a la USART para que se
reciban datos compuestos por 8 bits. Recuerde que se coloca la recepción de 9
bits de datos, cuando en la transmisión se tienen también 9 bits de datos, por lo
tanto, el dispositivo transmisor como el receptor deben estar fijos con el
148
mismo número de bits que conforman al dato que será intercambiado.
El bit 5 del registro RCSTA que se identifica como SREN (bit que habilita la
recepción de un solo dato), tiene la tarea de activar la recepción de un solo dato, si
es que su módulo USART se encuentra configurado en el modo de operación
―sí
ncrona‖. De manera contraria, sí el modulo USART se configuro para operar
de manera ―así
ncrona‖, este bit tiene que ser ignorado no importando su estado
lógico.
Por medio del bit 4 del registro RCSTA que se identifica como CREN (bit que
habilita la recepción continua de datos), el modulo USART del microcontrolador
PIC, tiene la tarea de recibir de manera continua todos los datos que se le envíen,
aun cuando se encuentre configurado tanto en el modo asíncrono como síncrono.
149
cuando el modulo USART se encuentra en el modo de operación asíncrona.
El bit 2 del registro RCSTA que se identifica como FERR (bit bandera que
indica errores en la trama), muestra por medio del estado lógico ―
1‖ sí el dato que
fue recibido no cumple con el contenido de la información real, este error se debe
a un bit de la información que se encuentre erróneo, este error puede ser
corregido mediante la implementación del bit de paridad.
El bit 1 del registro RCSTA que se identifica como OERR (bit bandera que
indica un sobre flujo de datos), se emplea para detectar sí en el momento que la
USART se encuentra recepcionando un dato, llega otro antes de que el primero
termine de recepcionarse.
1 = Error por sobre flujo de datos (puede limpiarse al limpiar el bit CREN).
0 = Sin error por sobre flujo de datos.
El bit 0 del registro RCSTA que se identifica como RX9D (bit que conforma al
noveno bit de datos o también puede ser el bit de paridad), se utiliza solamente
cuando se configura al módulo USART para que transmita 9 bits de datos, o
cuando se habilita el empleo del bit de paridad. Si el modulo USART se
configura para transmitir 8 bits de datos, sin bit de paridad, el bit RX9D no se
emplea y por lo general se le carga el estado lógico ―0‖.
150
Figura 37. Detalle del registro RCSTA.
Con la configuración del registro RCSTA paso ha quedado configurado el
módulo USART para que reciba datos, por lo que ahora debemos de tomar en
cuenta que la información que se reciba de manera serial se encontrará alojada en
el registro llamado ―R
CREG‖ (buffer de recepción). Cada vez que se recibe un
dato por medio de la terminal Rx del microcontrolador (previa activación de la
USART), se guardan en el registro RCREG, por lo que de inmediato se debe
tomar el dato recepcionado y cambiarlo a otro registro para almacenarlo, porque
solo existe el registro RCREG para recepcionar los datos, y si no es guardado se
perderá cuando suceda una nueva recepción de datos.
151
el bit RCIE que se encuentra en el registro PIE1. El bit bandera de la
interrupción por recepción de dato se encuentra en el bit RCIF que se encuentra
en el registro PIR1, esta bandera se colocara en estado lógico ―1‖ cuando el dato
que se recepciono ha llegado de manera completa, o dicho de otra manera,
cuando el dato que se alojo en el registro RCREG se ha recibido completamente.
152
LIST P=PIC16F876 ;************************************************************
;************************************************************ ; Programa principal
; Declaración de Registros ;************************************************************
;************************************************************ iniProg
status equ 0x03 bsf status,rp0 ;cambiar al banco 1
portc equ 0x07 bcf status,rp1
intcon equ 0x0b movlw b'10000000' ;config el bit 7 como entrada
pir1 equ 0x0c movwf trisc ;y los demás bits como salidas
rcsta equ 0x18 ;----------------------------------------------------------------------
txreg equ 0x19 ; Activación de la USART en modo Tx
rcreg equ 0x1a ;----------------------------------------------------------------------
trisc equ 0x87 bsf status,rp0 ;cambiar al banco 1
pie1 equ 0x8c bcf status,rp1
txsta equ 0x98 movlw b'00100110'
spbrg equ 0x99 movwf txsta
recep equ 0x25 movlw .25
;************************************************************ movwf spbrg
; Declaración de Bits bcf status,rp0 ;cambiar al banco 0
;************************************************************ bcf status,rp1
adon equ 0 bsf rcsta,spen ;habilita. del puerto serial
c equ 0 bsf rcsta,cren ;activa la recepción continua
z equ 2 bsf status,rp0 ;cambiar al banco 1
txif equ 4 bcf status,rp1
rcif equ 5 bsf pie1,rcie ;activa. Inter. por recepción
rcie equ 5 ;----------------------------------------------------------------------
rp0 equ 5 ; Retransmite el dato recibido mediante USART
rp1 equ 6 ;----------------------------------------------------------------------
peie equ 6 esperadato
adif equ 6 bcf status,rp0 ;cambiar al banco 0
gie equ 7 bcf status,rp1
;************************************************************ movf recep,w
; Inicio xorlw 0x00
;************************************************************ btfss status,z
reset goto transmite
org 0 goto esperadato
goto iniProg transmite
org 4 call subTx
bcf status,rp0 ;cambiar al banco 0 clrf recep
bcf status,rp1 goto esperadato
btfsc pir1,rcif ;¿interrupción por USART? ;************************************************************
goto interserie ; Subrutinas
retfie ;************************************************************
;************************************************************ subTx ;Subrutina para Tx un dato mediante la USART
; Interrupciones bsf status,rp0 ;cambiar al banco 1
;************************************************************ bcf status,rp1
interserie ;Interrupción por USART (Recepción) movlw b'00100110'
bcf status,rp0 ;cambiar al banco 0 movwf txsta
bcf status,rp1 movlw .25
bcf intcon,gie ;desactivación de las Inter. movwf spbrg
movf rcreg,w ;recuperar el dato recibido bcf status,rp0 ;cambiar al banco 0
movwf recep bcf status,rp1
bcf pir1,rcif ;limpia la bandera movf recep,w
bsf intcon,gie ;activa las interrupciones movwf txreg
retfie ;termina la interrupción espera
btfss pir1,txif
goto espera
return
end
153
muestra el código de un programa para implementar la interrupción. Se debe
considerar que se esta empleando un microcontrolador PIC16F87X, pero si se
requiere usar otro, lo único que se tiene que cambiar es la ubicación de las
terminales Tx y Rx. En la tabla 70 se muestra un programa completo, en el que
el dato que reciba el microcontrolador PIC de manera serial lo retransmitirá,
también empleando la USART.
154
4ª de forros.qxd:sumario 223 21/11/13 18:13 Página 4ªFo1
Creatronica 349.qxd:Maquetación 1 21/4/16 12:11 p.m.
p Página 1