3 Puertos de Inp - Out V3

41
1 Los Puertos Paralelos de Entrada/Salida

description

puertos del pic16f877A

Transcript of 3 Puertos de Inp - Out V3

  • 1

    Los Puertos Paralelos de Entrada/Salida

  • 2

    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).

  • 3

    Registro ADCON1 (direccin 9Fh)

    A continuacin se indica el registro ADCON1:

    U-0 U-0 R/W-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0 ADFM --- --- --- PCFG3 PCFG2 PCFG1 PCFG0

    Bit 7 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.

  • 4

    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:

  • 5

    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.

  • 6

    R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 R/W-1 #RBPU INTED T0CS T0SE PSA PS2 PS1 PS0

    Bit 7 Bit 0

    Bit 7: #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

  • 7

    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.

  • 8

    Cada entrada del puerto C posee un buffer con disparador trigger. Adems, cuando se selecciona la funcin I2C, las patitas PORTC pueden ser configuradas con niveles I2C o con niveles SMBus mediante el bit CKE del registro SSPSTAT, 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 Funcin multiplexada

    RC0/T1OSO/T1CKI Salida oscilatoria del Timer1/reloj de entrada del Timer 1

    RC1/T1OSI/CCP2

    Entrada oscilatoria del Timer1/entrada de captura2 o salida de

    comparacin2 o salida PWM2

    RC2/CCP1 Entrada de captura1 o salida de comparacin1 o salida PWM1

    RC3/SCK/SCL Reloj para los modos de comunicacin serie sncrona SPI e I2C

    RC4/SDI/SDA Dato de entrada (en modo SPI)/ Dato de entrada-salida (modo I2C)

    RC5/SDO Dato de salida (en modo SPI)

    RC6/TX/CK Lnea de transmisin asncrona de la USART/reloj sncrono

    RC7/RX/DT Lnea de recepcin asncrona de la USART/dato sncrono

  • 9

    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).

    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.

  • 10

    1. Diagrama de Flujo:

    INICIO

    RA50

    RA0=1

    SI

    NO

    RA1=1NO

    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 ;si RA=0 salta a checar RA1 Apaga 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 Prend BSF PORTA,5 ;si RA1=1 enciende el LED

    GOTO chRA0

  • 11

    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).

  • 12

    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

  • 13

    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 esc RETURN ;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 ;Carga dato que controla la duracin rep ADDLW 0xFF ;Le suma 1 BTFSS STATUS,2 ;Si es cero escapa GOTO rep ;si no es cero, repite esc RETURN ;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 ;(1) MOVWF cont ;(1)

    rep DECFSZ cont,1 ;(1 si no escapa, 2 si escapa) GOTO rep ;(2) esc RETURN ;(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

  • 14

    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

    FIN

    WN

    cont1W

    cont1cont1-1

    Z=1

    SI

    NO

    cont2cont2-1

    Z=1NO

    SI

    WM

    cont2W

  • 15

    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 ;(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

    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.

  • 16

    1. Diagrama de Flujo:

    d1seg

    Z=1NO

    SI

    Wp

    cont3W

    d20ms

    cont3cont3-1

    FIN

    2. Cdigo en Assembler:

    ;* Subrutina de pausa de 1 segundo ;********************************************************************** p EQU 0x05 cont3 EQU 0x22

    d1seg MOVLW p ;(1)carga duracin del ciclo MOVWF cont3 ;(1)inicializa contador3

    ciclo CALL d20ms ;(197639)pausa de 0.197639 seg DECFSZ cont3,1 ;(1,2)Decrementa y escapa si cero GOTO ciclo ;(2)si no es cero repite RETURN ;(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

  • 17

    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:

  • 18

    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 ;checa si RA0=1 GOTO checa ;si RA=0 checa de nuevo CALL d20ms ;si RA0=1 espera 20 miliseg. A que pase el rebote

    chec1 BTFSS PORTA,0 ;checa nuevamente si RA0=1 GOTO chec1 ;si RA1=0 falsa alarma, vuelve a checar MOVLW 0x20 ;si RA0=1 seal vlida; carga mscara en W XORWF PORTA,1 ;conmuta estado del LED GOTO checa ;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

  • 19

    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:

  • 20

    INICIO

    C=0SI

    NO

    RB01

    N0x00

    M0x00

    p0x05

    C0

    PORTB0

    RB01

    d1seg

    PORTBrota izq PORTB

    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

  • 21

    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.

  • 22

    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:

  • 23

    INICIO

    Z=1NO

    SI

    W0xFF

    masqW

    detect

    masqW-masq

    PORTCW

    initB

    codif

    N0x1A

    M0x00

    Diagrama de flujo de la Subrutina initB:

  • 24

    Diagrama de flujo de la Subrutina detec:

    INICIO

    PORTB0

    RB7=1NO

    RB4=1

    RB5=1

    RB6=1NO

    NO

    NO

    SI

    SI

    SI

    SI

    W0x00

    FIN

    d20ms

    A

    RB7=1NO

    RB4=1

    RB5=1

    RB6=1NO

    NO

    NO

    SI

    SI

    SI

    SI

    W0x00

    FIN

    A

    FIN

    W0xFF

    Diagrama de flujo de la Subrutina codif:

  • 25

    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

  • 26

    CLRF STATUS ;Selecciona Banco 0 CLRF PORTC ;Inicializa latches de datos de PORTC BSF STATUS,RP0 ;Selecciona Banco 1 MOVLW 0x00 ;configura puerto C como salidas MOVWF TRISC ; BCF STATUS,RP0 ;regresa al Banco 0

    ;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

    ;Esta subrutina realiza la Inicializacin del puerto B: ;*********************************************************************

    initB CLRF STATUS ;Selecciona Banco 0 CLRF PORTB ;Inicializa latches de datos de PORTB BSF STATUS,RP0 ;Selecciona Banco 1 MOVLW 0xF0 ;configura RB7,...,RB4 como entradas MOVWF TRISB ;y RB3,RB2,RB1 como salidas BCF OPTION_REG,7 ;Conecta todas las resistencias Pull-Up BCF STATUS,RP0 ;regresa al Banco 0 RETURN

    ;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 ;activa las cuatro filas BTFSS PORTB,7 ;lee rengln 1,2,3 GOTO rebo ;si tecla presionada limpia rebote BTFSS PORTB,6 ;lee rengln 4,5,6 GOTO rebo ;si tecla presionada limpia rebote BTFSS PORTB,5 ;lee rengln 7,8,9 GOTO rebo ;si tecla presionada limpia rebote BTFSS PORTB,4 ;lee rengln *,0,# GOTO rebo ;si tecla presionada limpia rebote RETLW 0x0 ;no hubo tecla presionada retorna con w=0

    rebo CALL d20ms ;pausa de 20 milisegundos 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

    ;* 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

  • 27

    ;*********************************************************************

    ; 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 ;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

    ;* Subrutina de pausa para frecuencias medias ;* (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

    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.

  • 28

    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 a b c d e f g Cdigo 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

  • 29

    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:

    Diagrama de flujo del Programa Principal:

    INICIO

    RC7=0NO

    SI

    N0x1A

    M0x00

    PORTB0x01

    cont0

    d20ms

    POTCW

    RC7=1NO

    SI

    RC7=1

    SI

    NO

    contcont+1

    codigo

  • 30

    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 ;banco 1 MOVLW 0x80 ;Todos los bits del puerto C como salidas MOVWF TRISC ;y el MSB como entrada BCF STATUS,RP0 ;regresa al Banco 0

    MOVLW 0x01 ;

  • 31

    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.

    ;* Subrutina para determinar el codigo hexadecimal ;* ;**************************************************************************

    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 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

    ;* 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

    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,

  • 32

    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 Funcin 1 GND Ground. Conectar al negativo de alimentacin 2 VDD Power Supply. Conectar al positivo de alimentacin (+5 v) 3 LCD Liquid Crystal Driving Voltage. En este pin debe ser aplicada una tensin variable entre 0 y 5V para

    regular el contraste 4 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) 5 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) 6 E Enable. Esta lnea de control sirve para habilitar el display para que reciba un dato o instrucciones a

    travs del bus (E=1) 7 DB0 Data Bus Line 0 - Sobre estas lneas viajan los datos entre el micro y el display 8 DB1 Data Bus Line 1 9 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.

  • 33

    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:

    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:

    HELLO WORD!_

  • 34

    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.

  • 35

    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.

    No requiere paso de parmetros. 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.

    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. LcdSendByte 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.

    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 ;Register Select LCD_E equ 3 ;Enable

    ;LCD data line bus LCD_DB4 equ 4 ;LCD data line DB4 LCD_DB5 equ 5 ;LCD data line DB5 LCD_DB6 equ 6 ;LCD data line DB6 LCD_DB7 equ 7 ;LCD data line DB7

    ORG 20H

    tmpLcdRegister res 2 msDelayCounter res 2

    Start bsf STATUS,RP0 ;Swap to register bank 1

    movlw 00000011B ; Set as output just the LCD's lines

  • 36

    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

  • 37

    return

    ;********************************************************************** ; Init LCD ; This subroutine must be called before each other lcd subroutine ;**********************************************************************

    LcdInit movlw 30 ;Wait 30 ms call msDelay

    ;**************** ; 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 PORTB,LCD_DB4 bsf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf 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

  • 38

    ;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 ;Wait 2 ms call msDelay

    ;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 ;**********************************************************************

  • 39

    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 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

    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 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

    bsf PORTB,LCD_E ;Enables LCD

  • 40

    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 bus LCD_DB4 equ 4 ;LCD data line DB4 LCD_DB5 equ 5 ;LCD data line DB5 LCD_DB6 equ 6 ;LCD data line DB6 LCD_DB7 equ 7 ;LCD data line 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 00H call LcdLocate

  • 41

    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:

    Con el valor 12H, se obtiene:

    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.

    HELLO WORD!_

    HELLO WORD!_