Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Entrada/Salida
1
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 pines pueden ser configurados
para trabajar como entradas o como salidas a seleccin del programador.
3.1. El Puerto A (PORTA)
El puerto A posee 6 pines 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 al p i n fsico
correspondiente del puerto. Al hacer una lectura este registro se lee el estado de todas los pines
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 los pines 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 del pin correspondiente del puerto A, as, para k=0,1,...,5:
Todos los pines 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 el pin RA4, e l 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). Los pines RA0, RA1, RA2, RA3 y RA5 estn
multiplexados con las entradas analgicas AN0,...,AN4, respectivamente; de manera que
antes de utilizarlos se debe 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)
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 los pines del
puerto A, mostrando la diferencia entre los pines RA4 y los dems pines del puerto A:
El PIC puede ser implementado en diversas topologas de estado de escritura para el pin de I/O,
teniendo en cuenta que los pines de los puertos E/S tienen igual comportamiento o ligeramente difiere
uno del otro. Conociendo el funcionamiento de diversos estados de escritura del puerto, se puede
aprovechar de mejor manera las caractersticas y optimizar el proyecto.
1. Estado de lectura y escritura de los pines RA0, RA1, RA2, RA3 y RA5
El esquema para estos pines muestra el estado de escritura extrado del data sheet del Microchip.
Por ejemplo, se toma el pin RA0 para analizar el funcionamiento del estado de salida cuando el
mismo funciona como entrada o como salida:
3
a. Funcionamiento como Entrada
Para configurar el pin 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 otro pin 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 el pin RA0 desconectado 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 el pin RA0 desconectado de
la tierra. El estado lgico del pin 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.
Para configurar el pin 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 el pin RA0. Si se coloca en 1 el bit
0 con la instruccin:
bsf PORTA, 0
Se obtendr la conduccin del transistor P y por tanto ir a +5 V el pin RA0. Con esta condicin
ser siempre posible revisar el valor enviado sobre el pin a travs del circuito de entrada.
4
2. Estado de Salida del pin RA4
Se analiza el funcionamiento del estado de salida del pin RA4 que es diferente de las otros pines 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 pines RA0 a RA3 con ausencia de la
compuerta OR y del transistor P, o de todos los circuitos que permiten una conexin a positivo del
pin RA4. Esto significa en trminos prcticos que cuando un pin RA4 est programado 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 un pin de salida y pudiendo as
reprogramarla como pin de entrada.
Si se quiere asegurar que el pin RA4 sea 1 se debe conectar externamente un resistor de PULL-UP,
ya sea un resistor conectado al positivo de alimentacin.
El puerto B es un puerto digital de 8 bits, todas sus pines 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
los ocho pines 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 el pin RB correspondiente como salida y al poner un 1 en un bit de TRISB se
configura el pin 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 pin 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 e l pin
correspondiente es configurado como salida. Un Reset desconecta todas las resistencias.
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
Bit 7: #RBPU: Resistencia de Pull-up en el PORTB
1=Resistencia de Pull-up desactivada
0= Resistencia de Pull-up activada
Pines RB4, ... ,RB7. Estos cuatro pines del puerto B tienen la capacidad de generar una solicitud de
interrupcin a la CPU cuando estn configuradas como entradas. El estado de estos pines 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 pin 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 alguno de los cuatro pines es activado, 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 estos cuatro pines, los 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 los pines del puerto B:
Para este grupo de pines permanece sustancialmente invariante la lgica de conmutacin, estas
disponen de un circuito WEAK PULL-UP que se activa cuando el pin es programado como
entrada.
6
La entrada del evento, como se explic anteriormente, el pin viene completamente desligado del
PIC. Un estado del pin 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 un pin 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. El pin
RB0 solo presenta una caracterstica especial, cuando est configurado como pin 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.
Un circuito de conmutacin de este grupo es muy similar al grupo de RB0 a RB3. Este pin dispone
tambin de un circuito de weak pull-up. Tambin tienen con respecto a los pines anteriores la
ventaja de poder revelar variaciones de estado sobre cualquier pin 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.
El puerto C consta de 8 pines bidireccionales. Trabaja en forma similar a los dos puertos
anteriores y tiene asociados los registros:
2. Registro TRISC (87H).- Registro de control de direccin de los pines del puerto C.
Poniendo un 1 en un bit del registro TRISC se configura los pines correspondiente como entrada
y poniendo un 0 se configura la lnea correspondiente como salida.
Los pines del puerto C se encuentran multiplexados con varios pines controlados por otros
perifricos, cuando se habilita el pin del perifrico respectivo puede ser ignorada la configuracin
de TRISC, de hecho, algunos perifricos configuran e l p i n como salida mientras que otros la
configuran como entrada.
Cada entrada del puerto C posee un buffer con disparador trigger. Adems, cuando se selecciona la
funcin I2C, los pines PORTC<4,3> pueden ser configurados 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 los pines del puerto B.
7
Pines 7, 6, 5, 2, 1 y 0 del puerto C Pines 4 y 3 del puerto C
3.3.2. Perifricos que estn multiplexados con los p i n e s del puerto C
En la siguiente tabla se resumen los p i n e s del puerto C y los de los perifricos que estn
multiplexados con ellos.
3.5. Ejemplo 31
Entradas digitales. En este ejemplo se configura el pin RA5 del puerto A como salida conectado a
un LED, el cual se controla de acuerdo al estado de los pines RA0 y RA1 configurados 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.
9
1. Diagrama de Flujo:
INICIO
NO
RA0=1
SI
RA50
NO
RA1=1
SI
RA51
2. Cdigo en Assembler:
;*****************************************************************************
;* Ejemplo31.asm
;* 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
;*****************************************************************************
PROCESSOR 16F877
RADIX DEC
INCLUDE "P16F877A.INC"
;Reset Vector
org 0x00 ;Inicia en el vector de reset
;Una vez inicializado el puerto, se procede leer los pines RA0 y RA1
BCF STATUS,RP0 ;regresa al banco 0
chRA0 BTFSS PORTA,0 ;checa si RA0=1
10
GOTO chRA1 ;si RA=0 salta a checar RA1
BCF PORTA,5 ;si RA0=1 apaga el LED
chRA1 BTFSS PORTA,1 ;checa si RA1=1
GOTO chRA0 ;si RA1=0 salta a checar RA0
BSF PORTA,5 ;si RA1=1 enciende el LED
GOTO chRA0
END
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 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.
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):
12
pau20ms
WN
contW
contcont-1
NO
Z=1
SI
FIN
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
MOVWF cont ;inicializa contador con el dato, cont=N
rep DECFSZ cont,1 ;Decrementa contador y escapa si cero, cont=cont-1
GOTO rep ;si no es cero, repite
RETURN ;regresa de esta subrutina
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
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:
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.
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:
14
d20ms
WN
cont1W
WM
cont2W
cont2cont2-1
NO
Z=1
SI
cont1cont1-1
NO
Z=1
SI
FIN
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 0x00
cont1 EQU 0x20
cont2 EQU 0x21
;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
RETURN ;(2) regresa de esta subrutina
15
La duracin de esta subrutina en ciclos de reloj ser
N = (Tsub/Tcy
7)/(3M+4)
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.
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.
1. Diagrama de Flujo:
16
d1seg
Wp
cont3W
d20ms
cont3cont3-1
NO
Z=1
SI
FIN
2. Cdigo en Assembler:
La mxima duracin de esta subrutina (para p =256), suponiendo un reloj de 4 Mhz (Tcy = 1
seg), se tiene un Tsubmximo=50,596357 seg. Sin embargo, si se desea un Tsub=1seg. Se
obtiene:
p = (Tsub/Tcy 5)/197642 = 5,059628 ~ 5
17
3.7. Ejemplo 2
En este ejemplo se usa slo el botn conectado al pin RA0 para controlar el encendido y
apagado del LED en el pin RA5, cuando se presiona el botn conectado a RA0 se enciende el LED
conectado en el pin RA5 y lo apaga cuando se presiona nuevamente el mismo botn y as
sucesivamente. 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:
INICIO
N0x1A
M0x00
NO
RA0=1
SI
d20ms
NO
RA0=1
SI
W0x20
RA5W XOR RA5
18
El diagrama de flujo de la Subrutina d20ms se realiza en el subtema Limpiado del rebote.
2. Cdigo en Assembler:
;**************************************************************************
;* Ejemplo32.asm
;* 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
;* as sucesivamente.
;**************************************************************************
PROCESSOR 16F877
RADIX DEC
INCLUDE "P16F877A.INC"
;Define constantes
N EQU 0x1A
M EQU 0x0
;Define variables
CBLOCK 0x20
cont1
cont2
ENDC
;Reset Vector
org 0x00 ;Inicia en el vector de reset
END
3.8. Ejemplo 3
Hardware necesario. Slo se requieren los ocho LEDs conectados a los pines RBP0,...,RBP7,
como se muestra en la siguiente figura.
1. Diagrama de Flujo:
20
INICIO
N0x00
M0x00
p0x05
C0
PORTB0
RB01
d1seg
SI
C=0
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:
;**********************************************************************
;* Ejemplo33.asm
;* Este programa Enciende en secuencia (uno a la vez) 8 LEDs conectados
;* a los pines del puerto B
;**********************************************************************
PROCESSOR 16F877
RADIX DEC
INCLUDE "P16F877A.INC"
21
p EQU 0x05
;Define variables
CBLOCK 0x20
;Define variables para pausa de 200 mseg
cont1
cont2
;Define variable para pausa de 1 segundo
cont3
ENDC
;Reset Vector
org 0x00 ;Inicia en el vector de reset
END
22
3.9. Ejemplo 4
El presente ejemplo realiza el 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.
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.
En la figura tambin se ilustra una conexin tpica con tres pines de entrada del puerto B que
controlan las columnas y cuatro pines de salida del mismo puerto que recogen la informacin de los
renglones.
1. Deteccin. Se ponen en bajo todos las 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 el pin
correspondiente a la fila a activar.
23
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:
INICIO
N0x1A
M0x00
initB
W0xFF
masqW
detect
masqW-masq
NO
Z=1
SI
codif
PORTCW
24
initB
STATUS0
PORTB0
TRISB0xF0
RBPU0
FIN
INICIO
PORTB0 A
NO NO
RB7=1 RB7=1
SI SI
NO NO
RB6=1 RB6=1
SI SI
NO NO
RB5=1 RB5=1
SI SI
NO NO
RB4=1 RB4=1
SI SI
NO NO NO
RB7=1 RB7=1 RB7=1
SI W1 SI W2 SI W3
NO NO NO
RB6=1 RB6=1 RB6=1
SI SI SI
W4 W5 W6
NO NO NO
RB5=1 RB5=1 RB5=1
SI W7 SI W8 SI W9
NO NO NO
RB4=1 RB4=1 RB4=1
SI W* SI W0 SI W#
A B W0x00
2. Cdigo en Assembler:
;*********************************************************************
;* Ejemplo34.asm
;* 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.
;*********************************************************************
PROCESSOR 16F877
RADIX DEC
INCLUDE "P16F877A.INC"
26
;Define variables
CBLOCK 0x20
;Define variables para pausa de 20 mseg
cont1
cont2
;Define variable para mascara 0xFF (tecla pulsada)
masq
ENDC
;Reset Vector
org 0x00 ;Inicia en el vector de reset
;Programa principal
CALL initB ;Llama a la subtutina initB
repite MOVLW 0xFF ;Almacena en W la mascara 0xFF
MOVWF masq ;Almacena en masq la mascara 0xFF
CALL detec ;Llama a la subtutina detect
SUBWF masq,1 ;
BTFSS STATUS,Z ;Resultado en W=0
GOTO repite ;Repite el proceso
CALL codif ;Llama a la subtutina codif
MOVWF PORTC ;Mueve la tecla presionada al puerto C
GOTO repite ;Repite el proceso
27
BTFSS PORTB,7 ;lee rengln 1,2,3
RETLW 0xFF ;tecla presionada, retorna con w=0xFF
BTFSS PORTB,6 ;lee rengln 4,5,6
RETLW 0xFF ;tecla presionada, retorna con w=0xFF
BTFSS PORTB,5 ;lee rengln 7,8,9
RETLW 0xFF ;tecla presionada, retorna con w=0xFF
BTFSS PORTB,4 ;lee rengln *,0,#
RETLW 0xFF ;tecla presionada, retorna con w=0xFF
RETLW 0x0 ;falsa alarma retorna con w=0
; Segunda columna
MOVLW 0xFB ;Activa la segunda columna
MOVWF PORTB ;y activa la columna 2,5,8,0
BTFSS PORTB,7 ;Es la tecla 2?
RETLW '2' ;retorna cdigo del ?2?
BTFSS PORTB,6 ;Es la tecla 5?
RETLW '5' ;retorna cdigo del ?5?
BTFSS PORTB,5 ;Es la tecla 8?
RETLW '8' ;retorna cdigo del ?8?
BTFSS PORTB,4 ;Es la tecla 0?
RETLW '0' ;Retorna cdigo del ?0?
; Tercera columna
MOVLW 0xFD ;Activa la tercera columna
MOVWF PORTB ;y activa la columna 3,6,9,#
BTFSS PORTB,7 ;Es la tecla 3?
RETLW '3' ;retorna cdigo del ?3?
BTFSS PORTB,6 ;Es la tecla 6?
RETLW '6' ;retorna cdigo del ?6?
BTFSS PORTB,5 ;Es la tecla 9?
RETLW '9' ;retorna cdigo del ?9?
BTFSS PORTB,4 ;Es la tecla #?
RETLW '#' ;Retorna cdigo del ?#?
RETLW 0x00 ;falsa alarma, no hay tecla presionada
28
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
RETURN ;(2) regresa de esta subrutina
END
3.10. Ejemplo 5
Para este ejemplo se supone un display de nodo comn conectado al puerto C como se muestra a
continuacin:
Dato a b c d e f g Cdigo
29
0 0 0 0 0 0 0 1 01
1 1 0 0 1 1 1 1 4F
2 0 0 1 0 0 1 0 12
3 0 0 0 0 1 1 0 06
4 1 0 0 1 1 0 0 4C
5 0 1 0 0 1 0 0 24
6 0 1 0 0 0 0 0 20
7 0 0 0 1 1 1 1 0F
8 0 0 0 0 0 0 0 00
9 0 0 0 0 1 0 0 04
A 0 0 0 1 0 0 0 08
b 1 1 0 0 0 0 0 60
C 0 1 1 0 0 0 1 31
d 1 0 0 0 0 1 0 42
E 0 1 1 0 0 0 0 30
F 0 1 1 1 0 0 0 38
1. Diagrama de Flujo:
30
INICIO
N0x1A
M0x00
PORTB0x01
cont0
NO
RC7=1
SI
d20ms
NO
RC7=1
SI
contcont+1
codigo
POTCW
NO
RC7=0
SI
31
codigo
W0x0F
WW AND cont
PCLW + PCL
Selecciona un
valor de acuerdo
a cont:
0: W0x01
1: W0x4F
2: W0x12
3: W0x06
4: W0x4C
5: W0x24
6: W0x20
7: W0x0F
8: W0x00
9: W0x04
10: W0x08
11: W0x60
12: W0x31
13: W0x42
14: W0x30
15: W0x38
FIN
2. Cdigo en Assembler:
;************************************************************************
;* Ejemplo35.asm
;* 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
;************************************************************************
PROCESSOR 16F877
RADIX DEC
INCLUDE "P16F877A.INC"
;Define variables
CBLOCK 0x20
;Define variables contador
cont
32
;Define variables para pausa de 20 mseg
cont1
cont2
;Define variable para pausa de 1 segundo
cont3
ENDC
;Reset Vector
org 0x00 ;Inicia en el vector de reset
MOVLW 0x01 ;
MOVWF PORTC ;Despliega un cero. Codificado
CLRF cont ;Inicializa contador en cero
tecla BTFSS PORTC,7 ;checa botn si se ha presionado
GOTO tecla ;Si no se ha presionado espera
CALL d20ms ;pausa de 20 milisegundos
BTFSS PORTC,7 ;checa nuevamente el botn si esta presionado
GOTO tecla ;tecla falsa, espera de nuevo
INCF cont,1 ;tecla vlida, incrementa contador
CALL codigo ;obtiene cdigo para desplegar el contador
MOVWF PORTC ;despliega contador
suelta BTFSC PORTC,7 ;checa de nuevo el botn si se ha soltado
GOTO suelta ;si sigue presionado espera
GOTO tecla ;si ya se solt espera nueva presin.
codigo
MOVLW 0x0F ;carga mscara
ANDWF cont,0 ;enmascara el contador y lo deja en W
ADDWF PCL,1 ;Salta W instrucciones adelante
RETLW 0x01 ;cdigo del 0
RETLW 0x4F ;cdigo del 1
RETLW 0x12 ;cdigo del 2
RETLW 0x06 ;cdigo del 3
RETLW 0x4C ;cdigo del 4
RETLW 0x24 ;cdigo del 5
RETLW 0x20 ;cdigo del 6
RETLW 0x0F ;cdigo del 7
RETLW 0x00 ;cdigo del 8
RETLW 0x04 ;cdigo del 9
33
RETLW 0x08 ;cdigo de la A
RETLW 0x60 ;cdigo de la b
RETLW 0x31 ;cdigo de la C
RETLW 0x42 ;cdigo de la d
RETLW 0x30 ;cdigo de la E
RETLW 0x38 ;cdigo de la F
;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
RETURN ;(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,
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
http://www.geekfactory.mx/tutoriales/tutoriales-pic/pantalla-lcd-16x2-con-pic-libreria/
por Jesus Ruben Santa Anna Zamudio | Ago 2, 2014 | Tutoriales PIC | 3 Comments
11.1. Descripcin:
Cuando los simples indicadores luminosos con led ya no son suficientes, habitualmente el siguiente
paso para todo programador es ir por una pantalla lcd 162. Se encuentra que existen mdulos LCD
que facilitan la interfaz con este perifrico. El estndar en la industria para estos mdulos con
controlador a bordo es el chipset HD44780 (y otros ms compatibles desarrollados a partir de este),
para los cuales se encuentra soporte en prcticamente cualquier plataforma: Arduino, PIC, AVR,
MSP430, etc.
En la Figura 1 se muestra un LCD 2x16 que est compuesto por 2 lneas de 16 caracteres, con
iluminacin azul y letras color blanco.
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 1 estn descriptas las funciones de cada lnea disponible del LCD. Las descripciones en
negrita, indican las lneas efectivamente utilizadas en la aplicacin de 4 bits de datos.
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 tierra.
Tampoco la lnea R/W# ser utilizada por lo que ser puesta a tierra. De este modo, quedar
seleccionado el modo escritura. En la prctica, slo se podr enviar datos al LCD pero no recibirlos.
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.
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.
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?
Los mdulos LCD responden a un conjunto especial de instrucciones, estas deben ser enviadas por el
microcontrolador o sistema de control al display, segn la operacin que se requiera. Se muestran en la
Tabla 2 el conjunto de instrucciones del mdulo LCD.
36
Tabla 2. Conjunto de instrucciones del mdulo LCD
Cdigo de Operacin Tiempo de
Instruccin Descripcin
RS R/W B7 B6 B5 B4 B3 B2 B1 B0 Ejecucin
Borra el contenido de la pantalla y
Clear display 0 0 0 0 0 0 0 0 0 1 retorna el cursor a la posicin home 1.52 ms
(direccin 0).
Retorna el cursor a la posicin
Home. Retorna tambin el rea de
Cursor home 0 0 0 0 0 0 0 0 1 * visin a la posicin inicial. El 1.52 ms
contenido de la DDRAM permanece
intacto.
Incrementar/Decrementar direccin
(I/D); Habilitar corrimiento de
Entry mode set 0 0 0 0 0 0 0 1 I/D S 37 s
pantalla (S). Estas operaciones se
realizan al leer o escribir datos
Enciende o apaga el display (D),
Display on/off
0 0 0 0 0 0 1 D C B Cursor encendido / apagado (C), 37 s
control
destello del cursor (blink) (B).
Selecciona entre desplazamiento de
pantalla o de cursor (S/C), selecciona
Cursor/display
0 0 0 0 0 1 S/C R/L * * la direccin de desplazamiento (R/L). 37 s
shift
El contenido de la DDRAM
permanece intacto.
Configurar en ancho de bus (4 u 8
Function set 0 0 0 0 1 DL N F * * bits) (DL), Nmero de lneas de 37 s
display (N), y tipo de fuente (F).
Escribe la direccin de CGRAM. Los
Set CGRAM Direccin generador de datos a almacenar en CGRAM pueden
0 0 0 1 37 s
address RAM ser enviados despus de esta
instruccin
Escribe la direccin de DDRAM. Los
Set DDRAM datos a almacenar en DDRAM pueden
0 0 1 Direccin de datos RAM 37 s
address ser enviados despus de esta
instruccin
Leer bandera Ocupado (Bussy Flag)
indicando si el controlador est
Read busy flag realizando alguna operacin interna o
&address 0 1 BF CGRAM/DDRAM address est listo para aceptar datos/comandos. 0 s
counter Lee la direccin CGRAM o DDRAM
(dependiendo de la instruccin
previa).
Write CGRAM Escribe datos a las memorias CGRAM
1 0 Escritura de Dato 37 s
orDDRAM o DDRAM.
Read from Lee datos desde las memorias
1 1 Lectura de Dato 37 s
CG/DDRAM CGRAM o DDRAM.
NOTA: ntese que el pin RS# debe tomar el valor 0 (cero) cuando lo que se va a enviar es una
instruccin de control y debe tomar el valor 1 (uno) cuando lo que se va a enviar es un dato.
37
Tabla 3. Significado de las abreviaturas
SIGNIFICADO DE LAS ABREVIATURAS
(Nombres y significado de bits en instrucciones)
I/D 0 = disminuir el contador de direccin, 1 = incrementar el contador de direccin;
N 0 = 1 lnea, 1 = 2 lneas;
La interface entre el microcontrolador y el LCD se puede hacer con el bus de datos del PIC trabajando
a 4 u 8 bits. Las seales de control trabajan de la misma forma en cualquiera de los dos casos, la
diferencia se establece en el momento de iniciar el display, ya que existe una instruccin que permite
establecer dicha configuracin. O sea se tiene que avisarle al LCD que se va a operar en 8 o a 4 bits.
Los caracteres que se envan al display se almacenan en la memoria RAM del mdulo. Existen
posiciones de memoria RAM, cuyos datos son visibles en la pantalla y otras que no son visibles, estas
ltimas se pueden utilizar para guardar caracteres que luego se desplazan a la zona visible.
Es importante anotar que solo se pueden mostrar caracteres ASCII de 7bits, por lo tanto algunos
caracteres especiales no se pueden ver (es aconsejable tener a mano una tabla de caracteres ASCII para
conocer los datos que son prohibidos). Tambin se tiene la opcin de mostrar caracteres especiales
creados por el programador y almacenarlos en la memoria RAM que posee el mdulo.
http://www.bolanosdj.com.ar/SOBRELCD/TEORIALCDV1.pdf
El HD44780 permite conectarse a travs de un bus de 4 u 8 bits. El modo de 4 bits permite usar solo 4
pines para el bus de datos, dndonos un total de 6 o 7 pines requeridos para la interfaz con el LCD,
38
mientras que el modo de 8 bits requiere 10 u 11 pines. El pin RW es el nico que puede omitirse si se
usa la pantalla en modo de solo escritura y deber conectarse a tierra si no se usa. En este caso el
microcontrolador no puede leer desde el chip controlador de pantalla, pero en la mayora de las
situaciones esto no es necesario.
11.3.1. Conexin bsica de una pantalla lcd 162 con una interface de 8 bits
Las conexiones para el modo de 8 bits son algo ms complicadas, ya que se requiere las 8 lneas de
datos activas. En este caso se utiliza los 8 bits del puerto B, aunque se puede usar cualquier
combinacin de pines. RA0 ahora funciona como seal de seleccin de registro (RS) y RA1 como
seal de habilitacin (E). En la Figura 2 se muestra las conexiones para el modo de 8 bits en un
PIC16F877.
Esta forma de manejo es la ms sencilla de programar, pero tiene la desventaja de utilizar 8 pines del
microcontrolador solo para el envo de datos y otros 2 pines para las seales de control.
En principio en la mayor parte de las aplicaciones se va requerir escribir en el LCD y rara vez leer en el
mismo, por lo tanto en este curso se dedicar exclusivamente a escribir en el LCD. Esto implica que el
pin de seleccin de lectura/escritura (R/W) se conectar siempre a tierra GND.
Si se utiliza el puerto B como bus de datos (manejar los pines D0 a D7 del LCD) y el puerto A se
encarga de manejar las seales de control (manejar los pines E y RS del LCD).
39
Se debe programar 2 subrutinas, una que se llama INSTRUC que ser invocada cuando se quiera enviar
una instruccin al mdulo LCD, por ejemplo limpiar pantalla, indicar una posicin de memoria, indicar
si se utiliza interfaz de 8 o 4 bits etc. Y otra subrutina que se llama ESCRIB que ser invocada cuando
se quiera escribir un dato para ser visualizado en el mdulo LCD.
Se configurar entonces todo el puerto B como salida al igual que los pines RA0 y RA1 del puerto A,
estando asignado cada pin del puerto como se indica a continuacin:
Pin PORTB RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
Pin LCD D7 D6 D5 D4 D3 D2 D1 D0
RECORDAR: Como solo se va a escribir en pantalla, el pin R/W vale siempre 0 (cero), as que se lo
conecta directamente a tierra.
Evidentemente se debe configurar el PORTB del PIC como salida, y en el PORTA los pines RA0 y
RA1 deben ser configurados como salidas. El resto de los pines del PORTA se puede configurar como
se desee. Recuerde que se est basando esta explicacin para interface de 8 bits.
Lo primero que hay que hacer es mandar una serie de instrucciones al mdulo LCD que constituyen la
configuracin del mismo. Luego recin se podr escribir el mensaje a presentar en pantalla.
11.3.3. Instrucciones muy importantes (son independientes a que se use interface de 4 u 8 bits)
Se informa el tipo de interfaz que se va a usar, 4 o 8 bits. La cantidad de lneas (1 o 2). La fuente de
caracter (5x8 dots o 5x10 dots).
RS R/W# D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 0 0 DL N F - -
DL = 0 interfaz de 4 bits.
DL = 1 interfaz de 8 bits.
40
D7 D6 D5 D4 D3 D2 D1 D0
0 0 1 1 0 0 0 1
DL = 1 interfaz de 8 bits.
N=0 se va a usar 1 sola lnea del display.
F=0 fuente de caracter 5x8 dots.
Ahora se debe llamar a la subrutina INSTRU (esta subrutina debe ser creada por el programador, se le
puede dar el nombre que se quiera), la cual va a enviar 30h al PORTB, hacer RS=0 o sea le dice al
LCD que lo que va a recibir es una instruccin (RA0= 0 del PORTA) y E=1 o sea habilita al LCD
(RB1= 0 del PORTA), luego vuelve a hacer E=0 deshabilita.
Configura el estado ON/OFF de todo el display, el estado del cursor y el parpadeo del caracter en la
posicin del cursor.
RS R/W# D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 0 0 0 1 D C B
Donde:
D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 0 1 1 0 0
Se est diciendo:
Ahora se debe llamar nuevamente a la subrutina INSTRU (esta subrutina debe ser creada por el
programador, se le puede dar el nombre que se quiera), la cual va a enviar 0Ch al PORTB, hacer RS=0
41
o sea le dice al LCD que lo que va a recibir es una instruccin (RA0=0 del PORTA) y E=1 o sea
habilita al LCD (RB1= 0 del PORTA), luego vuelve a hacer E=0 deshabilita.
RS R/W# D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 0 0 0 0 0 0 1
RS R/W# D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 0 0 0 0 1 ID S
ID = 1 incremento.
ID = 0 decremento.
D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 0 0 1 1 0
NOTAR que los unos enviados a D2 y D1 carecen de sentido porque no hay desplazamiento.
Hasta aqu se han enviado las instrucciones previas para inicializar el mdulo LCD y dejarlo listo para
la escritura de datos en pantalla.
El envi de los datos se realiza por medio de los pines D0 a D7 del LCD, que se encuentran conectados
a los pines RB0 a RB7 del PORTB B del PIC. Por lo tanto los datos a escribir deben ser enviados a
travs del PORTB B.
Un dato se enva por medio de su cdigo ASCII, pero previamente se debe indicar al mdulo la
posicin de memoria en que deseo escribir el dato que se enviar a continuacin. Esto se hace por
medio de la instruccin DDRAM.
42
DDRAM (Instruccin)
Le informa al mdulo LCD la direccin de memoria en la cual se va almacenar el cdigo del dato que
se le enviar a continuacin.
RS R/W# D7 D6 D5 D4 D3 D2 D1 D0
0 0 1 Posicin de memoria a escribir dato
Se aclara algo para no confundirse. Supngase que se desea escribir 'A' en la posicin de memoria 00h
del LCD.
Como se tiene que asegurar el 1 en el D7 se debe enviar al PORTB (recordar que D0 ... D7 del LCD
est conectado a RB0 ... RB7 del PORTB) en lugar de 00h el 80h, esto es para asegurar el 1 en el D7
(el 1 en D7 hace 00000000 se convierta en 10000000 o sea 80h).
D7 D6 D5 D4 D3 D2 D1 D0
1 0 0 0 0 0 0 0
Ahora que se le informa donde se va a escribir el dato, se debe enviarlo y aclararle que se est enviando
un dato, para lo cual se necesita una subrutina que justamente har esto y que se la llamar ESCRIB.
43
Tabla 4. Mapa de la Memoria del Mdulo LCD (2 lneas x 16 caracteres)
00h 01h 02h 03h 04h 05h 06h 07h 08h 09h 0Ah 0Bh 0Ch 0Dh 0Eh 0Fh 10h --- 1Fh
40h 41h 42h 43h 44h 45h 46h 47h 48h 49h 4Ah 4B 4C 4D 4Eh 4Fh 50h --- 5Fh
rea no
rea visible visible - 16
posiciones
Como se haba mencionado anteriormente, al enviar una direccin hay que asegurar el 1 en D7
Por ejemplo:
D7 D6 D5 D4 D3 D2 D1 D0
1 0 0 0 0 0 0 0
De este modo se podra pensar en un mapa de memoria equivalente del mdulo LCD como muestra en
la Tabla 5, en el caso de solo utilizar la zona visible.
80h 81h 82h 83h 84h 85h 86h 87h 88h 89h 8Ah 8Bh 8Ch 8Dh 8Eh 8Fh
C0h C1h C2h C3h C4h C5h C6h C7h C8h C9h CAh CB CC CD CEh CFh
Ejemplo 6
44
LCD1
LCD16x2
VDD
VSS
VEE
RW
RS
D0
D1
D2
D3
D4
D5
D6
D7
E
1
2
3
4
5
6
7
8
9
10
11
12
13
14
BOXER
13 33
OSC1/CLKIN RB0/INT
14 34
OSC2/CLKOUT RB1
X1 1 35
MCLR/Vpp/THV RB2
36
RB3/PGM
2 37
RA0/AN0 RB4
3 38
RA1/AN1 RB5
20Mhz R1 4
RA2/AN2/VREF- RB6/PGC
39
10k 5 40
RA3/AN3/VREF+ RB7/PGD
C2 C1 6
RA4/T0CKI
22p 22p 7 15
RA5/AN4/SS RC0/T1OSO/T1CKI
16
RC1/T1OSI/CCP2
8 17
RE0/AN5/RD RC2/CCP1 VDD
9 18
RE1/AN6/WR RC3/SCK/SCL
10 23
VDD RE2/AN7/CS RC4/SDI/SDA
24
RC5/SDO
25
RC6/TX/CK
26
RC7/RX/DT
19
RD0/PSP0
20
RD1/PSP1
21
RD2/PSP2
22
RD3/PSP3
27
RD4/PSP4
28
RD5/PSP5
29
RD6/PSP6
30
RD7/PSP7
PIC16F877
processor 16f877
include <p16f877.inc>
;Define variables
cblock 0x20
temp5
endc
org 00
inicio
bsf STATUS,5 ;se posiciona en banco1
clrf TRISB ;define el PORTB como salida
clrf TRISA ;define el PORTA como salida
movlw 06h ; carga w con literal 06h
movwf ADCON1; carga ADCON1 con w = 06h para entradas digitales
bcf STATUS,5
;------------Una instruccion-----------
movlw 30h; carga w con literal 30h
;la intrucc asociada dice: interface de datos de 8 bits y se va a usar
;1 linea - corresponde a la intruccion ACTIVAR FUNCION
call instruc; enviaremos este valor al PORTB y por lo tanto al LCD
45
;------------otra instruccion-----------
movlw 06h; carga w con literal 06h
;la intrucc asociada dice: dato fijo en pantalla- corresponde a la intruccion
;SELECCIONAR MODO
call instruc; enviaremos este valor al PORTB y por lo tanto al LCD
;------------otra instruccion-----------
movlw 0Ch; carga w con literal 0Ch
;la intrucc asociada dice: encienda la pantalla y desactive el cursor-
;corresponde a la intruccion ENCENDER O APAGAR PANTALLA
call instruc; enviaremos este valor al PORTB y por lo tanto al LCD
;------------otra instruccion-----------
movlw 01h; carga w con literal 01h
;la intrucc asociada dice: BORRAR PANTALLA
call instruc; enviaremos este valor al portb y por lo tanto al LCD
;---escritura de datos---------------
movlw 80h; se indica posicion de memoria del LCD en que quiere
; escibir el dato
call instruc
movlw " "; este es dato - al estar entre comillas se le indica al
; compilador que el dato requerido es el valor ASCII del
; caracter
call escrib
movlw 81h;
call instruc
movlw "H";
call escrib
movlw 82h;
call instruc
movlw "O";
call escrib
movlw 83h;
call instruc
movlw "L";
call escrib
movlw 84h;
call instruc
movlw "A";
call escrib
movlw 85h;
call instruc
movlw " ";
call escrib
movlw 86h;
call instruc
movlw "M";
call escrib
46
movlw 87h;
call instruc
movlw "U";
call escrib
movlw 88h;
call instruc
movlw "N";
call escrib
movlw 89h;
call instruc
movlw "D";
call escrib
movlw 8Ah;
call instruc
movlw "O";
call escrib
movlw 8Bh;
call instruc
movlw ".";
call escrib
movlw 8Ch;
call instruc
movlw ".";
call escrib
;---fin escritura de datos-----------
;--------SUBRUTINAS-------------
;----------------------------------------
;Subrutina que manda una instruccion al LCD
instruc
bcf PORTA,0 ; hace 0 el bit 0 del PORTA o sea hace RS=0 - Le dice
; al LCD que es una intruccion lo que va a recibir
bsf PORTA,1 ; hace 1 el bit 1 del PORTA - O sea E=1 habilita LCD
movwf PORTB; carga contenido de w en PORTB
call retardo
bcf PORTA,1; hace 0 el bit 1 del PORTA - O sea E=0 habilita LCD
call retardo
return
;----------------------------------------
;Subrutina que manda un dato al LCD
escrib
bsf PORTA,0 ; hace 1 el bit 0 del PORTA o sea hace RS=1 - Le dice
; al LCD que es es un dato lo que va a recibir
bsf PORTA,1 ; hace 1 el bit 1 del PORTA - O sea E=1 habilita LCD
movwf PORTB; carga contenido de w en PORTB
call retardo
bcf PORTA,1; hace 0 el bit 1 del PORTA - O sea E=0 habilita LCD
call retardo
return
;----------------------------------------
;Subrutina retardo
retardo
47
movlw 0ffh; carga literal 0ffh en w
movwf temp5; mueve contenido de w a temp5
decr
decfsz temp5,1 ; decrementa temp5 y guarda resultado en temp5- salta
; la intruccion siguiente si temp es igual a cero
goto decr
return
;--------FIN SUBRUTINAS--------
end
Realizar una aplicacin que muestre el siguiente mensaje en el lcd 2x16, en forma repetida, con un
tiempo de muestreo de 1 seg:
1. Diagrama de Conexiones
2. El cdigo es el siguiente:
48
processor 16F877
include <P16F877.INC>
;Configuracin de puertos
clrf PORTB ;Limpia PORTB
clrf PORTD ;Limpia PORTD
bsf STATUS, RP0
bcf STATUS, RP1 ;Selecciona el banco 1
clrf TRISB ;Configura PORTB como salida
clrf TRISD ;Configura PORTD como salida
bcf STATUS,RP0 ;Regresa al banco 0
START_LCD:
call INICIA_LCD ;Configura el LCD
call M1 ;Muestra Mensaje
call LINEA2 ;Configura lnea 2
call M2 ;Muestra Mensaje
goto START_LCD
;Mensaje a enviar
M1:
movlw 'H' ;Mueve 'H' a W
movwf PORTB ;Mueve lo que hay en W a PORTB
call ENVIA ;Imprime en LCD
movlw 'e'
movwf PORTB
call ENVIA
movlw 'l'
movwf PORTB
call ENVIA
movlw 'l'
movwf PORTB
call ENVIA
movlw 'o'
movwf PORTB
call ENVIA
movlw ' '
movwf PORTB
call ENVIA
movlw 'W'
movwf PORTB
call ENVIA
movlw 'o'
movwf PORTB
call ENVIA
movlw 'r'
movwf PORTB
call ENVIA
movlw 'l'
movwf PORTB
call ENVIA
movlw 'd'
49
movwf PORTB
call ENVIA
movlw '!'
movwf PORTB
call ENVIA
return
M2:
movlw 'I' ;Mueve 'I' a W
movwf PORTB ;Mueve lo que hay en W a PORTB
call ENVIA ;Imprime en LCD
movlw 'm'
movwf PORTB
call ENVIA
movlw ' '
movwf PORTB
call ENVIA
movlw 'O'
movwf PORTB
call ENVIA
movlw 'p'
movwf PORTB
call ENVIA
movlw 'e'
movwf PORTB
call ENVIA
movlw 'n'
movwf PORTB
call ENVIA
movlw 'B'
movwf PORTB
call ENVIA
movlw 'o'
movwf PORTB
call ENVIA
movlw 'x'
movwf PORTB
call ENVIA
movlw 'e'
movwf PORTB
call ENVIA
movlw 'r'
movwf PORTB
call ENVIA
return
50
;Subrutina para enviar comandos
COMANDO:
bsf PORTD,1 ; Pone ENABLE en 1
call DELAY ; Tiempo de espera
call DELAY
bcf PORTD, 1 ; ENABLE=0
call DELAY
return
; Subrutina de retardo
DELAY:
movlw 0xFF
movwf val2
ciclo:
movlw 0xFF
movwf val1
ciclo2:
decfsz val1,1
goto ciclo2
decfsz val2,1
goto ciclo
return
END
11.4.1. Conexin bsica de una pantalla lcd 162 con una interface de 4 bits
Las conexiones para el modo de 4 bits en un PIC16F877 se muestran en la Figura 5. Se utilizan los
primeros 4 bits del puerto A (RA0-RA3) como bus de datos. RB0 como seal de habilitacin (E) y
RB1 como seal de seleccin de registro (RS).
51
Figura 5. Las conexiones para el modo de 4 bits en un PIC16F877
Es el caso ms utilizado para aprovechar los puertos del PIC. Dejando disponibles pines de los mismos
para otras funciones.
RW va a tierra
Las subrutinas INSTRUC y ESCRIB sern diferentes que para el caso de interfaz de 8 bits. Estas
enviaran primero los 4bit MSB y luego los 4 bits LSB.
Ejemplo 8
Limpia la pantalla
52
(C) DJB_2009 Primera fila
Limpia la pantalla
RECREO Primera fila
Limpia la pantalla
ALARMA Primera fila
LCD1
LCD16x2
VDD
VSS
VEE
RW
RS
D0
D1
D2
D3
D4
D5
D6
D7
E
1
2
3
4
5
6
7
8
9
10
11
12
13
14
BOXER
13 33
OSC1/CLKIN RB0/INT
14 34
OSC2/CLKOUT RB1
X1 1 35
MCLR/Vpp/THV RB2
36
RB3/PGM
R1 2
RA0/AN0 RB4
37
10k 3 38
RA1/AN1 RB5
4 39
20Mhz RA2/AN2/VREF- RB6/PGC
5 40
RA3/AN3/VREF+ RB7/PGD
C2 C1 6
RA4/T0CKI
22p 22p 7 15
RA5/AN4/SS RC0/T1OSO/T1CKI
16
RC1/T1OSI/CCP2
8 17
VDD RE0/AN5/RD RC2/CCP1 VDD
9 18
RE1/AN6/WR RC3/SCK/SCL
10 23
RE2/AN7/CS RC4/SDI/SDA
24
RC5/SDO
25
RC6/TX/CK
26
RC7/RX/DT
19
RD0/PSP0
20
RD1/PSP1
21
RD2/PSP2
22
RD3/PSP3
27
RD4/PSP4
28
RD5/PSP5
29
RD6/PSP6
30
RD7/PSP7
PIC16F877
processor 16f877
include <p16f877.inc>
org 00
inicio
bsf STATUS,5 ;se posiciona en banco1
clrf TRISB ;define el PORTB como salida
movlw b'00001100'
movwf TRISA
movlw 06h ; carga w con literal 06h
movwf ADCON1; carga ADCON1 con w = 06h para entradas digitales
mostrar
btfsc PORTA,2 ; si en el pin 2 del PORTA hay un 0 entonces muestra
; mensaje1-alternado con mensaje3
goto frase2
call mensaje1
call espera
frase2
btfsc PORTA,3 ; si en el pin 3 del PORTA hay un 0 entonces muestra
; mensaje2-alternado con mensaje3
goto frase3
call mensaje2
call espera
frase3
call copyright ; si recibe un 0 en pines 2 y 3 de PORTA muestra
; mensaje3
call espera
goto mostrar
;--------SUBRUTINAS-------------
;------------otra instruccion-----------
movlw 28h; carga w con literal 28h
;la intrucc asociada dice: interfase de datos de 4 bits y se va a usar 2
;lineas - corresponde a la intruccion ACTIVAR FUNCION
call instruc; enviaremos este valor al PORTB y por lo tanto al LCD
;------------otra instruccion-----------
movlw 06h; carga w con literal 06h
54
;la intrucc asociada dice: dato fijo en pantalla- corresponde a la intruccion
;SELECCIONAR MODO
call instruc; enviaremos este valor al PORTB y por lo tanto al LCD
;------------otra instruccion-----------
movlw 0Ch; carga w con literal 0Ch
;la intrucc asociada dice: encienda la pantalla y desactive el
;cursor- corresponde a la intruccion ENCENDER O APAGAR PANTALLA
call instruc; enviaremos este valor al PORTB y por lo tanto al LCD
;------------otra instruccion-----------
movlw 01h; carga w con literal 01h
;la intrucc asociada dice: BORRAR PANTALLA
call instruc; enviaremos este valor al PORTB y por lo tanto al LCD
return
;-------Fin Subrutina LCD --------
;--------------------Subrutina INSTRC/ESCRIB-------------------------
;Subrutina que manda una instruccion o dato al LCD
;Esta subrutina utiliza el registro de proposito general aux
instruc
bcf PORTB,0; RB0=0 o sea RS=0 es una instruccion para LCD
goto dato2
escrib
bsf PORTB,0; RB0=1 o sea RS=1 es una dato para LCD
dato2
;lo que se va hacer es para no alterar el contenido de los 4 bit menos
;significativos del PORTB
movwf aux; guarda contenido de w en aux
movlw 0fh; carga 00001111 en w
andwf PORTB,1 ; AND entre w=00001111 y PORTB y guarda resultado en
; PORTB
;lo que se termino de hacer es para no alterar el contenido de los 4 bit
;menos significativos dell PORTB
return
;---------Fin subrutina que manda instruccion o dato al LCD------
retardo4
incf tempo1,1
retardo5
incf tempo2,1
retardo6
incf tempo3,1
btfss tempo3,7
goto retardo6
clrf tempo3
btfss tempo2,7
goto retardo5
clrf tempo2
btfss tempo1,7
goto retardo4
clrf tempo1
56
;Limpia la E en display que escribio al principio
movlw 0CFh;
call instruc
movlw " ";
call escrib
;Termino de limpiar la E
return
;-----Fin subrutina largaespera-----------------------
;---Subrutina copyright-----------
copyright
movlw 01h
; call instruc; borrar pantalla
movlw 82h;
call instruc
movlw ")";
call escrib
movlw 83h;
call instruc
movlw " ";
call escrib
57
movlw 84h;
call instruc
movlw "D";
call escrib
movlw 85h;
call instruc
movlw "J";
call escrib
movlw 86h;
call instruc
movlw "B";
call escrib
movlw 87h;
call instruc
movlw "-";
call escrib
movlw 88h;
call instruc
movlw "2";
call escrib
movlw 89h;
call instruc
movlw "0";
call escrib
movlw 8Ah;
call instruc
movlw "0";
call escrib
movlw 8Bh;
call instruc
movlw "9";
call escrib
call espera
call espera
call espera
call espera
return
;---Fin subrutina copyright-----------------------------------------------
;---Subrutina mensaje1-----------
mensaje1
movlw 01h
; call instruc; borrar pantalla
movlw 82h;
call instruc
movlw "C";
call escrib
movlw 83h;
call instruc
movlw "R";
call escrib
movlw 84h;
call instruc
movlw "E";
call escrib
movlw 85h;
call instruc
movlw "O";
call escrib
movlw 86h;
call instruc
movlw ".";
call escrib
movlw 87h;
call instruc
movlw ".";
call escrib
movlw 88h;
call instruc
movlw ".";
call escrib
movlw 89h;
call instruc
movlw ".";
call escrib
movlw 8Ah;
call instruc
movlw ".";
call escrib
movlw 8Bh;
call instruc
movlw ".";
call escrib
59
call espera
call espera
call espera
call espera
return
;---Fin subrutina mensaje1-----------------------------------------------
;---Subrutina mensaje2-----------
mensaje2
movlw 01h
; call instruc; borrar pantalla
movlw 82h;
call instruc
movlw "A";
call escrib
movlw 83h;
call instruc
movlw "R";
call escrib
movlw 84h;
call instruc
movlw "M";
call escrib
movlw 85h;
call instruc
movlw "A";
call escrib
movlw 86h;
call instruc
movlw ".";
call escrib
movlw 87h;
call instruc
movlw ".";
call escrib
movlw 88h;
call instruc
movlw ".";
60
call escrib
movlw 89h;
call instruc
movlw ".";
call escrib
movlw 8Ah;
call instruc
movlw ".";
call escrib
movlw 8Bh;
call instruc
movlw ".";
call escrib
call espera
call espera
call espera
call espera
return
;---Fin subrutina mensaje2-----------------------------------------------
;--------FIN SUBRUTINAS-------------
end
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 en la Figura 7:
61
Figura 7. Circuito de la Gestin de un LCD
1. Diagrama de Flujo:
Diagrama de flujo del Programa Principal:
62
INICIO
RS2
E3
DB44
DB55
DB66
DB77
LcdInit
W10H
LcdLocate
WH
LcdSendData
.
.
W!
LcdSendData
Los diagramas de flujo de las subrutinas de este programa no se presentan, pero en la Tabla 5 se
describen brevemente las Subrutinas de gestin del LCD.
63
LcdLocate Posiciona arbitrariamente el cursor dentro del rea visible del display.
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.
LcdSendData Enva el carcter ASCII al LCD a ser visualizado en la posicin donde se encuentra el cursor.
2. Cdigo en Assembler:
;**************************************************
;
; LCD.ASM
;
;**************************************************
PROCESSOR 16F877
RADIX DEC
INCLUDE "P16F877.INC"
ORG 20H
tmpLcdRegister res 2
msDelayCounter res 2
Start
bsf STATUS,RP0 ;Swap to register bank 1
;LCD inizialization
call LcdInit
foreverLoop
goto foreverLoop
;**********************************************************************
; Delay subroutine
; W = Requested delay time in ms (clock = 4MHz)
;**********************************************************************
msDelay
movwf msDelayCounter+1
clrf msDelayCounter+0
decfsz msDelayCounter+1,F
goto msDelayLoop
return
;**********************************************************************
; Init LCD
; This subroutine must be called before each other lcd subroutine
;**********************************************************************
65
LcdInit
movlw 30 ;Wait 30 ms
call msDelay
;****************
; Reset sequence
;****************
bcf PORTB,LCD_DB4
bsf PORTB,LCD_DB5
bcf PORTB,LCD_DB6
bcf PORTB,LCD_DB7
66
call LcdSendCommand
;Clear display
call LcdClear
return
;**********************************************************************
; Clear LCD
;**********************************************************************
LcdClear
;Clear display
movlw 01H
call LcdSendCommand
movlw 2 ;Wait 2 ms
call msDelay
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
;**********************************************************************
LcdSendData
bsf PORTB,LCD_RS
call LcdSendByte
return
;**********************************************************************
; Send a command to LCD
67
;**********************************************************************
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
btfsc tmpLcdRegister,4
bsf PORTB,LCD_DB4
btfsc tmpLcdRegister,5
bsf PORTB,LCD_DB5
btfsc tmpLcdRegister,6
bsf PORTB,LCD_DB6
btfsc tmpLcdRegister,7
bsf PORTB,LCD_DB7
btfsc tmpLcdRegister,0
bsf PORTB,LCD_DB4
btfsc tmpLcdRegister,1
bsf PORTB,LCD_DB5
btfsc tmpLcdRegister,2
bsf PORTB,LCD_DB6
btfsc tmpLcdRegister,3
bsf PORTB,LCD_DB7
68
return
END
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.
movlw 00H
call LcdLocate
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
69
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!_
A esta altura, para visualizar cada carcter de la frase, se usan las siguientes instrucciones:
movlw 'H'
call 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.
70