Está en la página 1de 28

UNIVERSIDAD NACIONAL DEL CALLAO

FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA


ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

CONTROL DE MODULO LCD


Introducción
Este capítulo está dedicado a los LCDs alfanuméricos con controlador Hitachi
HD44780 o compatible, es decir, la mayoría. Hay diversas firmas, como Optrex, Sharp,
Crystalfontz America, Tianma, etc., que producen muchísimos LCDs de este tipo.

Los hay desde 1 a 4 líneas, desde 8 a 40 letras por línea, algunos con iluminación de
fondo, con diferente tecnología de fabricación, etc. Dada la compatibilidad en el control
de todos ellos, la elección de un modelo en particular queda a tu cargo.

El LCD utilizado en este curso es de 2 líneas, de 16 letras cada una.

FIG.1 Un display LCD de 2 líneas, de 16 caracteres cada una.

Pines del LCD

PINES DEL DISPLAY LCD.


Tabla Número de Pin
Número de Pin Símbolo
1 Vss o GND
2 Vcc o Vdd
3 Vee o Vo
4 RS
5 R/W
6 E
7...14 DB0...DB7
15 y 16

Los pines 15 y 16 corresponden a la iluminación de fondo del LCD, pero aquí el orden varía
mucho. Sea como fuere, los 14 primeros pines siempre deberían coincidir.

Dr. Jacob Astocondor Villar 1


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

Nombre de
Función
señal
DB0-DB7 8 líneas de bus de datos. Para transferencia bidireccional de datos entre el MCU y el LCD.
o DB7 también se puede usar como bit busy flag. En operación de 4 bits solo se usa el nibble
D0-D7 alto.
E Enable – Señal de inicio de operación de lectura/escritura.
Señal para seleccionar operación de lectura o escritura.
R/W 0 : Escribir en LCD
1 : Leer de LCD
Register Select
0: Registro de comandos (escritura).
RS
   : Busy flag + puntero de RAM (lectura).
1 : Registro de datos (escritura, lectura). Acceso a DDRAM o CGRAM.
Vee o Vo Ajuste de contraste del LCD. Vee = GND es máximo contraste.
Vdd o Vcc Alimentación = +5 V típicamente.
Vss Alimentación = 0 V (GND).
AyK Son los pines de Anodo y Katodo de la iluminación de fondo que tienen algunos LCD.

Un modo de operación del LCD (con ventajas y desventajas) le permite trabajar sin
conectar el pin RW al microcontrolador. En ese modo pin RW siempre debe plantarse a
GND.

LCDs con iluminación de fondo

Algunos LCDs tienen iluminación de fondo. Esta característica se basa en diferentes


tecnologías, siendo la más habitual el empleo de una matriz de diodos LED colocados
detrás de la pantalla.

La iluminación basada en LEDs suele activarse con los pines 15 y 16, identificados
como A (de ánodo) y K (de cátodo) pero no necesariamente en ese orden. Estos pines
son independientes del controlador interno del LCD así que de poco sirve que nuestro
LCD diga ser compatible con HD44780. La polaridad varía tanto que en los diagramas
he puesto 15/16 para no especificar. En todo caso, la independencia de los pines A y K
permitirá que todas las prácticas de este curso funcionen con iluminación o sin ella.

Si los pines de iluminación en tu LCD no están marcados como A y K puedes consultar


su datasheet para ver cuáles son o averiguarlo manualmente del mismo modo que
compruebas la polaridad de un LED: aplica 5 V entre los pines 15 y 16 y si prende,.
Como en todo LED, no debes olvidar ponerle una resistencia en serie, como se ve
arriba. ¿Resistencia de cuánto?

Dr. Jacob Astocondor Villar 2


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

en términos generales, los LEDs de la iluminación requieren cerca de 4.3V y consumen


algo de 300 mA. De aquí calculamos que el valor de la resistencia debe andar por los 5
a 20 ohms. Queda a tu criterio hacer los ajustes para que alumbren tanto como quieras.

Memorias del LCD


CGROM - Character Generator ROM

Es la zona de memoria donde se encuentran grabados los patrones de todos los caracteres que
puede visualizar el LCD de fábrica. Tiene grabados cerca de 200 (varía mucho) tipos de
caracteres de 5×7 puntos (lo más común) o 32 caracteres de 5×10 puntos. Este último modo es
raramente usado porque no todos los modelos lo soportan.

DDRAM - Display Data RAM

La DDRAM almacena los códigos de las letras que se visualizan en la pantalla del LCD. Tiene
capacidad de 80 bytes, un byte por carácter si la fuente es de 5×7 puntos. Observa que no
siempre se podrán visualizar los 80 caracteres.

Por ejemplo, si quisiéramos mostrar el mensaje Hello en la pantalla, deberíamos enviar a la


DDRAM los códigos ascii de cada letra de esa palabra. El controlador interno del LCD tomará
esos códigos para buscar en la CGROM sus correspondientes patrones de visualización y luego
los mostrará en la pantalla.

La siguiente figura muestra la correspondencia entre las locaciones de la DDRAM y las


posiciones de las letras que vemos en la pantalla de un LCD de 2 líneas, particularmente de uno
de 2×16. Fíjate en que los 80 bytes de la DDRAM se dividen en dos sectores de 40 bytes, un
sector por línea, así:

 Línea 1, con sector de DDRAM desde 0x00 hasta 0x27.


 Línea 2, con sector de DDRAM desde 0x40 hasta 0x67.

Por lo tanto, podemos entender que siempre tenemos un LCD virtual de 2×40; aunque solo
podamos ver 8, 16 ó 20 letras por cada línea. Los otros datos escritos en la DDRAM
permanecen allí aunque no se visualicen.

Posiciones en DDRAM de las letras de la pantalla (números en hexadecimal).

Dr. Jacob Astocondor Villar 3


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

CGRAM - Character Generator RAM

La CGRAM es una RAM de 64 bytes donde el usuario puede programar los patrones de nuevos
caracteres gráficos, ya sean de 5×7 puntos (hasta 8 caracteres) o de 5×10 puntos (hasta 4
caracteres). Este tema lo detallaré en la práctica final.

El Puntero de RAM

Llamado también Address Counter, es un registro que sirve para acceder a las memorias RAM
del LCD. Por ejemplo, si el Puntero de RAM vale 0x00, accedemos a la locación de DDRAM
(o CGRAM) de esa dirección.

Ahora bien, solo hay un puntero de RAM que trabaja con las dos RAMs del LCD, y para saber a
cuál de ellas accede actualmente debemos ver la instrucción enviada más recientemente.

Las instrucciones Clear Display, Return Home y Set DDRAM Address designan el Puntero de
RAM a la DDRAM, mientras que Set CGRAM Address lo designa a la CGRAM.

Afortunadamente, en la gran mayoría de los casos, el Puntero de RAM estará apuntando a la


DDRAM. Además, en este caso viene a representar la posición del cursor (visible o no) del
LCD en la pantalla

SET DE INSTRUCCIONES DEL DISPLAY LCD

Es el controlador interno HD44780 (u otro) del LCD quien ejecutará las operaciones de mostrar
las letras en la pantalla, mover el cursor, desplazar el contenido de la pantalla, etc. Lo que nos
toca a nosotros es enviarle los códigos de esas operaciones. A continuación, un resumen.

Instrucciones del Display LCD


Código
Instrucciones
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
Clear Display 0 0 0 0 0 0 0 0 0 1
Return Home 0 0 0 0 0 0 0 0 1 ×
Entry Mode Set 0 0 0 0 0 0 0 1 I/D S
Display ON/OFF
0 0 0 0 0 0 1 D C B
Control
Instrucciones de Cursor or Display
0 0 0 0 0 1 S/C R/L × ×
comando Shift
Function Set 0 0 0 0 1 DL N F × ×
Set CGRAM Address 0 0 0 1 Puntero de RAM (CGRAM)
Set DDRAM Address 0 0 1 Puntero de RAM (DDRAM)
Read Busy Flag
0 1 BF Puntero de RAM (DDRAM o CGRAM)
& RAM Pointer
Write to CGRAM
1 0 Escribir dato
or DDRAM
Instrucciones de datos
Read from CGRAM
1 1 Leer dato
or DDRAM

Conviene saber que las instrucciones Clear Display y Return Home tienen un tiempo de
ejecución de cerca de 1.52 ms. Las demás toman algo de 40 µs.

Dr. Jacob Astocondor Villar 4


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

El LCD cuenta con dos registros internos principales, que dividen, grosso modo, las
instrucciones en de datos y de comando.

Poniendo el pin RS = 1 accedemos al registro de datos y mediante él a cualquier locación de la


DDRAM o CGRAM, para operaciones de lectura y escritura de datos.

Con RS = 0 accedemos al registro de comandos para escribir instrucciones de control del LCD
(Clear Display, Function Set, etc.). En el caso de una lectura, obtenemos un dato particular que
contiene el valor del puntero de RAM junto con el bit Busy flag.

Clear display:  0 0 0 0 0 0 0 1

Limpia toda la pantalla del LCD. También retorna el cursor a su posición inicial (cima
izquierda), esto es, designa el puntero de RAM a la dirección 0x00 de la DDRAM.

Return home:  0 0 0 0 0 0 1 x

Regresa el cursor a su posición inicial pero sin alterar el texto del display, es decir, solo designa
el puntero de RAM a la dirección 0x00 de la DDRAM.

Entry mode set:  0 0 0 0 0 1 I/D S

Establece el modo de incremento o decremento y modo de desplazamiento del LCD.

 I/D = 1: El puntero de RAM se incrementa en 1 después de leer o escribir un dato. Así


accedemos automáticamente a la siguiente locación de DDRAM o CGRAM. Si es
DDRAM, este puntero representa la posición del cursor en la pantalla y el incremento
significa su avance a la derecha.
 I/D = 0: El puntero de RAM se decrementa en 1 después de leer o escribir un dato.
 S = 1: Si se escribe un nuevo dato de carácter en el LCD, entonces el display entero se
desplaza a la derecha cuando I/D = 0 o a la izquierda cuando I/D = 1.
 S = 0: El display no se desplaza luego de escribir en la DDRAM. Esto es lo usual.

Display on/off control:  0 0 0 0 1 D C B

Prende o apaga el Display, el Cursor y la función Blink del cursor.

 D = 1: El display se prende.
 D = 0: Apaga el display. (No significa que los datos de las RAMs se vayan a borrar.)
 C = 1: Despliega el cursor.
 C = 0: No despliega el cursor
 B = 1: La letra indicada por el cursor parpadea.
 B = 0: La letra no parpadea.

Cursor or display shift:  0 0 0 1 S/C R/L x x

Desplaza el cursor o el display a la derecha o la izquierda sin escribir o leer datos .

Dr. Jacob Astocondor Villar 5


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

Tabla S/C

S/C R/L Operación

0 0 Mueve el cursor a la izquierda (puntero de RAM se decrementa en 1)

0 1 Mueve el cursor a la derecha (puntero de RAM se incrementa en 1)

1 0 El Cursor y el display entero se desplazan a la izquierda

1 1 El Cursor y el display entero se desplazan a la derecha

Function set:  0 0 1 DL N F x x

Configura la longitud del bus de datos, el número de líneas y el tipo de fuente.

 DL = 1 : La interface con el LCD es mediante un bus de datos de 8 bits.


 DL = 0 : La interface con el LCD es mediante un bus de datos de 4 bits.
 N = 1: Configura un display de 2 líneas.
 N = 0: Configura un display de 1 línea.
 F = 0: Fuente de carácter de 5×7 puntos.
 F = 1: Fuente de carácter de 5×10 puntos.

Set DDRAM address:  1AAAAAAA

Designa el puntero de RAM a la nueva dirección AAAAAAA de la DDRAM. Digamos que


sirve para controlar la posición del cursor del LCD.

Ejemplo, para escribir un texto en la segunda línea del display (que tiene dirección inicial 0x40),
primero habría que enviar el comando Set DDRAM Address con el número 0x40 en el
parámetro AAAAAAA.

Set CGRAM address:  01AAAAAA

Designa el puntero de RAM a la nueva dirección AAAAAAA de la CGRAM.

Read Busy Flag & RAM Pointer:  BF AAAAAAA

Leer bit Busy Flag (BF) y el valor del puntero de RAM. BF = 1 indica que una operación
interna está en progreso. El LCD no aceptará una nueva instrucción hasta que BF sea 0.

El valor de AAAAAAA leído representa el valor del puntero de RAM.

Es posible prescindir del bit BF. Para ello debemos esperar el tiempo adecuado antes de enviar
la siguiente instrucción.

Write data to CGRAM / DDRAM:  DDDDDDDD

Escribe el dato de 8 bits DDDDDDDD en la DDRAM o CGRAM, dependiendo de cuál de las


dos esté siendo direccionada actualmente. Después de la escritura el puntero de RAM se

Dr. Jacob Astocondor Villar 6


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

incrementa o decrementa, según se haya configurado el display. Ver instrucción Entry Mode
Set.

Read data from CGRAM / DDRAM:  DDDDDDDD

Lee un dato de 8 bits de la DDRAM o CGRAM, dependiendo de cuál de ellas esté siendo
direccionada actualmente. Después de la lectura el puntero de RAM se incrementa o decrementa
en uno, según la configuración del display. Ver instrucción Entry Mode Set.

Inicialización del LCD

Los LCDs tienen un circuito interno de reset que los inicializan automáticamente tras la
alimentación. Lo cierto es que la auto-inicialización no siempre es fiable. Por eso existe la
inicialización por software, que permite una completa configuración de los parámetros del LCD.
Se constituye de una serie de pasos aparentemente bastante exóticos, sobre todo los primeros,
pero que se justifican si tratamos de entender que este procedimiento debe ser capaz de
configurar el LCD para que funcione con bus de datos de 4 u 8 bits, sin importar cómo estuvo
operando antes, es decir, podemos cambiar "al vuelo" entre un modo y otro.

Además de ello cada nueva instrucción debe ser enviada al LCD asegurándonos de que no se
encuentre ocupado. El LCD indica su disponibilidad mediante el llamado bit BF (Busy Flag).
BF = 1 indica LCD ocupado y BF = 0 es LCD listo. BF es el MSbit del byte que se lee del LCD
cuando el pin RS = 0. Obviamente la lectura implica que debemos poder controlar el pin RW.
De no usar este pin en nuestra conexión, debemos hacer pausas entre una instrucción y otra.
Pero incluso si usamos el bit BF, al inicio debemos poner pausas porque se supone que el LCD
aún no sabe si va trabajar con bus de datos de 4 u 8 bits y no sabe cómo responder a las
instrucciones de lectura (no sabe si entregar bytes enteros o en nibbles). Que enredo!, ¿verdad?
Por eso los siguientes flowcharts se ven tan complicados pese a tratarse de los LCD más simples
del mundo. La inicialización de los LCD gráficos por ejemplo es más pequeña.

Dr. Jacob Astocondor Villar 7


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

Inicialización del LCD con bus de datos de 4 bits.

Dr. Jacob Astocondor Villar 8


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

Inicialización del LCD con bus de datos de 8 bits

Dr. Jacob Astocondor Villar 9


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

Interface entre un Microcontrolador y un display LCD

Esta presentación es poco usual. Los libros o los manuales de los compiladores suelen resaltar
solo la interface de la librería que proveen. Esta exposición va pensando en los noveles
usuarios del Arduino, que encuentran algo confusa la inicialización de su librería de
LCD por contemplar tofdos los modos de operación viables.

Aunque los LCDs parezcan simples de usar, para bien o para mal sus características abren
puertas a diversos modos de interface. Considerando que el bus de datos puede ser de 8 o 4 bits
y que se puede usar o prescindir de la línea de control RW, podemos obtener los siguientes 4
tipos de conexión. (Nota, la conexión de los pines de alimentación, de contraste y de la
iluminación de fondo se estudia en la sección pines del LCD)

Interface de display LCD


  8 líneas de Datos 4 líneas de Datos
3 líneas de Control (con RW) Interface de 11 líneas Interface de 7 líneas
2 líneas de Control (sin RW) Interface de 10 líneas Interface de 6 líneas

La interface de 11 líneas
se trabaja con los 8 bits del bus de datos y las 3 líneas de Control. El uso del pin RW controla
las operaciones de escritura (RW = 0) y lectura (RW = 1) del LCD.

Las lecturas nos permiten por un lado conocer si el LCD está ocupado o no para saber si
podemos enviar la siguiente instrucción de escritura, así como leer la posición actual del cursor.
La otra finalidad de las lecturas es obtener los datos de las memorias DDRAM y CGRAM del
LCD. Los datasheets dicen que el acceso bidireccional a las rams del LCD permiten utilizarlas
como memoria extendida del sistema. Ahora parece hasta ridículo pero tiene cierto sentido
considerando que estos LCDs nacieron en la prehistoria de los microcontroladores , donde los
microcontroladores tenían muy poca RAM o en su lugar se usaban microprocesadores (que
simplemente no tienen RAM).

Interface de 10 líneas entre un microcontrolador y un LCD

Dr. Jacob Astocondor Villar 10


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

En la interface de 10 lineas el pin RW del LCD va siempre plantado a GND (RW = 0). Ello
significa que el LCD solo aceptará operaciones de escritura del microcontrolador. Renunciar a
la lectura de las memorias RAM es un hecho que pasa casi desapercibido. El punto clave de no
controlar el pin RW es no enviar al LCD una nueva instrucción sin que haya terminado de
procesar la anterior. Ya que no podemos leer del LCD para saber su estado, debemos calcular su
disponibilidad a partir de los tiempos que demoran en ejecutarse las instrucciones. Por ejemplo,
una vez inviada la instrucción Clear Display debemos esperar al menos 1.6 ms (que es su
tiempo de ejecución) antes de enviar la siguiente instrucción.

Interface de 10 líneas entre un microcontrolador y un LCD

En la interface de 7 líneas
el bus de datos del LCD se conecta con el microcontrolador por sus 4 pines más altos: D4, D5,
D6 y D7. Como todas las instrucciones (de datos y de comando) son de un byte, los bytes deben
ser transferidos en dos mitades. Primero se envía o recibe el nibble alto y luego el nibble bajo,
siendo cada nibble validado por un pulso del pin Enable. Esas rutinas extras harán crecer un
poco el firmware (programa del microcontrolador).

En la contraparte, con el microcontrolador aún disponiendo de las tres líneas de control,


podemos realizar cualquier operación de lectura y escritura, lo mismo que en la interface
completa de 11 líneas pero ahorrándonos 4 pines. Este beneficio suele prevalecer sobre el
handicap derivado del firmware.

Los LCDs están fabricados con tecnología CMOS, por lo que algunos modelos sugieren
conectar los pines de entrada no usados a alguna señal estable para evitar que por ellos se filtre
algún ruido que pueda perturbar la operación del LCD.

Dr. Jacob Astocondor Villar 11


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

Interface de 7 líneas entre un microcontrolador y un LCD

Por último tenemos la interface de 6 líneas. Aquí se nos juntan todas las desventajas software de
tener que trabajar a base de nibbles y de renunciar a las lecturas del LCD para obtener datos de
sus memorias RAM o para saber si el LCD está ocupado o no antes de poder enviarle una nueva
instrucción. A pesar de todo eso, pueden darse ocasiones, como disponer de un
microcontrolador de muy pocos pines, donde tengamos que recurrir a esta conexión.

Interface de 6 líneas entre un microcontrolador y un LCD

Dr. Jacob Astocondor Villar 12


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

LABORATORIO 05

VISUALIZACION DE MENSAJES

1. Objetivo
Diseñar y desarrollar un programa utilizando el dsPIC33FJ12MC202 que despliegue el
siguiente mensaje: primera línea: UNAC-FIEE-2020A, segunda línea: APELLIDOS
2. Desarrollo.
Para mostrar cualquier mensaje en un LCD es necesario contar con las librerías xlcd.h y
xlcd.c.
Estas librerías contienen la configuración de la conexión del LCD con el dsPIC33FJMC202.
Adicionalmente en estas librerías se establece la programación para inicializar el LCD,
desplegar un carácter o una cadena de caracteres, la posición de escritura del LCD, y limpiar la
pantalla del LCD.
Existen diferentes librerías LCD para diferentes tipos de dsPICs pero todas cumplen con las
mismas funciones ya mencionadas.
En el caso del dsPIC33FJ12MC202 se tuvo que modificar la librería LCD para que ésta fuera
compatible con el DSPIC.
Teniendo estas librerías podemos mostrar cualquier mensaje, en la posición deseada con el
LCD. En la Tabla 1 se presenta el mensaje a desplegar.
Tabla 1. Mensaje a mostrar.

MENSAJE POSICION
FIEE-UNAC-2020A LINEA1
MICROCONTROLADORES LINEA2

3. Diagrama de flujo.
En la Fig. Se presenta el diagrama de flujo del programa desarrollado para el ejemplo 1. Se
observa al inicio del diagrama de flujo que se configura el programa, mediante el llamado de las
librerías y los encabezados, entre ellas se encuentran xlcd.h ( incluir: xlcd.c)
Posteriormente se habilita el puerto B en modo salida y el puerto A para controlar el LCD.
Hecho esto, se inicializa el LCD y se limpia pantalla. Se indica que posición tomará cada línea
del mensaje.

INICIO

LLAMADO DE X
LIBRERIAS

CONFIGURACION lcd_posicion linea 1(0x00)


DEL PROGRAMA mensaje:FIEE-2020A

habilitar PORTB=0 lcd_posicion linea 2(0x20)


PORTA =0 mensaje:MICROCONTROLADORES

xlcd_inicializa
xllcd _limpiar
FIN

Dr. Jacob Astocondor Villar 13


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

4. Desarrollo del programa (Código. )

A continuación se presenta el código del programa del ejemplo 1, donde el color azul
representa palabras reservadas, identificadores o tipos de datos.
El verde indica que son comentarios que definen el uso de cada sentencia. Y el color negro son
los bloques de código.

La simulación se llevó a cabo en proteus, donde observa que el resultado


corresponde a lo planteado con anterioridad.

5. Diagrama circuital.
En la Fig.2 se muestra el diagrama del circuito a implementar. En el se puede
Observar la conexión del dsPIC33FJMC202 donde el pin 1 está conectada al circuito RESET.
Del pin 2, 3 y 12 a los pines de control del LCD (RW, RS, E) y los Pines RB0, RB1, RB3 y
RB3 van conectados a los pines D4-D7 del LCD.

Los pines D0 al D3 del LCD deberán estar conectados a GND para no ocasionar conflicto con
los pines de datos que si están siendo utilizados.

El oscilador de cristal con sus respetivos capacitores se posiciona en los pines 9 y 10. Además
que es importante mantener alimentado todo el DSPIC para su correcto

6. Funcionamiento en proteus.

Ensamblaje y prueba.

Dr. Jacob Astocondor Villar 14


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

LCD1
LM016L

VDD
VEE

VSS
RW
RS
D7
D6
D5
D4
D3
D2
D1
D0

E
14
13
12
11
10
9
8
7

6
5
4

3
2
1
R1 U1
10k
1 4
MCLR RB0/CN4/RP0/AN2/EMUD1/PGD1
20 5
VDDCORE RB1/CN5/RP1/AN3/EMUC1/PGC1
6
RB2/CN6/RP2/AN4
7
RB3/CN7/RP3/AN5
11
RB4/CN1/RP4/SOSCI/EMUD3/PGD3
14
RB5/CN27/RP5/ASDA1
28 15
AVDD RB6/CN24/RP6/ASCL1
27 16
AVSS RB7/CN23/RP7/INT0
17
RB8/CN22/RP8/SCL1/PWM2H1/TCK
18
RB9/CN21/RP9/SDA1/PWM2L1/TDO
21
RB10/CN16/RP10/PWM1H3/TDI
2 22
RA0/CN2/VREF+/AN0/EMUD2/PGD2RB11/CN15/RP11/PWM1L3/TMS
3 23
RA1/CN3/VREF-/AN1/EMUC2/PGC2 RB12/CN14/RP12/PWM1H2
9 24
RA2/CN30/CLKI/OSCI RB13/CN13/RP13/PWM1L2
10 25
1

RA3/CN29/CLKO/OSCO RB14/CN12/RP14/PWM1H1
12 26
RA4/CN0/T1CK/SOSCO/EMUC3/PGC3 RB15/CN11/RP15/PWM1L1
X1
CRYSTAL DSPIC33FJ12MC202

RV1
2

1k

38%
Finalmente se demostró que el programa junto con el diseño del circuito, funciona
correctamente.

Conclusiones
Recomendaciones

GRACIAS

Dr. Jacob Astocondor Villar 15


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

ARCHIVOS DEL MODULO LCD

////**************************************xlcd.h************************************************

#ifndef XLCD_H
#define XLCD_H

/* DATA_PORT defines the port to which the LCD data lines are connected */
//#define WRITE_DATA_PORT PORTD
//#define READ_DATA_PORT PORTD
#define DATA_PORT PORTB
#define TRIS_DATA_PORT TRISB

/* CTRL_PORT defines the port where the control lines are connected.
* These are just samples, change to match your application.
*/
#define RW_PIN LATAbits.LATA0 /* PORT for RW */
#define TRIS_RW TRISAbits.TRISA0 /* TRIS for RW */
#define RS_PIN LATAbits.LATA1 /* PORT for RS */
#define TRIS_RS TRISAbits.TRISA1/* TRIS for RS */
#define E_PIN LATAbits.LATA4 /* PORT for E */
#define TRIS_E TRISAbits.TRISA4 /* TRIS for E */

//#define PWR_PIN PORTDbits.RD7 /* PORT for PWR */


//#define TRIS_PWR DDRDbits.RD7 /* TRIS for PWR */

/* Display ON/OFF Control defines */


#define DON 0b00001111 /* Display on */
#define DOFF 0b00001011 /* Display off */
#define CURSOR_ON 0b00001111 /* Cursor on */
#define CURSOR_OFF 0b00001101 /* Cursor off */
#define BLINK_ON 0b00001111 /* Cursor Blink */
#define BLINK_OFF 0b00001110 /* Cursor No Blink */

/* Some Command Type defines */


#define CLEAR_XLCD 0x01 /* Clears the LCD */
#define RETURN_CURSOR_HOME 0x02 /* Returns the cursor to the HOME
position */

/* Cursor or Display Shift defines */


#define SHIFT_CUR_LEFT 0b00010011 /* Cursor shifts to the left */
#define SHIFT_CUR_RIGHT 0b00010111 /* Cursor shifts to the right */
#define SHIFT_DISP_LEFT 0b00011011 /* Display shifts to the left */
#define SHIFT_DISP_RIGHT 0b00011111 /* Display shifts to the right */

/* Function Set defines */


#define FOUR_BIT 0b00101111 /* 4-bit Interface */
#define EIGHT_BIT 0b00111111 /* 8-bit Interface */
#define LINE_5X7 0b00110011 /* 5x7 characters, single line */
#define LINE_5X10 0b00110111 /* 5x10 characters */
#define LINES_5X7 0b00111011 /* 5x7 characters, multiple line */
/* LINES*/
#define DDRAM_LINE1 0b10000000 /* 4-bit Interface */
#define DDRAM_LINE2 0b11000000 /* 4-bit Interface */
#define CGRAM_ADDRESS 0b01000000 /* 4-bit Interface */
void XLCDInit(void);
void XLCDgotoXY(int x,int y);
void XLCD_WriteChr_CGRAM( const char *buffer, unsigned char Addres);

Dr. Jacob Astocondor Villar 16


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

/* OpenXLCD
* Configures I/O pins for external LCD
*/
void OpenXLCD(unsigned char lcdtype);

/* SetCGRamAddr
* Sets the character generator address
*/
void SetCGRamAddr(unsigned char);

/* SetDDRamAddr
* Sets the display data address
*/
void SetDDRamAddr(unsigned char);

/* BusyXLCD
* Returns the busy status of the LCD
*/
unsigned char BusyXLCD(void);

/* ReadAddrXLCD
* Reads the current address
*/
unsigned char ReadAddrXLCD(void);

/* ReadDataXLCD
* Reads a byte of data
*/
char ReadDataXLCD(void);

/* WriteCmdXLCD
* Writes a command to the LCD
*/
void WriteCmdXLCD(unsigned char cmd);

/* WriteDataXLCD
* Writes a data byte to the LCD
*/
void WriteDataXLCD(char);

/* putcXLCD
* A putc is a write
*/
#define putcXLCD WriteDataXLCD

/* putsXLCD
* Writes a string of characters to the LCD
*/
void putsXLCD(char *);

/* putrsXLCD
* Writes a string of characters in ROM to the LCD
*/
void putrsXLCD(const char *buffer);

/* User defines these routines according to the oscillator frequency */


//extern void DelayFor18TCY(void); // 1us delay
//extern void DelayPORXLCD(void); // 15ms delay

Dr. Jacob Astocondor Villar 17


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

//extern void DelayXLCD(void); // 4.1ms

extern void Delay_1us(void); // 1us delay


extern void DelayPORXLCD(void); // 15ms delay
extern void DelayXLCD(void); // 4.1ms
extern void DelayExecution(void);

#endif /* XLCD_H */

//*********************************ARCHIVO xlcd.c*************************************************

#include <xc.h>
#include "reloj.h"
#include <libpic30.h>
#include "xlcd.h"
void Delay_1us( void )
{
__delay_us(1);
return;
}
/* Provide at least a 15ms delay */
void DelayPORXLCD( void )
{
__delay_ms(200);
return;
}
/* Provide at least a 5ms delay */
void DelayXLCD( void )
{
__delay_ms(5);
return;
}

void DelayExecution( void )


{
__delay_us(50); // 46us to Read/Write data operation
return;
}
// Fila columna
//void XLCDgotoXY( int x , int y)
void XLCDgotoXY(int x,int y)
{
if ( x>0 ){WriteCmdXLCD(DDRAM_LINE2+y);}
else {WriteCmdXLCD(DDRAM_LINE1+y);}
return;
}

void XLCDInit(void)
{ unsigned char i;
/* ----------------------------- Inicializacion del LCD 2x16 --------------------------------------------------*/
DelayPORXLCD(); // retardo incial para que la tension de alimentacion se
estabilice
OpenXLCD( FOUR_BIT & LINES_5X7); // Initialize LCD
DelayXLCD(); // Retardo de por lo menos 4.1 ms
WriteCmdXLCD( DON & CURSOR_OFF & BLINK_OFF ); // Set parameters
DelayXLCD(); // Retardo de por lo menos 4.1 ms

Dr. Jacob Astocondor Villar 18


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

WriteCmdXLCD(CLEAR_XLCD);
DelayXLCD(); // Retardo de por lo menos 4.1 ms
WriteCmdXLCD(0x80); // Escribe el comando para poner el cursor a una
dirección en la memoria DDRAM
DelayXLCD(); // Retardo de por lo menos 4.1 ms
}
void XLCD_WriteChr_CGRAM( const char *buffer, unsigned char Addres)
{ unsigned char i=0;
SetCGRamAddr(Addres*8);
for (i=0;i<8;i++) // Write data to LCD up to null
{ WriteDataXLCD(*buffer); // Write character to LCD
++buffer;
}
}
void OpenXLCD(unsigned char lcdtype)
{
//TRIS_PWR = 0; // PWR control pin made output
//PWR_PIN = 1; // Power LCD
DelayPORXLCD(); // Delay 15ms

// The data bits must be either a 8-bit port or the upper or


// lower 4-bits of a port. These pins are made into inputs
#ifdef BIT8 // 8-bit mode, use whole port
DATA_PORT = 0;
TRIS_DATA_PORT = 0xff;
#else // 4-bit mode
#ifdef UPPER // Upper 4-bits of the port
DATA_PORT &= 0x0f;
TRIS_DATA_PORT |= 0xf0;
#else // Lower 4-bits of the port
DATA_PORT &= 0xf0;
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
TRIS_RW = 0; // All control signals made outputs
TRIS_RS = 0;
TRIS_E = 0;
RW_PIN = 0; // R/W pin made low
RS_PIN = 0; // Register select pin made low
E_PIN = 0; // Clock pin made low

// Delay for 15ms to allow for LCD Power on reset


DelayPORXLCD();

// Setup interface to LCD


#ifdef BIT8 // 8-bit mode interface
TRIS_DATA_PORT = 0; // Data port output
DATA_PORT = 0b00110000; // Function set cmd(8-bit interface)
#else // 4-bit mode interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= 0b00100000; // Function set cmd(4-bit interface)
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= 0b00000010; // Function set cmd(4-bit interface)
#endif

Dr. Jacob Astocondor Villar 19


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

#endif
E_PIN = 1; // Clock the cmd in
Delay_1us();
E_PIN = 0;

// Delay for at least 4.1ms


DelayXLCD();

// Setup interface to LCD


#ifdef BIT8 // 8-bit interface
DATA_PORT = 0b00110000; // Function set cmd(8-bit interface)
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00100000;
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00000010;
#endif
#endif
E_PIN = 1; // Clock the cmd in
Delay_1us();
E_PIN = 0;

// Delay for at least 100us


DelayXLCD();

// Setup interface to LCD


#ifdef BIT8 // 8-bit interface
DATA_PORT = 0b00110000; // Function set cmd(8-bit interface)
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00100000;
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00000010;
#endif
#endif
E_PIN = 1; // Clock cmd in
Delay_1us();
E_PIN = 0;

#ifdef BIT8 // 8-bit interface


TRIS_DATA_PORT = 0xff; // Make data port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make data nibble input
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make data nibble input
#endif
#endif

// Set data interface width, # lines, font


while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(lcdtype); // Function set cmd

// Turn the display on then off

Dr. Jacob Astocondor Villar 20


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

while(BusyXLCD()); // Wait if LCD busy


WriteCmdXLCD(DOFF&CURSOR_OFF&BLINK_OFF); // Display OFF/Blink OFF
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(DON&CURSOR_ON&BLINK_ON); // Display ON/Blink ON

// Clear display
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(0x01); // Clear display

// Set entry mode inc, no shift


while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(SHIFT_CUR_LEFT); // Entry Mode

// Set DD Ram address to 0


while(BusyXLCD()); // Wait if LCD busy
SetDDRamAddr(0); // Set Display data ram address to 0

return;
}

void SetCGRamAddr(unsigned char CGaddr)


{
while(BusyXLCD());
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make data port ouput
DATA_PORT = CGaddr | 0b01000000; // Write cmd and address to port
RW_PIN = 0; // Set control signals
RS_PIN = 0;
Delay_1us();
E_PIN = 1; // Clock cmd and address in
Delay_1us();
E_PIN = 0;
Delay_1us();
TRIS_DATA_PORT = 0xff; // Make data port inputs
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make nibble input
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((CGaddr | 0b01000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make nibble input
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((CGaddr | 0b01000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control signals
RS_PIN = 0;
Delay_1us();
E_PIN = 1; // Clock cmd and address in
Delay_1us();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((CGaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (CGaddr&0x0f);

Dr. Jacob Astocondor Villar 21


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

#endif
Delay_1us();
E_PIN = 1; // Clock cmd and address in
Delay_1us();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make inputs
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make inputs
#endif
#endif
return;
}

void SetDDRamAddr(unsigned char DDaddr)


{
while(BusyXLCD());
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = DDaddr | 0b10000000; // Write cmd and address to port
RW_PIN = 0; // Set the control bits
RS_PIN = 0;
Delay_1us();
E_PIN = 1; // Clock the cmd and address in
Delay_1us();
E_PIN = 0;
Delay_1us();
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make port output
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((DDaddr | 0b10000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make port output
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((DDaddr | 0b10000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control bits
RS_PIN = 0;
Delay_1us();
E_PIN = 1; // Clock the cmd and address in
Delay_1us();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((DDaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (DDaddr&0x0f);
#endif
Delay_1us();
E_PIN = 1; // Clock the cmd and address in
Delay_1us();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface

Dr. Jacob Astocondor Villar 22


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

TRIS_DATA_PORT |= 0xf0; // Make port input


#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make port input
#endif
#endif
return;
}

unsigned char BusyXLCD(void)


{
RW_PIN = 1; // Set the control bits for read
RS_PIN = 0;
Delay_1us();
E_PIN = 1; // Clock in the command
Delay_1us();
#ifdef BIT8 // 8-bit interface
if(DATA_PORT&0x80) // Read bit 7 (busy bit)
{ // If high
E_PIN = 0; // Reset clock line
RW_PIN = 0; // Reset control line
return 1; // Return TRUE
}
else // Bit 7 low
{
E_PIN = 0; // Reset clock line
RW_PIN = 0; // Reset control line
return 0; // Return FALSE
}
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
if( DATA_PORT & 0x80 )
#else // Lower nibble interface
if( DATA_PORT & 0x08 )
#endif
{
E_PIN = 0; // Reset clock line
Delay_1us();
E_PIN = 1; // Clock out other nibble
Delay_1us();
E_PIN = 0;
RW_PIN = 0; // Reset control line
return 1; // Return TRUE
}
else // Busy bit is low
{
E_PIN = 0; // Reset clock line
Delay_1us();
E_PIN = 1; // Clock out other nibble
Delay_1us();
E_PIN = 0;
RW_PIN = 0; // Reset control line
return 0; // Return FALSE
}
#endif
}

unsigned char ReadAddrXLCD(void)


{

Dr. Jacob Astocondor Villar 23


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

char data; // Holds the data retrieved from the LCD


while(BusyXLCD());

#ifdef BIT8 // 8-bit interface


RW_PIN = 1; // Set control bits for the read
RS_PIN = 0;
Delay_1us();
E_PIN = 1; // Clock data out of the LCD controller
Delay_1us();
data = DATA_PORT; // Save the data in the register
E_PIN = 0;
RW_PIN = 0; // Reset the control bits
#else // 4-bit interface
RW_PIN = 1; // Set control bits for the read
RS_PIN = 0;
Delay_1us();
E_PIN = 1; // Clock data out of the LCD controller
Delay_1us();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the nibble into the upper nibble of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // Read the nibble into the upper nibble of data
#endif
E_PIN = 0; // Reset the clock
Delay_1us();
E_PIN = 1; // Clock out the lower nibble
Delay_1us();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the nibble into the lower nibble of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the nibble into the lower nibble of data
#endif
E_PIN = 0;
RW_PIN = 0; // Reset the control lines
#endif
return (data&0x7f); // Return the address, Mask off the busy bit
}

char ReadDataXLCD(void)
{
char data;

while(BusyXLCD());
#ifdef BIT8 // 8-bit interface
RS_PIN = 1; // Set the control bits
RW_PIN = 1;
Delay_1us();
E_PIN = 1; // Clock the data out of the LCD
Delay_1us();
data = DATA_PORT; // Read the data
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#else // 4-bit interface
RW_PIN = 1;
RS_PIN = 1;
Delay_1us();
E_PIN = 1; // Clock the data out of the LCD

Dr. Jacob Astocondor Villar 24


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

Delay_1us();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the upper nibble of data
#else // Lower nibble interface

data = (DATA_PORT<<4)&0xf0; // read the upper nibble of data


#endif
E_PIN = 0; // Reset the clock line
Delay_1us();
E_PIN = 1; // Clock the next nibble out of the LCD
Delay_1us();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the lower nibble of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the lower nibble of data
#endif
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#endif
return(data); // Return the data byte
}

void WriteCmdXLCD(unsigned char cmd)


{
while(BusyXLCD());
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Data port output
DATA_PORT = cmd; // Write command to data port
RW_PIN = 0; // Set the control signals
RS_PIN = 0; // for sending a command
Delay_1us();
E_PIN = 1; // Clock the command in
Delay_1us();
E_PIN = 0;
Delay_1us();
TRIS_DATA_PORT = 0xff; // Data port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= cmd&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= (cmd>>4)&0x0f;
#endif
RW_PIN = 0; // Set control signals for command
RS_PIN = 0;
Delay_1us();
E_PIN = 1; // Clock command in
Delay_1us();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= (cmd<<4)&0xf0;
#else // Lower nibble interface
DATA_PORT &= 0xf0;

Dr. Jacob Astocondor Villar 25


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

DATA_PORT |= cmd&0x0f;
#endif
Delay_1us();
E_PIN = 1; // Clock command in
Delay_1us();
E_PIN = 0;
#ifdef UPPER // Make data nibble input
TRIS_DATA_PORT |= 0xf0;
#else
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}

void WriteDataXLCD(char data)


{
while(BusyXLCD());
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = data; // Write data to port
RS_PIN = 1; // Set control bits
RW_PIN = 0;
Delay_1us();
E_PIN = 1; // Clock data into LCD
Delay_1us();
E_PIN = 0;
RS_PIN = 0; // Reset control bits
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= data&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= ((data>>4)&0x0f);
#endif
RS_PIN = 1; // Set control bits
RW_PIN = 0;
Delay_1us();
E_PIN = 1; // Clock nibble into LCD
Delay_1us();
E_PIN = 0;
Delay_1us();

#ifdef UPPER // Upper nibble interface


DATA_PORT &= 0x0f;
DATA_PORT |= ((data<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= (data&0x0f);
#endif
Delay_1us();
E_PIN = 1; // Clock nibble into LCD
Delay_1us();
E_PIN = 0;

Dr. Jacob Astocondor Villar 26


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

#ifdef UPPER // Upper nibble interface


TRIS_DATA_PORT |= 0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}

void putsXLCD(char *buffer)


{
while(*buffer) // Write data to LCD up to null
{
//while(BusyXLCD()); // Wait while LCD is busy
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
}
return;
}

void putrsXLCD(const char *buffer)


{
while(*buffer) // Write data to LCD up to null
{
//while(BusyXLCD()); // Wait while LCD is busy
//DelayExecution();
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
}
return;
}

Archivos adicionales:
//**************config1.h**************************************

// DSPIC33FJ12MC202 Configuration Bit Settings

// 'C' source line config statements

// FBS
#pragma config BWRP = WRPROTECT_OFF // Boot Segment Write Protect (Boot Segment
may be written)
#pragma config BSS = NO_FLASH // Boot Segment Program Flash Code Protection (No
Boot program Flash segment)

// FGS
#pragma config GWRP = OFF // General Code Segment Write Protect (User program
memory is not write-protected)
#pragma config GSS = OFF // General Segment Code Protection (User program
memory is not code-protected)

// FOSCSEL
#pragma config FNOSC = PRI // Oscillator Mode (Primary Oscillator (XT, HS, EC))
#pragma config IESO = ON // Internal External Switch Over Mode (Start-up device
with FRC, then automatically switch to user-selected oscillator source when ready)

Dr. Jacob Astocondor Villar 27


UNIVERSIDAD NACIONAL DEL CALLAO
FACULTAD DE INGENIERIA ELECTRICA Y ELECTRONICA
ASIGNATURA. MICROCONTROLADORES Y SISTEMAS EMBEBIDOS 2020B

// FOSC
#pragma config POSCMD = XT // Primary Oscillator Source (XT Oscillator Mode)
#pragma config OSCIOFNC = OFF // OSC2 Pin Function (OSC2 pin has clock out
function)
#pragma config IOL1WAY = ON // Peripheral Pin Select Configuration (Allow Only One
Re-configuration)
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor (Both Clock
Switching and Fail-Safe Clock Monitor are disabled)

// FWDT
#pragma config WDTPOST = PS32768 // Watchdog Timer Postscaler (1:32,768)
#pragma config WDTPRE = PR128 // WDT Prescaler (1:128)
#pragma config WINDIS = OFF // Watchdog Timer Window (Watchdog Timer in Non-
Window mode)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (Watchdog timer
enabled/disabled by user software)

// FPOR
#pragma config FPWRT = PWR128 // POR Timer Value (128ms)
#pragma config ALTI2C = OFF // Alternate I2C pins (I2C mapped to SDA1/SCL1 pins)
#pragma config LPOL = ON // Motor Control PWM Low Side Polarity bit (PWM module
low side output pins have active-high output polarity)
#pragma config HPOL = ON // Motor Control PWM High Side Polarity bit (PWM
module high side output pins have active-high output polarity)
#pragma config PWMPIN = ON // Motor Control PWM Module Pin Mode bit (PWM
module pins controlled by PORT register at device Reset)

// FICD
#pragma config ICS = PGD1 // Comm Channel Select (Communicate on
PGC1/EMUC1 and PGD1/EMUD1)
#pragma config JTAGEN = OFF // JTAG Port Enable (JTAG is Disabled)

// #pragma config statements should precede project file includes.


// Use project enums instead of #define for ON and OFF.

#include <xc.h>

//*******************reloj.h******************************
define FCY 4000000
#define BAUDRATE 9600
#define BRGVAL ((FCY/BAUDRATE)/16)-1

Dr. Jacob Astocondor Villar 28

También podría gustarte