Librería LCD para Microcontroladores
Librería LCD para Microcontroladores
Facultad de Ingeniería
Estudiante
Adair Téllez Aviles
Expediente
298497
Maestros:
Dr. Luis Alberto Morales Velázquez
M.C. Leonardo Esteban Moreno Suárez
Materia: Microcontroladores
Practica 4: LCD
Fecha: 14-03-2024
Microcontroladores
Objetivo
Crear la librería con las funciones necesarias para la pantalla LCD mediante el uso de pines de propósito
general y hojas de datos del dispositivo para mostrar cadenas de datos y caracteres especiales.
Introducción
Una pantalla de cristal líquido o LCD (siglas en inglés liquid cristal display) es una pantalla delgada y plana
formada por un número de píxeles en color o monocromos colocados delante de una fuente de luz reflectora.
A menudo se utiliza en dispositivos electrónicos de pilas, ya que utiliza cantidades muy pequeñas de energía
eléctrica. Para configurar en aplicación de microcontroladores y electrónica digital. La pantalla de cristal
líquido o LCD (Liquid Crystal Display) es un dispositivo controlado de visualización grafico para la
presentación de caracteres, símbolos o incluso dibujos (en algunos modelos, es este caso dispone de 2 filas
de 16 caracteres cada una y cada carácter dispone de una matriz de 5x7 puntos (pixeles), aunque los hay
de otro número de filas y caracteres. Este dispositivo está gobernado internamente por un microcontrolador
y regula todos los parámetros de presentación, este modelo es el más comúnmente usado y esta
información se basará en el manejo de este u otro LCD compatible de uso común en proyectos de
electrónica, utiliza una interfaz paralela. La pantalla requiere 11 pines de entrada/salida para mostrar el
mensaje. Muy utilizada con microcontroladores PIC y Arduino [1].
El timer es un objeto que tiene como funcionalidad ejecutar una función o bloque de código cada cierto
tiempo. Esto tiene muchas aplicaciones ya que no depende de la acción por parte de usuario para ejecutar
cierto código [2].
Metodología
Descarga Búsqueda Seleccionar Definir Generar Realizar
Lectura Realizar código
de la hoja de del de los pines a entrada y nuevo conexiones
datos del de la hoja correspon-
de datos registro(s) utilizar. salida según documento físicas
LCD. diente.
a utilizar. la elección “.c”
La Figura 1, nos muestra el proceso que se llevara a cabo de forma general, para la implementación de la
LCD, de manera física.
Microcontroladores
Inicio
Función set
Esperar 4.1
ms
Función set
Esperar 100
us
Función set
Display off
Display clear
Entry modo set
En la Figura 2, se muestran los comandos que se tienen que utilizar y el tiempo de cada uno de ellos, cabe
señalar que si se da un tiempo mayor solo tardara más en inicializar la LCD, por ello, se deben de respetar
los tiempos, para que así se tenga un resultado casi de manera instantánea.
Inicio
Declaración de macros
Definir
preescalador
Función set
Encender
LCD
Mostrar caracteres
Para iniciar, el primer paso, es la lectura de la hoja de datos de la LCD 16x2, donde se muestran diferentes
puntos relevantes de la LCD, como lo es los tiempos de inicialización, los modos de la LCD (4 y 8 bits),
caracteres especiales, entre otros, para ello, el primer punto relevante es el número de pines que se
utilizaran para la librería, donde se observa que se utiliza de DB0-DB7, E y RS, por lo que se requiere de 9
pines para la LCD, como máximo, pues esto se considera para 8 bits.
Lo siguiente es crear una función de comandos para el modo de 8, para la cual, se siguen los siguientes
puntos:
Apagar RS y E.
Encendido de la variable utilizada por el usuario.
Encendido de E.
Delay.
Apagado de E.
Apagado de la variable utilizada por el usuario.
Microcontroladores
Posteriormente, se crea la función de caracteres para el modo de 8 bits, por lo cual se siguen los siguientes
puntos:
Encender RS.
Apagar E.
Encendido de la variable utilizada por el usuario.
Encendido de E.
Delay.
Apagado de E.
Apagado de la variable utilizada por el usuario.
Por ultimo para el modo de 8 bits, se realiza la inicialización de la LCD, por lo que se siguen los siguientes
puntos.
Delay.
Enviar a DB1 y DB2, como comando
Delay.
Enviar a DB1 y DB2, como comando.
Delay.
Enviar a DB1 y DB2, como comando.
Delay.
Enviar a DB5, DB4 y DB3, como comando.
Delay
Enviar a DB3, como comando.
Delay
Enviar a DB0, como comando.
Delay
Enviar a DB1 y DB2, como comando.
Delay
Enviar a DB3, DB2 y DB1, como comando.
Seguido de ello, se realizan las modificaciones correspondientes para el modo de 4 bits, para este caso,
solo se utiliza de DB4-DB7, los cuales son los bits más significativos, para los comandos, se siguen los
siguientes puntos:
Apagar RS y E.
GPIOA->ODR=(k&0xF0)|(GPIOA->ODR&0xFF0F); Concatenacion de los datos y cuidado de los
mismo
Encendido de E.
Delay.
Apagado de E.
GPIOA->ODR=(k<<4&0xF0)|(GPIOA->ODR&0xFF0F); realización de un corrimiento hacia la
izquierda, para utilizar de DB4-DB7.
Encendido de E.
Delay.
Microcontroladores
Apagado de E.
Posteriormente, se crea la función de caracteres para el modo de 4 bits, por lo cual se siguen los siguientes
puntos:
Apagar E.
Encender RS.
GPIOA->ODR=(k&0xF0)|(GPIOA->ODR&0xFF0F); Concatenacion de los datos y cuidado de los
mismo
Encendido de E.
Delay.
Apagado de E.
GPIOA->ODR=(k<<4&0xF0)|(GPIOA->ODR&0xFF0F); realización de un corrimiento hacia la
izquierda, para utilizar de DB4-DB7.
Encendido de E.
Delay.
Apagado de E.
Por ultimo para el modo de 4 bits, se realiza la inicialización de la LCD, por lo que se siguen los siguientes
puntos.
Enviar a DB4 y DB5, como comando
Delay.
Enviar a DB4 y DB5, como comando.
Delay.
Enviar a DB4 y DB5, como comando.
Delay.
Enviar a 0x28, como comando.
Delay
Enviar a 0x28, como comando.
Delay
Enviar a DB7 y DB6, como comando.
Delay
Enviar a DB4, como comando.
Delay
Enviar a DB6 y DB5, como comando.
Microcontroladores
Seguido de ello, se realiza un ciclo if else, para elegir el modo a utilizar, para ello, se da un valor de 0,
cuando es un modo de bits y 1 cuando es modo de 4 bits.
Posteriormente, se realiza la creación de los caracteres especiales, donde para ello, se puede apoyar de
una página de internet o realizarlo manualmente, para ello, se sabe que se tiene una matriz de 8x5, lo cual
son 8 renglones y 5 columnas, en la Figura 4, se muestra un ejemplo de un carácter especial.
Tras el haber seleccionado las secciones que se requiere iluminar, se mostraran los números hexadecimales
para crear el carácter.
Seguido de ello, se realiza un ciclo for, para mostrar los caracteres especiales. De la hoja de datos, se
recuperó que no se pueden almacenar más de 7 caracteres especiales. El siguiente fragmento del código,
es el utilizado para los caracteres especiales, recordando que se deben de sumar 8 para cada carácter,
pues si no se hace así, se sobrescribirán los caracteres
int j;
comd(0x40+8);
for(j=0; j<8; j++)
caract(etilde[j]);
Finalmente, se muestran las letras y caracteres utilizando la función de caracteres, cuando se muestra una
letra y ambas funciones, cuando se muestran caracteres especiales.
Microcontroladores
Resultados
En la Figura 5, se muestra la simulación implementada en el microcontrolador STM3F103C8T6.
Conclusión
Tras la finalización de la presente práctica, se utilizaron los conocimientos adquiridos dentro de la clase,
pues se utilizan Timers, para poder hacer los delays entre cada uno de los comandos que se mandan a la
LCD, pues para la inicialización de la LCD, se mandan diversos comandos para ello, mientras que se
observó que la LCD, solo puede procesar 7 caracteres especiales, además de que, para mandar los datos,
se tiene que colocar si es un carácter o un comando, pues esto es algo de importancia para poder mandar
caracteres a la misma.
Anexos
Anexo 1 código para STM3F103C8T6.
#include "LCD_COMUN.h"
#include "main.h"
int LCD=1;
#define RS 0x100
Microcontroladores
#define E 0x200
//PUERTO
#define puerto GPIOA
//------------
#define ON_DB0 (puerto->ODR|=DB0)//encendido DB0
#define ON_DB1 (puerto->ODR|=DB1)//encendido DB1
#define ON_DB2 (puerto->ODR|=DB2)//encendido DB2
#define ON_DB3 (puerto->ODR|=DB3)//encendido DB3
#define ON_DB4 (puerto->ODR|=DB4)//encendido DB4
#define ON_DB5 (puerto->ODR|=DB5)//encendido DB5
#define ON_DB6 (puerto->ODR|=DB6)//encendido DB6
#define ON_DB7 (puerto->ODR|=DB7)//encendido DB7
//------------
#define ON_RS (puerto->ODR|=RS)//encendido RS
#define ON_E (puerto->ODR|=E) //encendido E
}
else
{
OFF_RS; //apagado RS
OFF_E;
GPIOA->ODR=(k&0xF0)|(GPIOA->ODR&0xFF0F);//concatenacion de datos y cuidado
de datos
ON_E;
delay_timer(t);
OFF_E;
GPIOA->ODR=(k<<4&0xF0)|(GPIOA->ODR&0xFF0F);
ON_E;
delay_timer(t);
OFF_E;
}
}
void caract(char k)
{
if(LCD==0)//8 bits
{
ON_RS;
OFF_E;
puerto->ODR|=k;
ON_E;
delay_timer(t);;//envia pulso
OFF_E;
puerto->ODR&=~k;}
else{
OFF_E;
ON_RS;
GPIOA->ODR=(k&0xF0)|(GPIOA->ODR&0xFF0F);//concatenacion de datos y cuidado
de datos
ON_E;
delay_timer(t);
OFF_E;
Microcontroladores
GPIOA->ODR=(k<<4&0xF0)|(GPIOA->ODR&0xFF0F);
ON_E;
delay_timer(t);
OFF_E;
}
void inicializar(void)
{
RCC->APB1ENR|= RCC_APB1ENR_PWREN | RCC_APB1ENR_TIM2EN;//encendido del micro
RCC->APB2ENR|= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN |
RCC_APB2ENR_IOPCEN;//habilitacion de los puertos
puerto->CRL = 0x33333333;
puerto->CRH = 0x33;
puerto->ODR = 0x0;
if(LCD==0)//8 bits
{
//set modo
delay_timer(t);
comd(0x3);
delay_timer(t);
comd(0x3);
delay_timer(t);
comd(0x3);
delay_timer(t);
comd(0x38);//display on
delay_timer(t);
//set
comd(0x08);//lineas 5x8
delay_timer(t);
//show
comd(0x1);//display on
delay_timer(t);
comd(0x06);//display on
delay_timer(t);
//clear
comd(0x0e);//limpiar lcd
}
else {
comd(0x03);//
delay_timer(t);
comd(0x03);
delay_timer(t);
comd(0x03);
delay_timer(t);
comd(0x02);
Microcontroladores
delay_timer(t);
comd(0x28);//modo 4 bits
delay_timer(t);
comd(0x28);//seguro de configuración
delay_timer(t);
comd(0x0C);//on
delay_timer(t);
comd(0x01);//clear
delay_timer(t);
comd(0x06);//entry mode
}
}
/*
* P3_LCD.c
*
* Created on: Mar 5, 2024
* Author: adair
*/
//#include "main.h"
#include "LCD_COMUN.h"
#include "main.h"
int j;
comd(0x40+8);
for(j=0; j<8; j++)
caract(etilde[j]);//e con tilde
comd(0x40+16);
for(j=0; j<8; j++)
caract(I[j]);//
Microcontroladores
comd(0x40+24);
for(j=0; j<8; j++)
caract(II[j]);
comd(0x40+32);
for(j=0; j<8; j++)
caract(E[j]);
comd(0x40+40);
for(j=0; j<8; j++)
caract(M[j]);
comd(0x40+48);
for(j=0; j<8; j++)
caract(MM[j]);
comd(0x80);
caract('A');
caract('d');
caract('a');
caract('i');
caract('r');
comd(0x86);
caract('T');
caract(1);
caract('l');
caract('l');
caract('e');
caract('z');
comd(0xC0+3);//parte inferior
caract('A');
caract('v');
caract('i');
caract('l');
caract('e');
caract('s');
comd(0x80+12);
caract(2);
comd(0xC0+12);//parte inferior
caract(3);
comd(0x80+13);
caract(4);
comd(0xC0+13);//parte inferior
caract(4);
comd(0x80+14);
Microcontroladores
caract(5);
comd(0xC0+14);//parte inferior
caract(6);
comd(0x80+15);
caract(5);
comd(0xC0+15);//parte inferior
caract(6);
while(1)
{
/*
* LCD_COMUN.h
*
* Created on: Mar 5, 2024
* Author: adair
*/
#ifndef SRC_LCD_COMUN_H_
#define SRC_LCD_COMUN_H_
#include "main.h"
void inicializar(void);
void comd(char k);
void caract(char k);
#endif /* SRC_LCD_COMUN_H_ */
#define RS 0x1//PUERTO B
#define E 0x2 //PUERTO B
//PUERTO
#define puerto GPIOA
#define puerto2 GPIOC //PUERTO F
//------------
#define ON_DB0 (puerto->ODR|=DB0)//encendido DB0
#define ON_DB1 (puerto->ODR|=DB1)//encendido DB1
#define ON_DB2 (puerto->ODR|=DB2)//encendido DB2
#define ON_DB3 (puerto->ODR|=DB3)//encendido DB3
#define ON_DB4 (puerto->ODR|=DB4)//encendido DB4
#define ON_DB5 (puerto->ODR|=DB5)//encendido DB5
#define ON_DB6 (puerto->ODR|=DB6)//encendido DB6
#define ON_DB7 (puerto->ODR|=DB7)//encendido DB7
//------------
#define ON_RS (puerto2->ODR|=RS)//encendido RS
#define ON_E (puerto2->ODR|=E) //encendido E
TIM2->PSC= PRESCALER_VALUE-1;
TIM2->CR1 = TIM_CR1_ARPE | TIM_CR1_CEN; //0X81
while(!(TIM2->SR&TIM_SR_UIF));
TIM2->SR&=~TIM_SR_UIF;
}
}
else
{
OFF_RS; //apagado RS
OFF_E;
GPIOA->ODR=(k&0xF0)|(GPIOA->ODR&0xFF0F);//concatenacion de datos y cuidado
de datos
ON_E;
delay_timer(t);
OFF_E;
GPIOA->ODR=(k<<4&0xF0)|(GPIOA->ODR&0xFF0F);
ON_E;
delay_timer(t);
OFF_E;
}
}
void caract(char k)
{
if(LCD==0)//8 bits
{
ON_RS;
OFF_E;
puerto->ODR|=k;
ON_E;
delay_timer(t);;//envia pulso
OFF_E;
Microcontroladores
puerto->ODR&=~k;}
else{
OFF_E;
ON_RS;
GPIOA->ODR=(k&0xF0)|(GPIOA->ODR&0xFF0F);//concatenacion de datos y cuidado
de datos
ON_E;
delay_timer(t);
OFF_E;
GPIOA->ODR=(k<<4&0xF0)|(GPIOA->ODR&0xFF0F);
ON_E;
delay_timer(t);
OFF_E;
}
void inicializar(void)
{
RCC->AHB3ENR |= RCC_AHB3ENR_PWREN;
RCC->APB1ENR1 |= 0x01;
RCC->AHB2ENR1 |= RCC_AHB2ENR1_GPIOAEN | RCC_AHB2ENR1_GPIOBEN |
RCC_AHB2ENR1_GPIOCEN;
puerto->MODER &=~0xAAAA;
puerto2->MODER &=~ 0xAA;
puerto->ODR=0x0;
puerto2->ODR=0x0;
if(LCD==0)//8 bits
{
//set modo
delay_timer(t);
comd(DB1 | DB2); //39 us
delay_timer(t);
comd(DB1 | DB2); //39 us
delay_timer(t);
comd(DB1 | DB2); //39 us
delay_timer(t);
comd(DB5 | DB4 | DB3);//display on 0x38
delay_timer(t);
//set
comd(0x08);//lineas 5x8
delay_timer(t);
//show
comd(0x1);//display on
delay_timer(t);
comd(0x06);//display on
delay_timer(t);
Microcontroladores
//clear
comd(0x0e);//limpiar lcd
}
else {
comd(0x03);//
delay_timer(t);//5 ms
comd(0x03);
delay_timer(t);//120 us
comd(0x03);
delay_timer(t);//120us
comd(0x02);
delay_timer(t);
comd(0x28);//modo 4 bits
delay_timer(t);
comd(0x28);//seguro de configuración
delay_timer(t);//5 ms
comd(0x0C);//on
delay_timer(t);//120 us
comd(0x01);//clear
delay_timer(t); //2 ms
comd(0x06);//entry mode
}
}
/*
* P3_LCD.c
*
* Created on: Mar 5, 2024
* Author: adair
*/
//#include "main.h"
#include "LCD_ALTA.h"
#include "main.h"
int j;
Microcontroladores
comd(0x40+8);
for(j=0; j<8; j++)
caract(etilde[j]);//e con tilde
comd(0x40+16);
for(j=0; j<8; j++)
caract(I[j]);//
comd(0x40+24);
for(j=0; j<8; j++)
caract(E[j]);
comd(0x40+32);
for(j=0; j<8; j++)
caract(M[j]);
comd(0x40+40);
for(j=0; j<8; j++)
caract(MM[j]);
comd(0x40+48);
for(j=0; j<8; j++)
caract(MMM[j]);
comd(0x40+56);
for(j=0; j<8; j++)
caract(MMMM[j]);
comd(0x80);
caract('A');
caract('d');
caract('a');
caract('i');
caract('r');
comd(0x86);
caract('T');
caract(1);
caract('l');
caract('l');
caract('e');
caract('z');
comd(0xC0+3);//parte inferior
caract('A');
caract('v');
caract('i');
caract('l');
caract('e');
caract('s');
comd(0x80+12);
Microcontroladores
caract(2);
comd(0xC0+12);//parte inferior
caract(2);
comd(0x80+13);
caract(3);
comd(0xC0+13);//parte inferior
caract(3);
comd(0x80+14);
caract(4);
comd(0xC0+14);//parte inferior
caract(5);
comd(0x80+15);
caract(6);
comd(0xC0+15);//parte inferior
caract(7);
while(1)
{
/*
* LCD_ALTA.h
*
* Created on: Mar 7, 2024
* Author: adair
*/
#ifndef LCD_ALTA_H_
#define LCD_ALTA_H_
#include "main.h"
void inicializar(void);
void comd(char k);
void caract(char k);
#endif /* LCD_ALTA_H_ */
Bibliografía
[1] https://electronicathido.com/detallesProducto.php?id=dE5YQjJ5YXFjaCtaK0w0VlpjS2VKdz09
Microcontroladores