Está en la página 1de 41

Los Puertos Paralelos de

Entrada/Salida

3. Los Puertos Paralelos de Entrada/Salida


Los integrados PIC16F874 y PIC16F877 poseen 5 puertos de entrada/salida denominados
PORTA, PORTB, PORTC, PORTD y PORTE, mientras que el PIC16F873 y PIC16F876 poseen 3.
Estos puertos son totalmente programables, es decir, sus lneas pueden ser configuradas
para trabajar como entradas o como salidas a seleccin del programador.
3.1. El Puerto A (PORTA)
3.1.1. Registros asociados al Puerto A
El puerto A posee 6 lneas bidireccionales. Los 3 registros asociados a este puerto son:
1. Registro PORTA (05H), que es el registro de estado del Puerto A. Cada uno de los 6 bits
menos significativos (RA5,...,RA0) de este registro estn asociados a la lnea fsica
correspondiente del puerto. Al hacer una lectura este registro se lee el estado de todas las patitas
del puerto. Todas las escrituras al registro son operaciones del tipo lee- modifica-escribe, es
decir, toda escritura al puerto implica que el estado de las patitas es ledo, luego es modificado y
posteriormente se escribe al latch de datos del puerto.

2. Registro TRISA (85H). Cada bit de este registro configura la direccin en que fluye la
informacin de la patita correspondiente del puerto A, as, para k=0,1,...,5:
Bit k de TRISA = 1 configura la patita RAk del puerto A como Entrada
Bit k de TRISA = 0 configura la patita RAk del puerto A como Salida

Todas las patitas del puerto A poseen diodos de proteccin conectados a Vdd (contra altos
voltajes de entrada) y a Vss (contra voltajes negativos) adems, manejan niveles de entrada tipo
TTL y como salidas se comportan como drivers tipo CMOS. Excepto la patita RA4, la cual
como entrada posee un Disparador Schmitt trigger y como salida es de Drenaje abierto, adems
RA4 slo posee un diodo de proteccin conectado a Vss.
3. El Registro ADCON1 (9FH). Las patitas RA0, RA1, RA2, RA3 y RA5 estn
multiplexadas con las entradas analgicas AN0,...,AN4, respectivamente; de manera que
antes de utilizarlas debemos configurar si sern usadas como entradas analgicas o como
entradas/salidas digitales. Para seleccionar la segunda opcin (entradas/salidas digitales) se
debe colocar en el nible menos significativa de este registro un 01102 (es decir, un 06h).
2

Registro ADCON1 (direccin 9Fh)


A continuacin se indica el registro ADCON1:
U-0
ADFM
Bit 7

U-0
---

R/W-0
---

U-0
---

R/W-0
PCFG3

R/W-0
PCFG2

R/W-0
PCFG1

R/W-0
PCFG0
Bit 0

bit 3-0: PCFG3:PCFG0: bits de configuracin de los canales de entrada del convertidor A/D.
Se utilizan para configurar las patillas como E/S digital o como entrada analgica.

En las siguientes dos figuras se muestra el detalle de implementacin interna de las patitas del
puerto A, mostrando la diferencia entre las patitas RA4 y las dems patitas del puerto A:

Patitas RA0,RA1,RA2,RA3 y RA5

Patita RA4

3.1.2. Estado de lectura y escritura de una lnea de I/O


Por ser el PIC ms manejable para diversas exigencias de utilizacin, el Micro PIC puede ser
implementado en diversas topologas de estado de escritura para la lnea de I/O. Teniendo en cuenta
que los pines de los puertos E/S tienen igual comportamiento o ligeramente difiere uno del otro.
Conociendo mejor el funcionamiento de diversos estados de escritura, podemos aprovechar de mejor
manera las caractersticas y optimizar nuestro proyecto.
3

1. Estado de lectura y escritura de las lneas RA0, RA1, RA2, RA3 y RA5
El esquema para estas patitas muestra el estado de escritura extrado del data sheet del Microchip. Por
ejemplo, se toma la lnea RA0 para analizar el funcionamiento del estado de salida cuando la misma
funciona como entrada o como salida:
a. Funcionamiento como Entrada
Para configurar la lnea RA0 como entrada, se debe poner a 1 el bit 0 del registro TRISA:
bsf

TRISA, 0

Esta instruccin determina una conmutacin a 1 del estado lgico del Flip Flop del latch D
indicado en el circuito con el nombre TRIS latch. Para otra lnea de I/O existe uno de estos Flip
Flop y el estado lgico en que se mantiene depende estrictamente del estado lgico del bit relativo
al registro TRIS (en otras palabras, el mejor diseo de todos los bits del registro TRIS es
fsicamente realizable con un latch TRIS).
La salida Q del latch TRIS es conectada a la entrada de una compuerta lgica de tipo OR, esto
significa que independientemente del valor presente en la otra entrada, la salida de la compuerta
OR siempre estar en uno si una de sus entradas estn en uno. En esta condicin, el transistor P no
conduce manteniendo la lnea RA0 desconectada del positivo de la alimentacin.
Del mismo modo la salida negativa Q del latch TRIS es conectada a la entrada de una compuerta
AND, en donde, la salida de sta estar siempre en 0 mientras una de sus entradas valga 0. En esta
condicin el transistor N no conduce manteniendo la lnea RA0 desconectada de la masa. El
estado lgico de la lnea RA0 depender exclusivamente del circuito externo al cual estar
conectado. Aplicando 0 o 5 volts al pin RA0, ser posible leer el estado presente del circuito
externo en la entrada del bloque representado por TTL input buffer y el latch de entrada.
b. Funcionamiento como Salida
Para configurar la lnea RA0 como salida, se debe colocar 0 en el bit 0 del registro TRISA con la
instruccin:
bcf

TRISA, 0

Esta instruccin determina la conmutacin a cero de la salida Q del latch TRIS (a 1 si la salida Q
es negativa). En este estado el valor de la salida de las compuertas OR y AND dependen
exclusivamente del estado de salida del Q negado del latch de datos. Como para el latch TRIS, el
latch de datos depende del estado de un bit de un registro, particularmente del registro PORTA. Su
salida negativa ser enviada a la entrada de las dos compuertas lgicas OR y AND que est
directamente sobre la base del transistor P y N. Si ponemos en 0 el bit 0 del registro PORTA con
la instruccin:
bcf

PORTA, 0

Se obtendr la conduccin del transistor N y por tanto ir a 0 la lnea RA0. Si se coloca en 1 el bit
0 con la instruccin:
4

bsf

PORTA, 0

Se obtendr la conduccin del transistor P y por tanto ir a +5 volts la lnea RA0. Con esta
condicin ser siempre posible revisar el valor enviado sobre la lnea a travs del circuito de
entrada.
2. Estado de Salida de la lnea RA4
Se analizar el funcionamiento del estado de salida de la lnea RA4 que es diferente de las otras lneas
de I/O, en cuanto a la distribucin del pin en el PIC16C84 con el TOCKI, lo cual se analizar luego.
Se describe el esquema de bloques del estado de salida extrado del data sheet. La lgica de
conmutacin es substancialmente idntica al grupo de lneas RA0 a RA3 con ausencia de la compuerta
OR y del transistor P, o de todos los circuitos que permiten una conexin a positivo de la lnea RA4.
Esto significa en trminos prcticos que cuando una lnea RA4 est programada para salida, podr
asumir un nivel que depender del circuito externo, pues en realidad no est conectada al positivo y
s desconectada. Este tipo de circuito de salida se llama de colector abierto y es til para aplicaciones
en que es necesario compartir una misma ligacin con ms pines de salida, porque se tiene la necesidad
de colocar en alta impedancia una lnea de salida y pudiendo as reprogramarla como lnea de entrada.
Si se quiere asegurar que la lnea RA4 sea 1 se debe conectar externamente un resistor de PULL-UP, ya
sea un resistor conectado al positivo de alimentacin.
3.2. El Puerto B (PORTB)
3.2.1. Registros asociados al Puerto B
El puerto B es un puerto digital de 8 bits, todas sus patitas son bidireccionales y trabaja en forma
similar al puerto A. Tiene tres registros asociados: el registro de datos PORTB, el registro de
direccin de los datos TRISB y el registro OPTION_REG.
1. Registro PORTB (06H, 106H). Los ocho bits que contiene reflejan directamente el estado de
las ocho patitas del puerto B: RB0,...,RB7.
2. Registro TRISB (86H, 186H).- En forma similar a TRISA, al poner un 0 en un bit de TRISB
se configura la patita RB correspondiente como salida y al poner un 1 en un bit de TRISB se
configura la patita RB correspondiente como entrada.
3. Registro OPTION_REG (81H, 181H). El bit 7 de este registro, denominado RBPU es usado
para conectar/desconectar una resistencia pull-up conectada a cada patita RB. Poniendo un 0
en este bit todas las resistencias se conectan. Para desconectar las resistencias pull-up se
debe poner este bit en 1, tambin se desconectan automticamente cuando la patita
correspondiente es configurada como salida. Un Reset desconecta todas las resistencias.
REGISTRO OPTION u OPTION_REG (Direccin 81h, 181h)
A continuacin se indica el registro OPTION_REG, que puede ser ledo o escrito y que contiene varios
bits de control para configurar la asignacin del preescaler al TMR0 o al WDT, la interrupcin externa,
el TMR0 y las resistencias de pull-up del PORTB.
5

R/W-1
#RBPU
Bit 7
Bit 7:

R/W-1
INTED

R/W-1
T0CS

R/W-1
T0SE

R/W-1
PSA

R/W-1
PS2

R/W-1
PS1

R/W-1
PS0
Bit 0

#RBPU: Resistencia de Pull-up en el PORTB


1=Resistencia de Pull-up desactivada
0= Resistencia de Pull-up activada

Patitas RB4,...,RB7. Estas cuatro patitas del puerto B tienen la capacidad de generar una solicitud
de interrupcin a la CPU cuando estn configuradas como entradas. El estado de estas patitas es
comparado con el ltimo estado que tenan durante la ltima lectura a PORTB, guardado en un
latch. Los bits que indican que hay una diferencia entre estos valores por cada patita estn
conectados a una puerta OR cuya salida activa el bit RBIF del registro INTCON solicitando
con esto una interrupcin. Esta interrupcin es especialmente til para despertar al dispositivo de
su estado de SLEEP cuando alguna de las cuatro lineas es activada, por ejemplo, en respuesta a la
presin de una tecla.
Esta caracterstica de solicitud de interrupcin cuando se detecta un cambio junto con las
resistencias pull-up configurables para estas cuatro patitas, las hacen ideales para el manejo de
teclados en dispositivos porttiles que requieren dormirse durante largos ratos para economizar
bateras y despertarse cuando una tecla es presionada.
En las siguientes figuras se muestra el alambrado interno de las patitas del puerto B:

Patitas RB0,...RB3

Patitas RB4,...,RB7

3.2.2. Estado de salida de las lneas del puerto B


1. Estado de salida de las lneas RB0, RB1, RB2 y RB3
Para este grupo de lneas permanece sustancialmente invariante la lgica de conmutacin, estas
disponen de un circuito WEAK PULL-UP que se activa cuando la lnea es programada como entrada.
La entrada del evento, como se explico anteriormente, la lnea viene completamente desligada del
PIC. Un estado de la lnea depende entonces exclusivamente del circuito externo. S un circuito es del
tipo colector abierto o simplemente est constituido de un simple switche que cuando es presionado,
conecta a tierra la lnea de I/O, es necesario poner una resistencia del PULL-UP desde el positivo para
tomar cuando el switche se suelte y volver al nivel a una condicin lgica activa sobre una lnea de
entrada. El circuito de WEAK PULL-UP evita el uso del resistor PULL-UP e inhabilita que sea
activado sobre el bit RBPU (0 habilita, 1 deshabilita) del registro OPTION.
La figura anterior representa un esquema de salida extrado del data sheet del Microchip. La lnea RB0
sola presenta una caracterstica especial, cuando est configurada como lnea de entrada, puede generar,
en correspondencia un cambio de estado lgico, una interrupcin ya sea una interrupcin inmediata
del programa en ejecucin o una llamada a una subrutina especial denominada interrupt handler, lo
que se indicar ms adelante.
2. Estado de salida de las lneas RB4, RB5, RB6 Y RB7
Un circuito de conmutacin de este grupo es muy similar al grupo de RB0 a RB3. Esta lnea dispone
tambin de un circuito de weak pull-up. Tambin tienen con respecto a las lneas anteriores la ventaja
de poder revelar variaciones de estado sobre cualquier lnea y generar una interrupcin, la misma que
se hablar ms adelante.
La figura representa un esquema de salida extrado del data sheet del Microchip. Donde, el bit RBIF
corresponde al registro INTCON.
3.3. El puerto C (PORTC)
3.3.1. Registros asociados al puerto C
El puerto C consta de 8 lneas bidireccionales. Trabaja en forma similar a los dos puertos
anteriores y tiene asociados los registros:
1. Registro PORTC (07H).- Es el registro de datos cuyos 8 bits RC7,RC6,...,RC0 reflejan
directamente el valor lgico de las lneas fsicas del puerto C.
2. Registro TRISC (87H).- Registro de control de direccin de las lneas del puerto C.
Poniendo un 1 en un bit del registro TRISC se configura la lnea correspondiente como entrada y
poniendo un 0 se configura la lnea correspondiente como salida.
Las lneas del puerto C se encuentran multiplexadas con varias lneas controladas por otros
perifricos, cuando se habilita la lnea del perifrico respectivo puede ser ignorada la configuracin
de TRISC, de hecho, algunos perifricos configuran la lnea como salida mientras que otros la
configuran como entrada.
7

Cada entrada del puerto C posee un buffer con disparador trigger. Adems, cuando se selecciona la
funcin I2C, las patitas PORTC<4,3> pueden ser configuradas con niveles I2C o con niveles SMBus
mediante el bit CKE del registro SSPSTAT<6>, como se muestra en las figuras siguientes.
En las siguientes figuras se muestra el alambrado interno de las patitas del puerto B.

Patitas 7,6,5,2,1 y 0 del puerto C

Patitas 4 y 3 del puerto C

3.3.2. Perifricos que estn multiplexados con las lneas del puerto C
En la siguiente tabla se resumen las lneas del puerto C y las de los perifricos que estn
multiplexados con ellas.
Nombre
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RC2/CCP1
RC3/SCK/SCL
RC4/SDI/SDA
RC5/SDO
RC6/TX/CK
RC7/RX/DT

Funcin multiplexada
Salida oscilatoria del Timer1/reloj de entrada del Timer 1
Entrada oscilatoria del Timer1/entrada de captura2 o salida de
comparacin2 o salida PWM2
Entrada de captura1 o salida de comparacin1 o salida PWM1
Reloj para los modos de comunicacin serie sncrona SPI e I2C
Dato de entrada (en modo SPI)/ Dato de entrada-salida (modo I2C)
Dato de salida (en modo SPI)
Lnea de transmisin asncrona de la USART/reloj sncrono
Lnea de recepcin asncrona de la USART/dato sncrono

3.4. Los Puertos D y E


Estos dos puertos no se encuentran disponibles en los circuitos PIC16F873 y PIC16F876.
El puerto D es un puerto de 8 lneas configurables como entradas o salidas mediante el registro
TRISD (88H) y cuyas lneas pueden ser accedidas mediante el registro PORTD (08H). Cuando se
configuran como entradas stas poseen un disparador Schmitt trigger.
El Puerto D puede configurarse para trabajar simultneamente con sus 8 bits como un puerto
esclavo (Parallel Slave Port) de comunicacin paralela bidireccional con lneas de protocolo
proporcionadas por las tres lneas del Puerto E, para ello se deber activar el bit PSPMODE
(TRISE<4>).
El Puerto E slo posee 3 lneas configurables como entradas o salidas mediante el los 3 bits menos
significativos del registro TRISE (89H). Sus lneas pueden ser accedidas mediante los 3 bits menos
significativos del registro PORTE (09H). Las lneas del puerto E estn compartidas con el
convertidor analgico/digital, por ello, antes de usarlas debern ser configuradas como
entradas/salidas digitales o analgicas, segn se desee en forma similar a como se hizo con el
puerto A, usando el registro de configuracin ADCON1 (9FH).
3.5. Ejemplo 1
Entradas digitales. En este ejemplo se configura la patita RA5 del puerto A como salida conectada
a un LED, el cual se controla de acuerdo al estado de las patitas RA0 y RA1 configuradas como
entradas.
Hardware necesario. Como prcticamente en todos los programas para PIC, si no se conecta el
hardware adecuado no se puede ver ningn efecto al ejecutar el programa. En la siguiente
figura se muestra la conexin de los dos botones y el LED necesarios para probar el programa,
adems claro est de la circuitera de reloj necesaria.

En este programa el rebote generado por los switches no es problema, porque funciona correctamente
haya o no haya rebote.

1. Diagrama de Flujo:
INICIO

RA0=1

NO

SI
RA50

NO

RA1=1
SI
RA51

2. Cdigo en Assembler:
;* Este programa Enciende un LED conectado a RA5 cuando se presiona un botn
;* conectado a RA1 y lo apaga cuando se presiona un botn conectado a RA0
;*****************************************************************************
include "p16f877.inc"
org 0x0000

;Inicia en el vector de reset

;Inicializacin del puerto A:


CLRF STATUS
;Selecciona Banco 0
CLRF PORTA
;Inicializa latches de datos de PORTA
BSF
STATUS,RP0 ;Selecciona Banco 1
MOVLW 0x06
;Configura todas las patitas de A
MOVWF ADCON1
;como digitales
MOVLW 0x1F
;configura todas las patitas de A como entradas
MOVWF TRISA
;y RA5 como salida
;Una vez inicializado el puerto, se procede leer las patitas RA0 y RA1
BCF STATUS,RP0
;regresa al banco 0
chRA0 BTFSS PORTA,0
;checa si RA0=1
GOTO chRA1
Apaga BCF PORTA,5
chRA1 BTFSS PORTA,1
GOTO chRA0
Prend BSF PORTA,5
GOTO chRA0

;si RA=0 salta a checar RA1


;si RA0=1 apaga el LED
;checa si RA1=1
;si RA1=0 salta a checar RA0
;si RA1=1 enciende el LED

10

end

3.6. El efecto rebote y su eliminacin


En el momento de presionar un botn pulsador o cualquier conmutador electromecnico es inevitable
que se produzca un pequeo arco elctrico durante el breve instante en que las placas del contacto
se aproximan o se alejan de sus puntos de conexin, ya que las distancias microscpicas entre los
puntos a diferente potencial son suficientes para romper por un instante la resistividad del aire.
Este fenmeno se conoce como rebote (bounce) y se ilustra en la siguiente figura:

3.6.1. Duracin del rebote


La experiencia emprica indica que el periodo transitorio de un rebote depende entre otros factores,
de la calidad de los switches y de la rapidez de su accionamiento, pero a lo ms puede durar unos
20 milisegundos, En la siguiente figura se muestra un rebote real en los contactos de un
relevador capturado en la pantalla de un osciloscopio digital Fluke 123. (Obsrvese que el rebote
mostrado dur solamente 3 milisegundos).

11

3.6.2. Limpiado del rebote (debouncing)


El rebote generado por un switch no siempre es un problema, porque en algunas aplicaciones
puede funcionar correctamente haya o no haya rebote (como en el ejemplo 1). Sin embargo, Qu
pasara si se desea controlar el encendido y apagado del LED con un solo botn?. En este caso
s se debe contemplar el limpiado del rebote. (Siempre que a una sola tecla se le asigna dos o ms
funciones diferentes en un programa se deben considerar el efecto del rebote).
El rebote de un switch puede durar a lo ms unos 20 milisegundos, por lo que para el limpiado del
rebote se debe realizar una subrutina con una pausa de 20 mseg, la cual se desarrolla a continuacin.
I. Subrutina de pausa con un ciclo
La subrutina pau20ms simplemente realiza una pausa de 20 milisegundos. Se tiene dos formas de
implementacin de esta subrutina (suponiendo un reloj de 100 Khz):
a. Usando memoria de datos
1. Diagrama de Flujo:

2. Cdigo en Assembler:
;* Subrutina de pausa que dura 20 milisegundos (usando memoria de datos)
;* (Supone un reloj de 100 Khz)
;**************************************************************************
;Define constantes
N
EQU 0xA5
cont
EQU 0x20
; inicia subrutina
pau20ms MOVLW N

;Carga dato que controla la duracin, W=N


12

rep
esc

MOVWF cont
DECFSZ cont,1
GOTO rep
RETURN

;inicializa contador con el dato, cont=N


;Decrementa contador y escapa si cero, cont=cont-1
;si no es cero, repite
;regresa de esta subrutina

b. Sin usar memoria de datos


;* Subrutina de pausa que dura 20 milisegundos (sin usar memoria de datos)
;* (Supone un reloj de 100 Khz)
;**************************************************************************
;Define dato que controla la duracin
N
EQU ???
;inicia subrutina
pau20ms MOVLW N
rep
ADDLW 0xFF
BTFSS STATUS,2
GOTO rep
esc
RETURN

;Carga dato que controla la duracin


;Le suma 1
;Si es cero escapa
;si no es cero, repite
;regresa de esta subrutina

Clculo del valor de N


Para lograr que la duracin de la subrutina presentada sea de 20 milisegundos es necesario
elegir adecuadamente el valor de la constante N. Para ello se ejemplifica el clculo en la primera de
las dos versiones (a): A continuacin se repite el cdigo fuente de la subrutina incluyendo entre
parntesis el nmero de ciclos que dura cada instruccin:
pau20ms MOVLW N
MOVWF cont
rep
DECFSZ cont,1
GOTO rep
esc
RETURN

;(1)
;(1)
;(1 si no escapa, 2 si escapa)
;(2)
;(2)

De manera que el nmero de ciclos de instruccin Tsub consumidos por la subrutina,


incluyendo los 2 ciclos de la llamada (CALL) sern:
Tsub = [2+1+1+(N-1)*(1+2)+2+2] ciclos
Lo cual se puede expresar en segundos como:
Tsub = (3N+5) Tcy
Donde Tcy es la duracin en segundos de un ciclo de instruccin. Despejando N tenemos:
N = (Tsub/Tcy 5)/3
Por ejemplo,
suponiendo Tsub = 20 mseg y que se est usando un reloj de 100 Khz y (fcy = fosc/4 =
(100x103 Hz)/4 =25x103 Hz entonces Tcy = 1/(25x103) = 40x10-6 seg = 40 seg):
N = (20 mseg /40seg 5)/3
N = 165 = A5H
Observacin. La mxima duracin que se puede lograr con esta subrutina y con la frecuencia del
13

reloj de 100 Khz supuesta (Tcy = 40 seg), es cuando el ciclo se ejecute 256 veces, es decir con
un valor N=256, lo cual en el programa se logra con el valor inicial N=0:
Tsub = (3N+5) Tcy
Tsub = (3 x 256 + 5) x 40 x 10-6seg
Tsub = 30.92 mseg
As, si la frecuencia del reloj es mayor, por ejemplo, en el modo de oscilador interno se
tienen 4 Mhz, que da un Tcy=1seg, esta subrutina no podr proporcionar nunca los 20 mseg,
por lo que habr que realizar una pausa ms larga anidando dos ciclos.
II. Subrutina de pausa con dos ciclos anidados
La pausa pau20ms es demasiado corta, de manera que para frecuencias altas de reloj no puede
alcanzar ni siquiera los 20 mseg. A continuacin se muestra una pausa que puede dar tiempos mucho
ms largos usando ciclos anidados. A continuacin se va realizar una subrutina d20ms de 20 mseg
con un reloj de 4 Mhz:
1. Diagrama de Flujo:
d20ms

WN
cont1W

WM
cont2W

cont2cont2-1

NO

Z=1

SI
cont1cont1-1

NO

Z=1
SI

FIN

14

2. Cdigo en Assembler:
;* Subrutina de pausa para frecuencias medias
;* (Adecuada para un reloj de 4 Mhz)
;**************************************************************************
;Define constantes para 20 milisegundos
N
EQU 0x1A
M
EQU 0x0
cont1 EQU 0x20
cont2 EQU 0x21
;inicia subrutina
d20ms MOVLW N
MOVWF cont1
rep1 MOVLW M
MOVWF cont2
rep2 DECFSZ cont2,1
GOTO rep2
DECFSZ cont1,1
GOTO rep1
esc
RETURN

;(1) Carga dato N


;(1) inicializa contador1 ciclo externo
;(1) Carga dato M
;(1) inicializa contador2 ciclo interno
;(1,2)Decrementa contador2 y escapa si cero
;(2) si no es cero, repite ciclo interno
;(1,2)Decrementa contador1 y escapa si cero
;(2) si no es cero repite ciclo externo
;(2) regresa de esta subrutina

La duracin de esta subrutina en ciclos de reloj ser


Tsub = 2+1+1+N*[1+1+(M-1)*(1+2)+2+1+2]+1-2+2+2 ciclos
Lo cual se puede simplificar como sigue:
Tsub = [N*(3M+4)+7] Tcy
La mxima duracin de esta subrutina se obtiene para N=M=256, lo cual en el programa se logra con
los valores iniciales de N=M=0; entonces Tsub mximo = 197639 Tcy. Para una frecuencia de 4
Mhz (Tcy = 1 seg), entonces Tsub mximo =0,197639 seg.
Si deseamos Tsub = 20 mseg, haciendo M=256, despejando N,
N = (Tsub/Tcy 7)/(3M+4)
Sustituyendo valores obtenemos N= 25.89 ~ 1Ah. (debido a la aproximacin la subrutina
realmente dura 20.08 mseg.
Observacin. Hasta aqu se estn realizando pausas de duracin controlada por software, sin
embargo, lo ms adecuado para controlar tiempo de manera ms exacta es usar los timers que se
vern ms adelante.
III. Subrutina de pausa con ciclos anidados para tiempos largos
Para realizar la pausa de un segundo, d1seg, se puede hacer uso de la subrutina d20ms con su
mxima duracin Tsub = 0,197639 seg, teniendo los valores N=M=256 (con los valores iniciales
de N=M=0 en el programa). Para ello se implementa un tercer ciclo externo que repita esta pausa p
veces.
15

1. Diagrama de Flujo:
d1seg

Wp
cont3W

d20ms

cont3cont3-1

NO

Z=1
SI

FIN

2. Cdigo en Assembler:
;* Subrutina de pausa de 1 segundo
;**********************************************************************
EQU 0x05
p
cont3 EQU 0x22
d1seg MOVLW p
MOVWF cont3
ciclo CALL d20ms
DECFSZ cont3,1
GOTO ciclo
RETURN

;(1)carga duracin del ciclo


;(1)inicializa contador3
;(197639)pausa de 0.197639 seg
;(1,2)Decrementa y escapa si cero
;(2)si no es cero repite
;(2)si es cero retorna

La duracin de esta subrutina incluyendo la llamada ser


Tsub = [2+1+1+(p)*(197639+1+2)+1-2+2] ciclos
Es decir,
Tsub = [197642*p+5] Tcy
La mxima duracin de esta subrutina (para p =256), suponiendo un reloj de 4 Mhz (Tcy = 1
seg)), se tiene un Tsub mximo = 50,596357 segundos. Sin embargo, si deseamos un
Tsub=1seg. Obtenemos, despejando
p = (Tsub/Tcy 5)/197642 = 5,059628 ~ 5
16

3.7. Ejemplo 2
En este ejemplo se usa slo el botn conectado a la patita RA0 para controlar el encendido y
apagado del LED en la patita RA1, y se incluye el limpiado del rebote con un reloj de 4Mhz.
Hardware necesario. En la siguiente figura se muestra la conexin del botn y el LED necesarios
para probar el programa.

1. Diagrama de Flujo:
Diagrama de flujo del Programa Principal:

17

El diagrama de flujo de la Subrutina d20ms se realiza en el subtema Limpiado del rebote.


2. Cdigo en Assembler:
;*Este programa Enciende un LED conectado a RA5 cuando se presiona un botn
;*conectado a RA0 y lo apaga cuando se presiona nuevamente el mismo botn y a s
;*sucesivamente.
;**************************************************************************
include "p16f877.inc"
;Define constantes
N
EQU 0x1A
M
EQU 0x0
cont1 EQU 0x20
cont2 EQU 0x21
org 0x0000

;Inicia en el vector de reset

;Inicializacin del puerto A:


CLRF STATUS
;Selecciona Banco 0
CLRF PORTA
;Inicializa latches de datos de PORTA
BSF
STATUS,RP0 ;Selecciona Banco 1
MOVLW 0x06
;Configura todas las patitas de A
MOVWF ADCON1
;como digitales
MOVLW 0x1F
;configura todas las patitas de A como entradas
MOVWF TRISA
;y RA5 como salida
BCF STATUS,RP0
;regresa al banco 0
checa BTFSS PORTA,0
GOTO checa
CALL d20ms
chec1 BTFSS PORTA,0
GOTO chec1
MOVLW 0x20
XORWF PORTA,1
GOTO checa

;checa si RA0=1
;si RA=0 checa de nuevo
;si RA0=1 espera 20 miliseg. A que pase el rebote
;checa nuevamente si RA0=1
;si RA1=0 falsa alarma, vuelve a checar
;si RA0=1 seal vlida; carga mscara en W
;conmuta estado del LED
;repite

;* Subrutina de pausa para frecuencias medias


;* (Adecuada para un reloj de 4 Mhz)
;**************************************************************************
;Define constantes para 20 milisegundos
;inicia subrutina
d20ms MOVLW N
;(1) Carga dato N
MOVWF cont1
;(1) inicializa contador1 ciclo externo
rep1 MOVLW M
;(1) Carga dato M
MOVWF cont2
;(1) inicializa contador2 ciclo interno
rep2 DECFSZ cont2,1
;(1,2)Decrementa contador2 y escapa si cero
GOTO rep2
;(2) si no es cero, repite ciclo interno
DECFSZ cont1,1
;(1,2)Decrementa contador1 y escapa si cero
GOTO rep1
;(2) si no es cero repite ciclo externo
Esc
RETURN
;(2) regresa de esta subrutina
end

3.8. Ejemplo 3
Luces secuenciales. En este ejemplo se realiza el encendido secuencial de 8 LEDs conectados a
RB0,...,RB7, es decir, se enciende RB0 durante un segundo, luego RB1 y as sucesivamente hasta
18

llegar a RB7 para recomenzar despus con RB0. (en un segundo dado slo un LED est prendido).
Hardware necesario. Slo se requieren los ocho LEDs conectados a las patitas RBP0,...,RBP7,
como se muestra en la siguiente figura.

1. Diagrama de Flujo:
Diagrama de flujo del Programa Principal:

19

INICIO

N0x00
M0x00
p0x05
C0
PORTB0
RB01

d1seg

PORTBrota izq PORTB

C=0

SI

NO
RB01

C0

Los diagramas de flujo de la Subrutinas d1seg y d20ms se realiza en el subtema Limpiado del
rebote.
2. Cdigo en Assembler:
;* Este programa Enciende en secuencia (uno a la vez) 8 LEDs conectados
;* a las patitas del puerto B
;**********************************************************************
;
Include "p16f877.inc"
;Define constantes Para 197 milisegundos
N
EQU 0x0
M
EQU 0x0
cont1 EQU 0x20
cont2 EQU 0x21
; Define constantes para pausa de 1 segundo
p
EQU 0x05
cont3 EQU 0x22

20

org 0x0000

;Inicia en el vector de reset

;Inicializacin del puerto B:


CLRF STATUS
;Selecciona Banco 0
CLRF PORTB
;Inicializa latches de datos de PORTB
BSF STATUS,RP0
;Selecciona Banco 1
CLRF TRISB
;Configura todas las patitas de B como salidas
;Una vez inicializado el puerto, se procede a controlar los LEDs
CLRF STATUS
;regresa al banco 0 y limpia acarreo
CLRF PORTB
;Apaga todos los LEDs
BSF PORTB,0
;enciende el LED RB0
ciclo CALL d1seg
;pausa de un segundo
RLF PORTB,1
;Recorre posicin encendida a la izquierda
BTFSC STATUS,C
BSF PORTB,0
BCF STATUS,C
GOTO ciclo
;repite
;* Subrutina de pausa para tiempos largos
;* (Adecuada para un reloj de 4 Mhz)
;**************************************************************************
;inicia subrutina
d20ms MOVLW N
;(1) Carga dato N
MOVWF cont1
;(1) inicializa contador1 ciclo externo
rep1 MOVLW M
;(1) Carga dato M
MOVWF cont2
;(1) inicializa contador2 ciclo interno
rep2 DECFSZ cont2,1
;(1,2)Decrementa contador2 y escapa si cero
GOTO rep2
;(2) si no es cero, repite ciclo interno
DECFSZ cont1,1
;(1,2)Decrementa contador1 y escapa si cero
GOTO rep1
;(2) si no es cero repite ciclo externo
esc
RETURN
;(2) regresa de esta subrutina
;* Subrutina de pausa de 1 segundo
;**********************************************************************
;inicia rutina
d1seg MOVLW p
;(1)carga duracin del ciclo
MOVWF cont3
;(1)inicializa contador3
ciclo1 CALL d20ms
;(196868)pausa de 0.197639 seg
DECFSZ cont3,1
;(1,2)Decrementa y escapa si cero
GOTO ciclo1
;(2)si no es cero repite
RETURN
;(2)si es cero retorna
end

3.9. Ejemplo 4
Conexin de un teclado matricial
Una de las funciones ms comunes de un microcontrolador es la aceptacin de datos numricos o
alfanumricos suministrados por un operador mediante un teclado.
La mayora de los teclados estn organizados en forma matricial como un conjunto de switches en
las intersecciones de varios renglones y columnas conductoras como se muestra en la siguiente
figura que ejemplifica un teclado de tipo telefnico.

21

En la figura tambin se ilustra una conexin tpica con tres lneas de entrada del puerto B que
controlan las columnas y cuatro lneas de salida del mismo puerto que recogen la informacin de
los renglones.
Observacin. Es recomendable colocar un diodo de proteccin en cada lnea de salida del
puerto para evitar que al activar ms de una columna a la vez se produzca un corto circuito.
Procedimiento de deteccin de teclas y codificacin. Para la deteccin y asignacin de
cdigo segn la tecla presionada se procede como sigue:
1. Deteccin. Se ponen en bajo todos los filas (cuidando que haya diodos de proteccin) y se
leen las columnas.
2. Si hay alguna columna activa se limpia el rebote, si es tecla vlida se pasa al paso 3, si
no es tecla vlida se asigna un cdigo de ninguna tecla presionada.
3. Codificacin. El puerto activa una fila a la vez colocando un cero lgico en la lnea
correspondiente a la fila a activar.
4. Por cada fila activa se lee la informacin de columnas y dependiendo de la fila y la
columna activada (en bajo) se asigna el cdigo a la tecla de la interseccin.
1. Diagrama de Flujo:
Diagrama de flujo del Programa Principal:

22

INICIO

N0x1A
M0x00

initB

W0xFF
masqW

detect

masqW-masq

NO
Z=1
SI
codif

PORTCW

Diagrama de flujo de la Subrutina initB:

23

Diagrama de flujo de la Subrutina detec:


INICIO

PORTB0

NO

NO

RB7=1

RB7=1

SI

RB6=1

SI

NO

RB6=1

SI

RB5=1

SI

NO

RB5=1

SI

RB4=1

NO

NO

SI

NO

RB4=1

SI

NO

SI

W0x00

d20ms

W0x00

W0xFF

FIN

FIN

FIN

Diagrama de flujo de la Subrutina codif:

24

El diagrama de flujo de la Subrutina d20ms se realiza en el subtema Limpiado del rebote.


2. Cdigo en Assembler:
;* Ingreso de datos numricos hexadecimales mediante un teclado de
;* tipo telefnico, controlando las 3 columnas con las salidas RB1,RB2 y RB3
;* y las 4 filas con las entradas RB4,RB5,RB6 y RB7
;* con resistencias pull-up internas para evitar resistencias externas.
;* Luego mostrar el dato ingresado en el puerto C.
;*********************************************************************
include "p16f877.inc"
;Define constantes para 20 milisegundos
N
EQU 0x1A
M
EQU 0x0
cont1 EQU 0x20
cont2 EQU 0x21
;Define constante para mascara 0xFF (tecla pulsada)
masq equ 0x32
org 0x0000
;Configura el puerto C como salida

25

CLRF STATUS
CLRF PORTC
BSF STATUS,RP0
MOVLW 0x00
MOVWF TRISC
BCF STATUS,RP0
;Programa principal
CALL initB
repite MOVLW 0xFF
MOVWF masq
CALL detec
SUBWF masq,1
BTFSS STATUS,Z
GOTO repite
CALL codif
MOVWF PORTC
GOTO repite

;Selecciona Banco 0
;Inicializa latches de datos de PORTC
;Selecciona Banco 1
;configura puerto C como salidas
;
;regresa al Banco 0

;Llama a la subtutina initB


;Almacena en W la mascara 0xFF
;Almacena en masq la mascara 0xFF
;Llama a la subtutina detect
;
;Resultado en W=0
;Repite el proceso
;Llama a la subtutina codif
;Mueve la tecla presionada al puerto C
;Repite el proceso

;Esta subrutina realiza la Inicializacin del puerto B:


;*********************************************************************
initB CLRF STATUS
CLRF PORTB
BSF STATUS,RP0
MOVLW 0xF0
MOVWF TRISB
BCF OPTION_REG,7
BCF STATUS,RP0
RETURN

;Selecciona Banco 0
;Inicializa latches de datos de PORTB
;Selecciona Banco 1
;configura RB7,...,RB4 como entradas
;y RB3,RB2,RB1 como salidas
;Conecta todas las resistencias Pull-Up
;regresa al Banco 0

;Esta subrutina realiza la Deteccin de tecla presionada: regresa W=0 si no hay tecla
;presionada y W=0xFF si hay alguna tecla presionada
;*********************************************************************
detec CLRF PORTB
BTFSS PORTB,7
GOTO rebo
BTFSS PORTB,6
GOTO rebo
BTFSS PORTB,5
GOTO rebo
BTFSS PORTB,4
GOTO rebo
RETLW 0x0

;activa las cuatro filas


;lee rengln 1,2,3
;si tecla presionada limpia rebote
;lee rengln 4,5,6
;si tecla presionada limpia rebote
;lee rengln 7,8,9
;si tecla presionada limpia rebote
;lee rengln *,0,#
;si tecla presionada limpia rebote
;no hubo tecla presionada retorna con w=0

rebo

;pausa de 20 milisegundos
;lee rengln 1,2,3
;tecla presionada, retorna con
;lee rengln 4,5,6
;tecla presionada, retorna con
;lee rengln 7,8,9
;tecla presionada, retorna con
;lee rengln *,0,#
;tecla presionada, retorna con
;falsa alarma retorna con w=0

CALL d20ms
BTFSS PORTB,7
RETLW 0xFF
BTFSS PORTB,6
RETLW 0xFF
BTFSS PORTB,5
RETLW 0xFF
BTFSS PORTB,4
RETLW 0xFF
RETLW 0x0

w=0xFF
w=0xFF
w=0xFF
w=0xFF

;* Esta subrutina realiza la codificacin del teclado tipo telefnico


;* retornando en W el cdigo ASCII de la tecla presionada,
;* regresa W=0 si no hubo tecla presionada

26

;*********************************************************************
; Se hace un barrido por columnas
codif ; Primera columna
MOVLW 0xF7
;Activa la primera columna
MOVWF PORTB
;y activa la columna 1,4,7,*
BTFSS PORTB,7
;Es la tecla 1?
RETLW '1'
;retorna cdigo del 1
BTFSS PORTB,6
;Es la tecla 4?
RETLW '4'
;retorna cdigo del 4
BTFSS PORTB,5
;Es la tecla 7?
RETLW '7'
;retorna cdigo del 7
BTFSS PORTB,4
;Es la tecla *?
RETLW '*'
;Retorna cdigo del *
; Segunda columna
MOVLW 0xFB
MOVWF PORTB
BTFSS PORTB,7
RETLW '2'
BTFSS PORTB,6
RETLW '5'
BTFSS PORTB,5
RETLW '8'
BTFSS PORTB,4
RETLW '0'

;Activa la segunda columna


;y activa la columna 2,5,8,0
;Es la tecla 2?
;retorna cdigo del 2
;Es la tecla 5?
;retorna cdigo del 5
;Es la tecla 8?
;retorna cdigo del 8
;Es la tecla 0?
;Retorna cdigo del 0

; Tercera columna
MOVLW 0xFD
MOVWF PORTB
BTFSS PORTB,7
RETLW '3'
BTFSS PORTB,6
RETLW '6'
BTFSS PORTB,5
RETLW '9'
BTFSS PORTB,4
RETLW '#'
RETLW 0x00

;Activa la tercera columna


;y activa la columna 3,6,9,#
;Es la tecla 3?
;retorna cdigo del 3
;Es la tecla 6?
;retorna cdigo del 6
;Es la tecla 9?
;retorna cdigo del 9
;Es la tecla #?
;Retorna cdigo del #
;falsa alarma, no hay tecla presionada

;* Subrutina de pausa para frecuencias medias


;* (Adecuada para un reloj de 4 Mhz)
;**************************************************************************
;inicia subrutina
d20ms MOVLW N
MOVWF cont1
rep1 MOVLW M
MOVWF cont2
rep2 DECFSZ cont2,1
GOTO rep2
DECFSZ cont1,1
GOTO rep1
esc
RETURN

;(1) Carga dato N


;(1) inicializa contador1 ciclo externo
;(1) Carga dato M
;(1) inicializa contador2 ciclo interno
;(1,2)Decrementa contador2 y escapa si cero
;(2) si no es cero, repite ciclo interno
;(1,2)Decrementa contador1 y escapa si cero
;(2) si no es cero repite ciclo externo
;(2) regresa de esta subrutina

end

Observacin: La repeticin de cdigo se puede evitar utilizando direccionamiento indirecto dentro


de un ciclo, sin embargo, esto slo representa un ahorro de cdigo y de memoria para teclados de
mayor complejidad.
27

3.10. Ejemplo 5
Manejo de un Display de 7 segmentos
Un display de siete segmentos es un arreglo de 7 LEDs conectados como se muestra en la siguiente
figura:

Para este ejemplo se supone un display de nodo comn conectado al puerto C como se muestra a
continuacin:

El programa visualiza dgitos numricos hexadecimales en el display, de acuerdo a la codificacin


mostrada en la siguiente tabla.

Dato
0
1
2
3
4
5
6
7
8
9

0
1
0
0
1
0
0
0
0
0

0
0
0
0
0
1
1
0
0
0

c
0
0
1
0
0
0
0
0
0
0

d
0
1
0
0
1
0
0
1
0
0

e
0
1
0
1
1
1
0
1
0
1

f
0
1
1
1
0
0
0
1
0
0

g
1
1
0
0
0
0
0
1
0
0

Cdigo
01
4F
12
06
4C
24
20
0F
00
04

28

A
b
C
d
E
F

0
1
0
1
0
0

0
1
1
0
1
1

0
0
1
0
1
1

1
0
0
0
0
1

0
0
0
0
0
0

0
0
0
1
0
0

0
0
1
0
0
0

08
60
31
42
30
38

1. Diagrama de Flujo:
Diagrama de flujo del Programa Principal:
INICIO

N0x1A
M0x00
PORTB0x01
cont0

RC7=1

NO

SI
d20ms

RC7=1

NO

SI
contcont+1

codigo

POTCW

RC7=0

NO

SI

29

El diagrama de flujo de la Subrutina d20ms se presenta en el subtema Limpiado del rebote


Diagrama de flujo de la Subrutina cdigo:

2. Cdigo en Assembler:
;* Este programa despliega un dgito hexadecimal en un display de nodo
;* comn conectado al puerto C. El dgito se incrementa en 1 cada vez que
;* se presiona un botn conectado al MSB del mismo puerto C
;************************************************************************
Include "p16f877.inc"
;Define constantes para 20 milisegundos
N
EQU 0x1A
M
EQU 0x00
cont1 EQU 0x20
cont2 EQU 0x21
cont

equ 0x22

inic

BSF STATUS,RP0
MOVLW 0x80
MOVWF TRISC
BCF STATUS,RP0

;banco 1
;Todos los bits del puerto C como salidas
;y el MSB como entrada
;regresa al Banco 0

MOVLW 0x01

30

MOVWF PORTC
CLRF cont
tecla BTFSS PORTC,7
GOTO tecla
CALL d20ms
BTFSS PORTC,7
GOTO tecla
INCF cont,1
CALL codigo
MOVWF PORTC
Suelta BTFSC PORTC,7
GOTO suelta
GOTO tecla

;Despliega un cero. Codificado


;Inicializa contador en cero
;checa botn si se ha presionado
;Si no se ha presionado espera
;pausa de 20 milisegundos
;checa nuevamente el botn si esta presionado
;tecla falsa, espera de nuevo
;tecla vlida, incrementa contador
;obtiene cdigo para desplegar el contador
;despliega contador
;checa de nuevo el botn si se ha soltado
;si sigue presionado espera
;si ya se solt espera nueva presin.

;* Subrutina para determinar el codigo hexadecimal


;*
;**************************************************************************
codigo
MOVLW
ANDWF
ADDWF
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW

0x0F
cont,0
PCL,1
0x01
0x4F
0x12
0x06
0x4C
0x24
0x20
0x0F
0x00
0x04
0x08
0x60
0x31
0x42
0x30
0x38

;carga mscara
;enmascara el contador y lo deja en W
;Salta W instrucciones adelante
;cdigo del 0
;cdigo del 1
;cdigo del 2
;cdigo del 3
;cdigo del 4
;cdigo del 5
;cdigo del 6
;cdigo del 7
;cdigo del 8
;cdigo del 9
;cdigo de la A
;cdigo de la b
;cdigo de la C
;cdigo de la d
;cdigo de la E
;cdigo de la F

;* Subrutina de pausa para tiempos largos


;* (Adecuada para un reloj de 4 Mhz)
;**************************************************************************
;inicia subrutina
d20ms MOVLW N
MOVWF cont1
rep1 MOVLW M
MOVWF cont2
rep2 DECFSZ cont2,1
GOTO rep2
DECFSZ cont1,1
GOTO rep1
esc
RETURN

;(1) Carga dato N


;(1) inicializa contador1 ciclo externo
;(1) Carga dato M
;(1) inicializa contador2 ciclo interno
;(1,2)Decrementa contador2 y escapa si cero
;(2) si no es cero, repite ciclo interno
;(1,2)Decrementa contador1 y escapa si cero
;(2) si no es cero repite ciclo externo
;(2) regresa de esta subrutina

end

Observacin: Una manera ms cmoda de escribir la lista de instrucciones RETLW al final del
programa anterior puede lograrse usando la directiva DT (Define Table) del ensamblador, la cual
nos permite definir una tabla de datos que ser sustituida por una lista de instrucciones RETLW; as,
31

la lista anterior puede quedar como sigue:


DT 0x01,0x4F,0x12,0x06,0x4C,0x24,0x3F,0x0F
DT 0x00,0x04,0x08,0x60,0x31,0x42,0x30,0x38

3.11. Ejemplo 6
Gestin de un LCD
Se realizar la interface del PIC16F877 con un LCD (Liquid Crystal Display) compuesto por dos lneas
de 16 caracteres cada una. Los LCD ms comunes, disponen de una interface ideada por Hitachi y
adoptada como estndar por otros fabricantes. Esta interface hace que el LCD pueda ser conectado al
micro a travs de un bus de 4 u 8 lneas ms tres lneas de control y las de alimentacin.
En la tabla siguiente estn descriptas las funciones de cada lnea disponible del LCD. Las descripciones
en negrita, indican las lneas efectivamente utilizadas en la aplicacin que se realizar.
Pin

Nombre

GND

Funcin
Ground. Conectar al negativo de alimentacin

VDD

Power Supply. Conectar al positivo de alimentacin (+5 v)

LCD

Liquid Crystal Driving Voltage. En este pin debe ser aplicada una tensin variable entre 0 y 5V para
regular el contraste

RS

Register Select. Este pin es una lnea de control con la que se le indica al display si se est enviando en el
bus de datos un comando (RS=0) o un dato (RS=1)

R/W

Read, Write. Esta es otra lnea de control con la que se indica al display si se est enviando un dato (R/W=0) o
leyendo un dato del display (R/W=1)

Enable. Esta lnea de control sirve para habilitar el display para que reciba un dato o instrucciones a
travs del bus (E=1)

DB0

Data Bus Line 0 - Sobre estas lneas viajan los datos entre el micro y el display

DB1

Data Bus Line 1

DB2

Data Bus Line 2

10

DB3

Data Bus Line 3

11

DB4

Data Bus Line 4

12

DB5

Data Bus Line 5

13

DB6

Data Bus Line 6

14

DB7

Data Bus Line 7

Para reducir al mximo las conexiones entre el micro y el LCD, se usar la modalidad de interconexin
de datos a 4 bit, usando slo las lneas DB4, DB5, DB6, DB7. Las lneas DB0, DB1, DB2 y DB3 no
sern usadas y sern conectadas a masa.
Tampoco la lnea R/W ser utilizada por lo que ser puesta a masa. De este modo, quedar
seleccionado el modo escritura. En la prctica, slo se podr enviar datos al LCD pero no recibirlos.
I. La lnea Register Select (RS) y Enable (E) del LCD
Para poder visualizar una frase en el LCD, el PIC debe enviar una serie de comandos a travs del bus
de datos (lneas DB4 a DB7). Para hacer esto, son utilizadas dos lneas de control con las que se
comunica al LCD la operacin de transferencia que realizar el bus.
32

Las dos lneas de control son Register Select (pin 4) y Enable (pin 6) del LCD, las cuales se describen
a continuacin:

Con la lnea Register Select, el PIC indica al display que el dato presente en el bus es un comando
( RS=0 ) o un dato a ser visualizado ( RS=1 ). A travs de los comandos, el PIC puede indicar al
LCD el tipo de operacin a realizar, como por ejemplo "limpiar pantalla". Con los datos, el PIC
puede enviar directamente los caracteres ASCII a ser visualizados.
La lnea Enable habilita al LCD para leer el comando o el dato enviado en el bus por el PIC. El PIC
debe ocuparse de haber enviado en el bus de datos el comando o el dato correcto antes de poner a 1
la seal Enable.

II. Mutiplexado sobre el bus de datos


Puesto que los comandos son datos de 8 bits Cmo es posible enviarlos al LCD si el bus de datos
dispone slo de 4 lneas?
En la prctica se usa la operacin de multiplexado, es decir, cada bit es descompuesto en dos grupos de
4 bit y transmitidos por el bus de datos en secuencia. Son enviados primero los 4 bit menos
significativos seguidos de los 4 bit ms significativos.
En el ejemplo a desarrollar, todas las operaciones de transmisin de datos y comandos hacia el LCD
son seguidas de una serie de subrutinas, simplificando de esa manera la complejidad del programa.
III. Ejemplo para la Gestin de un LCD
Mostrar en el LCD la siguiente leyenda:
HELLO WORD!_
NOTA: Si no se logra ver nada en el LCD, tal vez, sea necesario regular el contraste del LCD a
travs de R2 conectado al pin 3 del LCD.
El circuito a ser utilizado para comprender mejor las explicaciones de la Gestin de un LCD, se
presenta a continuacin:

33

1. Diagrama de Flujo:
Diagrama de flujo del Programa Principal:

Los diagramas de flujo de las subrutinas de este programa no se presentan, pero a continuacin se
describen brevemente las Subrutinas de gestin del LCD.

34

Subrutina

Funcin

LcdInit

Se ocupa de inicializar el display y de limpiar la pantalla. Debe ser llamada una sola vez y antes de cualquier otra
subrutina.
No requiere paso de parmetros.

LcdClear

Limpia el contenido de pantalla y reposiciona el cursor en la primera fila y primera columna.

LcdLocate

Posiciona arbitrariamente el cursor dentro del rea visible del display.

No requiere paso de parmetros.

Necesita el valor de fila y columna para posicionar el cursor en el registro W. Los bits desde D0 a D3 contienen
el valor de columna (eje Y) y los bits desde D4 a D7 los valores de filas (eje X). La numeracin de las filas parte
de cero hacia arriba, la de columna parte de cero hacia la derecha.
Enva el carcter ASCII al LCD a ser visualizado en la posicin donde se encuentra el cursor.

LcdSendData

Requiere cargar en el registro W el valor ASCII del carcter.


LcdSendCommand Enva un comando al LCD. Los comandos reconocidos por el LCD, estn especificados en la hoja de datos del
mismo.
Requiere cargar en el registro W el valor de 8 bit del comando a enviar.
Esta funcin, es usada internamente por las dems y se ocupa de efectuar el deslizamiento de los datos y comando
de 8 bit en el bus de datos de 4 bit.

LcdSendByte

2. Cdigo en Assembler:
El cdigo de este ejemplo se muestra a continuacin:
;**************************************************
;
; LCD.ASM
;
;**************************************************
PROCESSOR 16F877
RADIX
DEC
INCLUDE
"P16F877.INC"
__CONFIG

_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

;LCD Control lines


LCD_RS equ 2
LCD_E equ 3

;Register Select
;Enable

;LCD data line bus


LCD_DB4 equ 4
LCD_DB5 equ 5
LCD_DB6 equ 6
LCD_DB7 equ 7

;LCD data line DB4


;LCD data line DB5
;LCD data line DB6
;LCD data line DB7

ORG

20H

tmpLcdRegister res
msDelayCounter res
Start
bsf

2
2

STATUS,RP0

movlw 00000011B

;Swap to register bank 1


; Set as output just the LCD's lines

35

movwf TRISB
bcf

STATUS,RP0

;Swap to register bank 0

;LCD inizialization
call LcdInit
;Locate LCD cursor on row 0, col 0
movlw 10H
call LcdLocate
;Shows "HELLO WORLD" string on LCD
movlw 'H'
call LcdSendData
movlw 'E'
call LcdSendData
movlw 'L'
call LcdSendData
movlw 'L'
call LcdSendData
movlw 'O'
call LcdSendData
movlw ' '
call LcdSendData
movlw 'W'
call LcdSendData
movlw 'O'
call LcdSendData
movlw 'R'
call LcdSendData
movlw 'L'
call LcdSendData
movlw 'D'
call LcdSendData
movlw ' '
call LcdSendData
movlw '!'
call LcdSendData
foreverLoop
goto foreverLoop
;**********************************************************************
; Delay subroutine
; W = Requested delay time in ms (clock = 4MHz)
;**********************************************************************
msDelay
movwf msDelayCounter+1
clrf msDelayCounter+0
; 1 ms (about) internal loop
msDelayLoop
nop
decfsz msDelayCounter+0,F
goto msDelayLoop
nop
decfsz msDelayCounter+1,F
goto msDelayLoop

36

return
;**********************************************************************
; Init LCD
; This subroutine must be called before each other lcd subroutine
;**********************************************************************
LcdInit
movlw 30
call msDelay

;Wait 30 ms

;****************
; Reset sequence
;****************
bcf

PORTB,LCD_RS ;Set LCD command mode

;Send a reset sequence to LCD


bsf PORTB,LCD_DB4
bsf PORTB,LCD_DB5
bcf PORTB,LCD_DB6
bcf PORTB,LCD_DB7
bsf PORTB,LCD_E ;Enables LCD
movlw 5
;Wait 5 ms
call msDelay
bcf PORTB,LCD_E ;Disables LCD
movlw 1
;Wait 1ms
call msDelay
bsf PORTB,LCD_E ;Enables LCD
movlw 1
;Wait 1ms
call msDelay
bcf PORTB,LCD_E ;Disables LCD
movlw 1
;Wait 1ms
call msDelay
bsf PORTB,LCD_E ;Enables E
movlw 1
;Wait 1ms
call msDelay
bcf PORTB,LCD_E ;Disables E
movlw 1
;Wait 1ms
call msDelay
bcf
bsf
bcf
bcf

PORTB,LCD_DB4
PORTB,LCD_DB5
PORTB,LCD_DB6
PORTB,LCD_DB7

bsf PORTB,LCD_E ;Enables LCD


movlw 1
;Wait 1ms
call msDelay
bcf PORTB,LCD_E ;Disabled LCD
movlw 1
;Wait 1ms
call msDelay
;Set 4 bit data bus length
movlw 28H;
call LcdSendCommand

37

;Entry mode set, increment, no shift


movlw 06H;
call LcdSendCommand
;Display ON, Curson ON, Blink OFF
movlw 0EH
call LcdSendCommand
;Clear display
call LcdClear
return
;**********************************************************************
; Clear LCD
;**********************************************************************
LcdClear
;Clear display
movlw 01H
call LcdSendCommand
movlw 2
call msDelay

;Wait 2 ms

;DD RAM address set 1st digit


movlw 80H;
call LcdSendCommand
return
;**********************************************************************
; Locate cursor on LCD
; W = D7-D4 row, D3-D0 col
;**********************************************************************
LcdLocate
movwf tmpLcdRegister+0
movlw 80H
movwf tmpLcdRegister+1
movf tmpLcdRegister+0,W
andlw 0FH
iorwf tmpLcdRegister+1,F
btfsc tmpLcdRegister+0,4
bsf tmpLcdRegister+1,6
movf tmpLcdRegister+1,W
call LcdSendCommand
return
;**********************************************************************
; Send a data to LCD
;**********************************************************************

38

LcdSendData
bsf PORTB,LCD_RS
call LcdSendByte
return
;**********************************************************************
; Send a command to LCD
;**********************************************************************
LcdSendCommand
bcf PORTB,LCD_RS
call LcdSendByte
return
;**********************************************************************
; Send a byte to LCD by 4 bit data bus
;**********************************************************************
LcdSendByte
;Save value to send
movwf tmpLcdRegister
;Send highter four bits
bcf PORTB,LCD_DB4
bcf PORTB,LCD_DB5
bcf PORTB,LCD_DB6
bcf PORTB,LCD_DB7
btfsc
bsf
btfsc
bsf
btfsc
bsf
btfsc
bsf

tmpLcdRegister,4
PORTB,LCD_DB4
tmpLcdRegister,5
PORTB,LCD_DB5
tmpLcdRegister,6
PORTB,LCD_DB6
tmpLcdRegister,7
PORTB,LCD_DB7

bsf PORTB,LCD_E ;Enables LCD


movlw 1
;Wait 1ms
call msDelay
bcf PORTB,LCD_E ;Disabled LCD
movlw 1
;Wait 1ms
call msDelay
;Send lower four bits
bcf PORTB,LCD_DB4
bcf PORTB,LCD_DB5
bcf PORTB,LCD_DB6
bcf PORTB,LCD_DB7
btfsc
bsf
btfsc
bsf
btfsc
bsf
btfsc
bsf

tmpLcdRegister,0
PORTB,LCD_DB4
tmpLcdRegister,1
PORTB,LCD_DB5
tmpLcdRegister,2
PORTB,LCD_DB6
tmpLcdRegister,3
PORTB,LCD_DB7

bsf

PORTB,LCD_E

;Enables LCD

39

movlw 1
;Wait 1ms
call msDelay
bcf PORTB,LCD_E ;Disabled LCD
movlw 1
;Wait 1ms
call msDelay
return
END

Anlisis del programa fuente LCD.ASM


En la primera parte, estn definidas algunas constantes:
;LCD Control lines
LCD_RS
equ 2 ;Register Select
LCD_E
equ 3 ;Enable
;LCD data line
LCD_DB4 equ 4
LCD_DB5 equ 5
LCD_DB6 equ 6
LCD_DB7 equ 7

bus
;LCD
;LCD
;LCD
;LCD

data
data
data
data

line
line
line
line

DB4
DB5
DB6
DB7

Estas constantes definen la asociacin entre las lneas del PIC (todas conectadas al PortB) y las lneas
del LCD. Cada definicin en particular, ser usada en las subrutinas de gestin del LCD en lugar de
cada nmero de identificacin de las lneas de I/O.
tmpLcdRegister res 2
msDelayCounter res 2

Seguidamente, se reserva el espacio para dos registros: tmpLcdRegister, usado por la subrutina de
gestin del LCD y msDelayCounter usada por la subrutina msDelay que generan los retardos por
sofware de 1 ms para el contenido del registro W. Estas subrutinas son usadas siempre por las
subrutinas de gestin para generar las temporizaciones requeridas durante la transmisin de datos y
comandos.
Sigue la definicin de las lneas de conexin entre el PIC y el LCD y luego se arriba a la primera
subrutina que interesa:
call

LcdInit

LcdInit es una subrutina que debe ser llamada solamente una vez en el inicio del programa y antes de
cualquier otra subrutina de gestin. Ella se ocupa de efectuar todas las operaciones necesarias para
inicializar correctamente el LCD y permite que las funciones sucesivas operen correctamente.
Con las instrucciones:
movlw
call

00H
LcdLocate

40

se posiciona el cursor del display en la primera fila y en la primera columna de la pantalla. Los
caracteres enviados sucesivamente, sern visualizados a partir de esta posicin. Los cuatro bits ms
significativos del valor cargado en el registro W con la instruccin:
movlw

00H

Contienen el nmero de fila donde se quiere posicionar el cursor, los cuatro bits menos significativos,
contienen el nmero de columna.
Cambiando el valor en el registro W, se obtiene posicionamientos diferentes. Con el valor 10H, por
ejemplo, se obtiene:
HELLO WORD!_
Con el valor 12H, se obtiene:
HELLO WORD!_
A esta altura, para visualizar cada carcter de la frase, se usan las siguientes instrucciones:
movlw
call

'H'
LcdSendData

Y as sucesivamente para cada letra a ser visualizada. El incremento de la posicin del cursor, se hace
automticamente.
Mayor informacin sobre el uso de los LCDs, puede obtenerse de la hoja de datos que el fabricante
debe proveer.

41

También podría gustarte