Beruflich Dokumente
Kultur Dokumente
Embarcados
26 de maio de 2014
Adilson Thomsen
Para ligarmos um display LCD 16×2 ao PIC, precisamos antes de mais nada saber como programar pic
e entender um pouco sobre a forma como esse tipo de display trabalha. Um dos tipos mais comuns de
controlador utilizados em displays LCD é o HD44780, que pode ser ligado ao microcontrolador usando-se 4
ou 8 os, e que vai determinar a velocidade de comunicação entre eles.
Não podemos simplesmente enviar dados à um LCD sem uma sequencia lógica. Antes de utilizá-lo, é
necessário o envio de comandos que preparam o display para receber caracteres. Vamos tomar como
exemplo o display LCD 16×2 com controlador HD44780, disponível aqui na FILIPEFLOP :
Esse tipo de display tem 16 pinos : 3 pinos de alimentação, 3 de controle, 8 de dados e 2 para acionar o
backlight (ou luz de fundo), que você pode ver em detalhes na imagem abaixo :
https://www.filipeflop.com/blog/display-lcd-16x2-pic-16f628a/ 1/8
12/12/2017 Ligando Display LCD 16x2 ao PIC 16F628A - FilipeFlop
O pino RS tem a função de mostrar ao display que tipo de dados estamos transmitindo. Em nível baixo (0),
os dados são tratados como comandos, e em nível alto (1), os dados são tratados como caracteres. O pino
R/W (Read/Write) é utilizado para determinar se estamos lendo ou transmitindo dados para o display. Já o
pino ENABLE é utilizado para determinar o início da transferência de dados entre o microcontrolador e o
display.
Os pinos de dados D0 a D7 formam o barramento de dados. O mais comum é utilizarmos apenas 4 pinos
para comunicação com o microcontrolador, mas nada impede que em aplicações mais elaboradas sejam
utilizados todos os 8 pinos. Essa é uma das funções do envio de comandos que preparam o display, pois é
nesse momento que determinamos se vamos usar 4 ou 8 pinos para comunicação.
No Arduino temos várias bibliotecas prontas que fazem todo esse trabalho pesado. No caso do PIC,
podemos agrupar os comandos também em um arquivo texto e criar uma biblioteca própria. Esse é o
método que vamos utilizar nesse post, contando com a ajuda das rotinas de comando do display
disponibilizadas no blog do Marcelo Maciel.
Para controle do display LCD 16×2 vamos utilizar o microcontrolador PIC16F628A, e o programa
desenvolvido para uso no software MPLab. Os detalhes para con guração e utilização do MPLab você
encontra no artigo Programando PIC16F628A para piscar um led, aqui mesmo no blog.
Crie no MPLab a estrutura básica do projeto, e na mesma pasta do projeto crie um arquivo texto com o
nome de lcd.h. Dentro desse arquivo, copie o seguinte código :
1 /***************************************************************************/
2 /* Rotinas para o LCD */
3 /***************************************************************************/
4
5 //Este é o bloco com as rotinas necessárias para manipular o LCD
6
7 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8 * Envio de "Nibble" para o LCD *
9 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10
11 //Esta rotina lê o "Nibble" inferior de uma variável e envia para o LCD.
12 void envia_nibble_lcd(int dado)
13 {
14 //Carrega as vias de dados (pinos) do LCD de acordo com o nibble lido
15 output_bit(lcd_db4, bit_test(dado,0)); //Carrega DB4 do LCD com o bit DADO<0>
16 output_bit(lcd_db5, bit_test(dado,1)); //Carrega DB5 do LCD com o bit DADO<1>
17 output_bit(lcd_db6, bit_test(dado,2)); //Carrega DB6 do LCD com o bit DADO<2>
18 output_bit(lcd_db7, bit_test(dado,3)); //Carrega DB7 do LCD com o bit DADO<3>
19
20 //Gera um pulso de enable
21 output_high(lcd_enable); // ENABLE = 1
22 delay_us(1); // Recomendado para estabilizar o LCD
23 output_low(lcd_enable); // ENABLE = 0
24 return; // Retorna ao ponto de chamada da função
25 }
26
27 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
28 * Envio de Byte para o LCD *
29 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
30
31 //Esta rotina irá enviar um dado ou um comando para o LCD conforme abaixo:
32 // ENDEREÇO = 0 -> a variável DADO será uma instrução
33 // ENDEREÇO = 1 -> a variável DADO será um caractere
34
35 void envia_byte_lcd(boolean endereco, int dado)
36 {
37 output_bit(lcd_rs,endereco); // Seta o bit RS para instrução ou caractere
38 delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD
39 output_low(lcd_enable); // Desativa a linha ENABLE
40 envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/comando
41 envia_nibble_lcd(dado & 0x0f); // Limpa a parte ALTA e envia a parte BAIXA do
42 // dado/comando
43 delay_us(40); // Aguarda 40us para estabilizar o LCD
44 return; // Retorna ao ponto de chamada da função
45 }
46
47
48 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
49 * Envio de caractere para o LCD *
50 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
51 // Esta rotina serve apenas como uma forma mais fácil de escrever um caractere
52 // no display. Ela pode ser eliminada e ao invés dela usaremos diretamente a
53 // função envia_byte_lcd(1,"<caractere a ser mostrado no LCD>"); ou
54 // envia_byte_lcd(1,<código do caractere a ser mostrado no LCD>);
55
56 void escreve_lcd(char c)
57 // envia caractere para o display
58 {
59 envia_byte_lcd(1,c);
60 }
61
62 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
63 * Função para limpar o LCD *
64 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
65 // Como esta operação pode ser muito utilizada, transformando-a em função
66 // faz com que o código compilado seja menor.
67
68 void limpa_lcd()
69 {
70 envia_byte_lcd(0,0x01); // Envia instrução para limpar o LCD
71 delay_ms(2); // Aguarda 2ms para estabilizar o LCD
72 return; // Retorna ao ponto de chamada da função
73 }
74
75 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
76 * Inicializa o LCD *
77 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
78
79 void inicializa_lcd()
80 {
81 output_low(lcd_db4); // Garante que o pino DB4 estão em 0 (low)
82 output_low(lcd_db5); // Garante que o pino DB5 estão em 0 (low)
83 output_low(lcd_db6); // Garante que o pino DB6 estão em 0 (low)
84 output_low(lcd_db7); // Garante que o pino DB7 estão em 0 (low)
https://www.filipeflop.com/blog/display-lcd-16x2-pic-16f628a/ 2/8
12/12/2017 Ligando Display LCD 16x2 ao PIC 16F628A - FilipeFlop
85 output_low(lcd_rs); // Garante que o pino RS estão em 0 (low)
86 output_low(lcd_enable); // Garante que o pino ENABLE estão em 0 (low)
87 delay_ms(15); // Aguarda 15ms para estabilizar o LCD
88 envia_nibble_lcd(0x03); // Envia comando para inicializar o display
89 delay_ms(5); // Aguarda 5ms para estabilizar o LCD
90 envia_nibble_lcd(0x03); // Envia comando para inicializar o display
91 delay_ms(5); // Aguarda 5ms para estabilizar o LCD
92 envia_nibble_lcd(0x03); // Envia comando para inicializar o display
93 delay_ms(5); // Aguarda 5ms para estabilizar o LCD
94 envia_nibble_lcd(0x02); // CURSOR HOME - Envia comando para zerar o
95 //contador de caracteres e retornar à posição
96 // inicial (0x80).
97 delay_ms(1); // Aguarda 1ms para estabilizar o LCD
98 envia_byte_lcd(0,0x28); // FUNCTION SET - Configura o LCD para 4 bits,
99 // 2 linhas, fonte 5X7.
100 envia_byte_lcd(0,0x0c); // DISPLAY CONTROL - Display ligado, sem cursor
101 limpa_lcd(); // Limpa o LCD
102 envia_byte_lcd(0,0x06); // ENTRY MODE SET - Desloca o cursor para a direita
103 return; // Retorna ao ponto de chamada da função
104 }
105
106 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
107 * Define inicio da escrita *
108 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
109 //Esta função foi adicionada e serve para se definir em que posição do
110 //LCD deseja-se iniciar a escrita. Para isto basta chamar a Função
111 //"caracter_Inicio()" indicando a linha e a coluna onde o cursor será
112 // posicionado antes de se mandar escrever
113
114 void caracter_inicio(int linha, int coluna)//define a posicão de inicio da frase
115 {
116 int16 posicao=0;
117 if(linha == 1)
118 {
119 posicao=0x80; //Se setado linha 1, end incial 0x80
120 }
121 if(linha == 2)
122 {
123 posicao=0xc0; //Se setado linha 2, end incial 0xc0
124 }
125
126 posicao=posicao+coluna; //soma ao end inicial, o numero da coluna
127 posicao--; //subtrai 1 para corrigir posição
128
129 envia_byte_lcd(0,posicao);
130 return;
131 }
132 /***************************************************************************/
133 /* Final das rotinas para o LCD */
134 /***************************************************************************/
No MPLab, coloque o código abaixo, que chama as rotinas contidas no arquivo lcd.h para inicializar o
display, apagar a tela, enviar caracteres, etc. No circuito vamos usar um cristal de 16Mhz, mas você pode
utilizar, por exemplo um de 20Mhz. Para isso, altere a linha com o comando #use delay(clock=16000000) no
início do programa:
https://www.filipeflop.com/blog/display-lcd-16x2-pic-16f628a/ 3/8
12/12/2017 Ligando Display LCD 16x2 ao PIC 16F628A - FilipeFlop
//Definição de entradas e saídas
//Cada bit representa um pino físico de I/O
// 0 significa que o pino será uma saída
// 1 significa que o pino será uma entrada
#define trisa 0b00000000
#define trisb 0b00000000
//Programa principal
void main(){
while(1){
//limpa_lcd(); //Limpa o display do LCD
caracter_inicio(2,6);
printf(escreve_lcd," ");
delay_ms(500);
caracter_inicio(1,4); //Define o caracter de inicio da escrita
printf(escreve_lcd,"FILIPEFLOP"); //Escreve no LCD
delay_ms(2000);
caracter_inicio(1,4);
printf(escreve_lcd," ");
delay_ms(500);
caracter_inicio(2,6);
printf(escreve_lcd,"P I C");
delay_ms(2000);
}
} //fecha void main
Grave o programa utilizando o software MicroBRN, ou outro de sua preferência, e teste o microcontrolador
ligando-o ao display seguindo a tabela e circuito mostrados abaixo :
Além disso, ligue o pino 5 do PIC ao GND e o pino 14 ao 5v. O cristal deve ser ligado aos pinos 15 e 16 do
PIC.
Gostou ? Ajude-nos a melhorar o blog atribuindo uma nota aos posts (estrelas no início ou no nal
do artigo) e visite nossa loja FILIPEFLOP !
https://www.filipeflop.com/blog/display-lcd-16x2-pic-16f628a/ 4/8
12/12/2017 Ligando Display LCD 16x2 ao PIC 16F628A - FilipeFlop
Posts Relacionados
Adilson Thomsen
Conectar com:
O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *
Comentário
Nome * E-mail *
Site
Publicar comentário
19 Comentários
Ola amigo bom noite. será que teria como você me enviar por e-mail o arquivo deste programa. pois não
consegui fazer.
Estou precisando pois quero fazer um robo e pretendo usar o pic16f628a e um display 16×2.
att: Mateus
Essa biblioteca possibilita, assim como outras, um comando para mostrar o estado ou o valor de uma
variável? se sim, qual o comando?
https://www.filipeflop.com/blog/display-lcd-16x2-pic-16f628a/ 5/8
12/12/2017 Ligando Display LCD 16x2 ao PIC 16F628A - FilipeFlop
Meus parabéns!
Seus posts são de grande ajuda para muita gente, eu como iniciante em PIC tenho esclarecido
muitas dúvidas com os seus artigos.
Boa tarde!
Uma dúvida, a segunda parte da programação, eu tenho que colocar logo abaixo da primeira?
Não. A primeira parte você coloca em um arquivo texto, o lcd.h. A segunda parte você vai utilizar
dentro do MPLab, para chamar as rotinas que foram inseridas nesse arquivo texto.
Abraço.
Esta biblioteca serve para qualquer PIC da familia 16?? mais especi camente o 16f877A?
Boa noite,
Tentei fazer o projeto mas não funcionou… no display acendem todos os quadrados da linha inferior,
somente isso. Tem alguma ideia do que pode ser?
olá, eu gostaria de saber até que distância consigo ligar o display do PIC? Exemplo posso ligar o LCD há 5
metros do PIC? A ideia é fazer esta ligação através de um cabo de rede.
https://www.filipeflop.com/blog/display-lcd-16x2-pic-16f628a/ 6/8
12/12/2017 Ligando Display LCD 16x2 ao PIC 16F628A - FilipeFlop
Abraço.
Como faço para escrever uma string maior que o numero de posições do LCD, de forma que uma frase
com 30 caracteres por exemplo, possa aparecer uma parte na linha de cima (16 colunas) e o restante na
linha de baixo (14 colunas) ??
Olá, gostaria de saber como envio uma variável GLOBAL do tipo STRING para o LCD?.
Atualmente uso para enviar uma variável do tipo INTEIRO para o lcd a seguinte instrução:
printf(LCD_texto,”fHora: %2u:%2u:%2u”,hora,min,seg); //Escrevo
Funciona, mas String não estou conseguindo.
Poderia me ajudar?
Muito obrigado!!
Marcio Leandro
Bom dia. acho muito bacana o trabalho de vocês de ensinar e ajudar quem esta aprendendo. Gostaria
de saber se vocês tem e pode me enviar o diagrama da placa de desenvolvimento “acepi 18-28” ja
procurei e não consigo encontrar nem mesmo na acepic. Sepuderem me ajudar eu agradeço.
Forte abraço a tds…
Display (7)
Embarcados (41)
https://www.filipeflop.com/blog/display-lcd-16x2-pic-16f628a/ 7/8
12/12/2017 Ligando Display LCD 16x2 ao PIC 16F628A - FilipeFlop
ESP8266 (15)
Módulos (14)
News (26)
Outros (11)
Raspberry Pi (45)
Sensores (23)
Shield (2)
Wearable (4)
Wireless (44)
Posts Recentes
v Assine a Newsletter
...e junte-se à maior comunidade maker do Brasil
Digite seu E-mail Enviar
Dúvidas Institucional
Frequentes
r m n
o
0 0
Pesquisar produtos… Quem Somos
Como comprar
Alguma dúvida? Entre em Termos de Uso
contato! Frete Grátis
(48) 3307-3495 Trabalhe
Pagamento e Conosco
envio
https://www.filipeflop.com/blog/display-lcd-16x2-pic-16f628a/ 8/8