TECLADO MATRICIAL - Página 1/8
PROGRAMAÇÃO C PARA MICROCONTROLADORES 8051 E PIC PALAVRAS-CHAVE Microcontrolador 8051, Microcontrolador PIC 16F877A, Display LCD
UNIDADE DE ESTUDOS:
DISPLAY LCD Nesta unidade de estudos vamos explorar o funcionamento e a
aplicação do display de cristal líquido alfanumérico ou LCD
amplamente utilizado em equipamentos eletrônicos, tais como
exemplo, telefones, alarmes, autoatendimento e uma ampla
variedade de aplicações. Este componente tem como finalidade
servir de interface homem-máquina (IHM) para exibir
informações e solicitar dados do usuário para que o sistema
realize determinada ação.
Um bom motivo para utilizar este componente é a possibilidade
de exibir um amplo conjunto de caracteres da tabela ASCII que
não seria possível utilizando display de 7 segmentos. Os
exemplos aqui apresentados utilizam LCD 16x2, no entanto,
funcionarão com outros tamanhos, como por exemplo 20x2,
40x2, 16x4, 8x1 entre outros.
METODOLOGIA Serão analisadas as funções da biblioteca lcd.h de modo a exibir
mensagens (strings) no LCD através da programação. Para a
exibição de variáveis com mais de um caractere será
implementado um algoritmo que converterá um número para
string.
A abordagem desta unidade de estudos utiliza a programação
C para o microcontrolador AT89S52, da família MCS-51 ou
popularmente chamada de “8051” de modo que as informações
em display LCD 16x2. Depois a atividade é revista com a
programação C para o microcontrolador PIC16F877A da família
PIC 16F.
RECURSOS Para desenvolver e experimentar este material é necessário um
computador ou notebook com sistema operacional Windows ou
posterior e baixar o pacote de programas disponível em
www.u8051.com.br o qual contém as seguintes ferramentas de
desenvolvimento: Compilador 8051, Compilador PIC, Software
de simulação Proteus-ISIS.
AVALIAÇÃO DE DESEMPENHO A secção ATIVIDADES PROPOSTAS apresenta um conjunto de
exercícios de dificuldade incremental a fim de avaliar o seu
entendimento a cerca desta unidade de estudos.
RESULTADOS ESPERADOS Ao concluir o desenvolvimento das atividades propostas, você
deverá ser capaz de utilizar o display LCD para exibir
informações personalizadas nestes modelos de
microcontroladores.
TECLADO MATRICIAL - Página 2/8
// Programa 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Colunas
Linhas
DISPLAY LCD COM AT89S52 Os displays LCD são geralmente utilizados em projetos nos
quais o usuário precisa acompanhar e interagir com os dados
um sistema, calculadoras, senhas acesso, de atendimento,
centrais de alarme, etc. Para este estudo vamos considerar um
LCD 16x2 conforme as figuras abaixo.
Figura 1: Display LCD 16x2
O display exibe caracteres nas posições denominadas linhas e
colunas ou simplesmente nas coordenadas x, y respectivamente.
A BIBLIOTECA LCD.H É encontrada na pasta 8051\SDCC\INCLUDE que implementa as
seguintes funções de uso do LCD:
Comando Efeito
lcd_init(); inicializa o LCD / Limpa a
tela e define x=1, y=1
lcd_gotoxy(x,y); Posiciona a escrita na
coordenada linha x e
coluna y
lcd_putchar(char) Escreve um caractere ASCI
no LCD ao lado direito do
caractere anterior
lcd_puts(string); Escreve uma string no LCD
ao lado direito do caractere
anterior
lcd_cursor(bit); Exibe o cursor piscante na
coordenada em que ocorre
a escrita no LCD
lcd_shift_left(); Desloca todos os caracteres
para a esquerda
lcd_shift_right(); Desloca todos os caracteres
para a direita
Tabela 1: Funções da biblioteca lcd.h
Considere que no circuito real que as funções lcd_shift_left e lcd_shift_right produzem a animação oposta da simulação.
ESQUEMÁTICO 8051 E LCD
Figura 2: Conectando o display LCD 16x2 ao microcontrolador AT89S52
Este esquema foi desenhado no software Proteus-ISIS versão 7
ou posterior utilizando os seguintes componentes:
Referência Componente AT89C52 Microcontrolador AT89C52
LM016L Display LCD 16x2
BUTTON Botões AVANCAR e SOMAR
Uma versão portátil deste
simulador pode ser
executada a partir da pasta
8051\ISIS77\BIN\ISIS.EXE
Figura 3: Executando o Simulador ISIS
A biblioteca lcd.h comunica com o 8051 através do PORT P2,
mas esta definição pode ser editada dentro da biblioteca se
necessário. Para incluir o protocolo de comunicação com o LCD
você verá a declaração da biblioteca na seguinte ordem:
#include<at89x52.h> //este comando primeiro
#include<lcd.h> //este comando depois
A função lcd_init( ) inicializa a comunicação com o LCD e deve
ser realizada pelo menos uma vez no programa, por isso, esta
função antecede o laço de repetição while(1) conforme o
exemplo a seguir (ver também programa 2).
void main(){
lcd_init(); //inicializa e limpa o LCD
}
O display LCD 16x2 é contém 16 colunas e 2 linhas endereçáveis
através da função lcd_gotoxy. Para escrever na linha 1 e coluna
15 escreva o seguinte comando e veja o resultado na figura 11.
lcd_gotoxy(1,15); //posiciona linha x=1, coluna y=15
lcd_puts("B3"); //mostra a string “B3” na coordenada x,y
EXIBINDO STRINGS A função lcd_puts(string) envia uma string contendo um ou mais
caracteres declarados entre aspas duplas, conforme o exemplo
a seguir.
#include<at89x52.h>
#include<lcd.h>
void main(){
lcd_init();
lcd_puts("Micro");
lcd_puts("controlador");
}
O programa 1 exibe a mensagem “Microcontrolador” a partir
das coordenadas (x=1, y=1) ocupando somente a primeira linha
do LCD. Observe que a função lcd_init( ) limpa a tela e posiciona
a escrita na coordenada (1, 1).
O circuito da figura 2 apresenta a conexão do microcontrolador ao display LCD. Fig. 3a: Coordenadas endereçáveis do display LCD 6x2
1
2
TECLADO MATRICIAL - Página 3/8
// Programa 2
// Programa 3
// Programa 4
// Programa 5
EXIBINDO VARIÁVEIS A função putchar( ) envia um único char de cada vez ao LCD
obedecendo o código da tabela ASCII (lê-se ásqui). Considere o
seguinte exemplo:
A variável char cont recebe 65. Depois
o valor de cont é enviado ao LCD que
exibirá ‘A’ por que na tabela ASCII o
65 equivale ao caractere ‘A’.
As instruções lcd_putc(‘A’) e lcd_putc(65) têm o mesmo efeito.
Para relembrar a tabela ASCII dos dígitos decimais por favor
leia a unidade de estudos LEITURA DE SENSORES, tópico 3.6
EXIBINDO 0 A 9 Para exibir valores de apenas um dígito temos o exemplo de
código que soma uma unidade na variável cont a cada clique no
botão SOMAR. A variável cont é convertida para ASCI somando-
se 48.
#include<at89x52.h>
#include<lcd.h>
#define SOMAR P3_3
int cont=0;
bit b1;
void main()
{
lcd_init();
while(1)
{
if(SOMAR==0 && b1==0)
{
b1=1;
cont++;
lcd_gotoxy(1,1);
lcd_putchar(cont+48);
}
if(SOMAR==1) b1=0;
}
}
Quando cont é 0, o valor ASCII cont+48 equivale a “0”. Quando
cont é 9, o valor ASCII cont+48 =57 equivale a “9”. Porém
quando cont é 10, o valor ASCII cont+48 =58 equivale a “:”, por
isso, este modelo funciona apenas com um dígito.
EVENTO CLIQUE O programa 2 emprega a lógica do evento pressionar-e-soltar
o botão para evitar a repetição. No exemplo a seguir, a variável
b1 registra o instante em que o botão SOMAR é pressionado.
Por exemplo, quando SOMAR é pressionado, a variável cont é
aumenta uma unidade (+1) e b1 recebe 1. Não importa agora
que SOMAR ainda esteja pressionado, pois o teste b1==0 é
falso e não ocorre mais a repetição. Porém, ao soltar este botão,
a variável b1 retorna a 0, podendo então, registrar um novo
clique. Os programadores, denominam a variável b1 de flag por
que sinaliza um evento, assumindo os valores 0 e 1 apenas. As
variáveis booleanas do tipo bit (no 8051) e int1 (no PIC)
atendem a esse propósito e ocupam pouca memória RAM do
chip.
EXIBINDO 0 A 99 Para exibir valores de até dois dígitos envia-se a dezena
seguida da unidade da variável char cont.
lcd_init();
lcd_putchar(cont/10+48);
lcd_putchar(cont%10+48);
EXIBINDO 0 A 255 E 0 A 999 Para exibir valores de três dígitos envia-se a centena, dezena e
unidade separadamente. Se a contagem for até 255, a variável
cont deve ser do tipo char, se for precisar ultrapassar esse valor,
deverá ser do tipo int.
lcd_init();
lcd_putchar(cont/100+48);
lcd_putchar(cont%100/10+48);
lcd_putchar(cont%10+48);
Observe nos exemplos acima que operador de modulo % obtém
o resto da divisão cont por 10. Por exemplo, a operação 937%10
(lê-se 937 MOD 10) dividirá 937 por 10 e ficará com o resto: 7.
Por isso, 937%10=7. Empregando corretamente os operadores
módulo “%10” e divisão “/10” você deverá ser capaz de exibir
números com mais dígitos no display.
ROTAÇÃO MENSAGENS O comando lcd_shift_right desloca todos os caracteres (de todas
as linhas) uma casa ao lado, sendo que aplicando repetição
desse comando com velocidade moderada é possível criar
animações e exibir mensagens maiores do que 16 caracteres.
#include<at89x52.h>
#include<lcd.h>
#include<delay.h>
char i=0;
void main(){
while(1) {
lcd_init();
lcd_gotoxy(1,16);
lcd_puts("Microcontrolador com LCD");
for(i=0;i<40;i++){
delay_ms(100);
lcd_shift_right();
}
}
}
EXIBINDO VETORES NO LCD (8051)
Para exibir todo o conteúdo de um vetor em display LCD,
utiliza-se a função lcd_puts passando como parâmetro o nome
do vetor sem o índice. O exemplo a seguir exibe o vetor senha.
#include<at89x52.h>
#include<lcd.h>
#define TAM_SENHA 3
char senha[TAM_SENHA]= {'1','4','1'};
void main()
{
lcd_init();
lcd_puts(senha);
}
EXIBINDO O CURSOR A função lcd_cursor envia o comando
para ativar o traço sublinhado no LCD.
Observe a imagem ao lado.
Esta função permite criar uma interface homem-máquina (IHM)
com reduzido número de botões, como por exemplo: um botão
para ajustar o valor e outro para navegar entre os valores
ajustáveis.
Por exemplo, com está função você
deverá ser capaz de ajustar os
campos ao lado com apenas dois
botões.
char cont=65;
lcd_putc(cont);
16/10/21 20:30
Cont:0001 LIG
Fig. 4: Ajustando data, hora e contagem
TECLADO MATRICIAL - Página 4/8
// Programa 6 // Programa 7
PROGRAMAÇÃO A seguir temos a programação para ajustar o valor de duas
variáveis exibidas no LCD utilizando a função lcd_cursor. O botão
AVANCAR define variável que será ajustada, bem como define
a coordenada de exibição do cursor.
#include<at89x52.h>
#include<lcd.h>
#define AVANCAR P3_2
#define SOMAR P3_3
bit b1,b2;
char dia=1, mes=3, pos;
void atualizaLCD();
void atualizaCursor();
//******************************
void main(){
lcd_init();
atualizaLCD();
atualizaCursor();
while(1){
if(SOMAR==0 && b1==0){
b1=1;
if(pos==0) dia++;
if(pos==1) mes++;
atualizaLCD();
}
if(SOMAR==1) b1=0;
if(AVANCAR==0 && b2==0)
{
b2=1;
pos++;
if(pos>1) pos=0;
atualizaCursor();
}
if(AVANCAR==1) b2=0;
}
}
//******************************
void atualizaLCD(){
lcd_cursor(0);
lcd_gotoxy(1,1);
lcd_putchar(dia/10+48);
lcd_putchar(dia%10+48);
lcd_putchar('/');
lcd_putchar(mes/10+48);
lcd_putchar(mes%10+48);
atualizaCursor();
}
//******************************
void atualizaCursor()
{
if(pos==0) lcd_gotoxy(1,2);
if(pos==1) lcd_gotoxy(1,5);
lcd_cursor(1);
}
Observe o programa 4: a exibição das variáveis dia e mês foram
encapsuladas na função atualizaLCD por que é chamada no
inicio do programa e também ao clicar no botão SOMAR. Por
esse mesmo motivo a exibição do cursor também está numa
função. O cursor deve ser ativado depois que todas informações
já estão no LCD. Observe que o cursor é desligado na função
atualizaLCD para que não seja exibido lado do último caractere
enviado, por exemplo 16/10_. Então, após a escrita da data, a
chamada para a função atualizaCursor exibirá o sublinhado na
coordenada correta.
EXIBINDO 0 A 4.294.967.295 A seguir temos a programação para exibir todas as faixas de
valores inteiros suportados no 8051, inclusive o tipo unsigned
long int que alcança a faixa de 4 bilhões. A função valParaString
realiza sucessivas operações de módulo e divisão e preenche
uma variável indexada (vetor) com cada digito do valor. A
variável cont pode ser do tipo int por exemplo, para uma faixa
de valores menor. A definição QTD_DIGITOS especifica a
quantidade de dígitos que será apresentada no LCD. Por
exemplo, ao definir QTD_DIGITOS 4 a exibição será no formato
“00001”.
#include<at89x52.h>
#include<lcd.h>
unsigned long int cont=4294967295;
#define QTD_DIGITOS 10
char vetor[QTD_DIGITOS+1];
bit x,y;
void valParaString(unsigned long int val, char*
string, char digitos);
//********************************************
void main(){
lcd_init();
valParaString(cont, vetor, 10);
}
//********************************************
void valParaString(unsigned long int val, char*
string, char digitos){
char i;
for(i=QTD_DIGITOS;i>0;i--){
string[i]=(val%10)+48;
val/=10;
}
for(i=QTD_DIGITOS-digitos;i<QTD_DIGITOS+1;i++){
if(string[i]!=0) lcd_putchar(string[i]);
}
}
ATIVIDADES PROPOSTAS
1 Desenhar o esquemático da figura 2 no software
simulador ISIS;
Digitar e compilar o programa 1 no software JFE;
Simular o programa 1 no software ISIS;
Simular o programa 2 no software ISIS combinando as
instruções do programa 3 e depois do programa 4;
Revisar e acrescentar operações de modo a exibir até 4
dígitos. Você deve inicializar a variável cont=1234;
2 Digitar e compilar o programa 5 no software JFE;
Simular o programa 5 no software ISIS;
Exibir o seu primeiro e último na primeira linha do LCD
empregando o efeito de rotação de modo repetitivo;
3 Digitar e compilar o programa 5 no software JFE;
Simular o programa 5 em conjunto com o esquemático
da figura 2;
Simular o programa 6 em conjunto com o esquemático
da figura 2;
Desafio supremo: Implementar os ajustes da figura 4,
sendo os limites: dia até 31; mês até 12; ano até 30; hora
até 23:59; Cont deverá somar até 2000; o último campo
deve alternar entre LIG/DES e acrescentar um botão em
P3.4 que desconta o valor.
AGRADECIMENTO A biblioteca lcd.h foi apresentada em sala de aula 2011 pelo
então estudante e Max Felipe Knevitz Pedroso. Posteriormente
formou-se e integrou o corpo docente do curso Técnico em
Eletrônica do CIMOL, atuando até 2017.
TECLADO MATRICIAL - Página 5/8
Engenharia Curso de microcontrolador online pic 8051 programação jfe pic c compiler projeto s microgenios gravador cu scopic aeci sp progisp u sbasp atmega Arduino faculdade unisinos feeva le.br pucrs ufrgs uninter faccat ita unisanta unoeste anhanguera usp unesp feec feelt ufrj pucminas unitaumaua ime unopar fam ufsc pucpr fei fatec uninove ead uniceug Anchieta uceff ufpel rogercom ufal edu br fpb up unifacs fatecpr feitep univap fen/ufg famen dombosco utfpr cefet uni pifam senai impacta unilasalle uva uc s.br unifor upe.br unig.br ifrs.edu.br
// Programa 8
DISPLAY LCD COM PIC16F877A
A BIBLIOTECA LCD.H Implementa as seguintes funções de uso do LCD:
Comando Efeito
lcd_init(); inicializa o LCD / Limpa
a tela e define x=1,
y=1
lcd_gotoxy(x,y); Posiciona a escrita na
coordenada linha x e
coluna y
lcd_putc(char)
Escreve um caractere
ASCII ou string no LCD
ao lado direito do
caractere anterior
lcd_cursor(bit); Exibe o cursor piscante
na coordenada em que
ocorre a escrita no LCD
lcd_shift_left(); Desloca todos os
caracteres para a
esquerda
lcd_shift_right(); Desloca todos os
caracteres para a
direita
printf(lcd_putc,"%li",
int); Exibe um string e texto
no formato printf
Tabela 2: Funções da biblioteca lcd.h
ESQUEMÁTICO PIC E LCD
Figura 4: Conectando o display LCD 16x2 ao microcontrolador PIC16F877A
Observe que quando os I/O’s do PIC são utilizados para leitura
de sensores de contato, como no caso das teclas, as entradas
ficam em coletor aberto ou tristate, necessitando de resistores
pull up R1 e R2 para definir o estado lógico 1 das entradas.
Este esquema foi desenhado no software Proteus-ISIS versão 7
ou posterior utilizando os seguintes componentes:
Referência Componente PIC16F877A Microcontrolador PIC16F877A LM016L Display LCD 16x2 BUTTON Botões AVANCAR e SOMAR RES Resistor 4K7
Uma versão portátil deste
simulador pode ser executada
a partir da pasta
8051\ISIS77\BIN\ISIS.EXE
Figura 5: Executando o Simulador ISIS
A biblioteca lcd.h comunica com o PIC através do PORT B, mas
esta definição pode ser editada dentro da biblioteca se
necessário. Para incluir o protocolo de comunicação com o LCD
você verá a declaração da biblioteca na seguinte ordem:
#include<16F877A.h>
#fuses nowdt, nobrownout, xt, noput, noprotect
#use delay(clock=4000000)
#include<lcd.h>
void main(){
lcd_init(); //inicializa e limpa o LCD
}
A função lcd_init( ) inicializa a comunicação com o LCD e deve
ser realizada pelo menos uma vez no programa, antes do laço
de repetição while(1).
EXIBINDO STRINGS A função lcd_putc(char ou string) envia um caractere ou string
contendo um ou mais caracteres declarados entre aspas duplas,
conforme o exemplo a seguir.
#include<16F877A.h>
#fuses nowdt, nobrownout, xt, noput
#use delay(clock=4000000)
#include<lcd.h>
void main(){
lcd_init();
lcd_putc("Micro");
lcd_putc("controlador");
}
O programa 1 exibe a mensagem “Microcontrolador” a partir
das coordenadas (x=1, y=1) ocupando somente a primeira linha
do LCD. Observe que a função lcd_init( ) limpa a tela e posiciona
a escrita na coordenada (1, 1).
O comando lcd_putc suporta um código ASCII para ser exibido
no LCD. Por exemplo, o comando lcd_putc(65) exibirá o
caractere “A”. As instruções lcd_putc(‘A’) e lcd_putc(65) têm o
mesmo efeito.
EXIBINDO 0 A 9 No PIC você deve especificar os I/O’s que serão utilizados como
entrada (leitura de botões) e quais serão saídas de dados (neste
contexto é o acionamento do LCD). A instrução set_tris define
a direção dos dados sendo 0=Output e 1=Input.
Comando em binário literal: set_tris_C(0b11111111);
Efeito (todo o PORTC como entrada de dados):
I/O C7 C6 C5 C4 C3 C2 C1 C0
Val 1 1 1 1 1 1 1 1
Direção Entr Entr Entr Entr Entr Entr Entr Entr
A função input(IO) retorna o nível lógico encontrado no I/O
especificado.
A diretiva #use fast_io(IO) especifica que o programado
irá decidir quais I/O’s serão entrada com o comando set_tris(IO).
TECLADO MATRICIAL - Página 6/8
// Programa 9
// Programa 10
// Programa 11
// Programa 10
#include<16F877A.h>
#fuses nowdt, nobrownout, xt, noput
#use fast_io(C) //sinal digital
#use delay(clock=4000000)
#include<lcd.h>
#define SOMAR PIN_C1
int cont=3;
int1 b1;
void main(){
set_tris_C(0b11111111);
lcd_init();
while(1){
if(input(SOMAR)==0 && b1==0){
b1=1;
cont++;
lcd_gotoxy(1,1);
lcd_putc(cont+48);
}
if(input(SOMAR)==1) b1=0;
}
}
EXIBINDO 0 A 99 Para exibir valores de até dois dígitos envia-se a dezena
seguida da unidade da variável.
lcd_init();
lcd_putc(cont/10+48);
lcd_putc(cont%10+48);
EXIBINDO 0 A 999 Para exibir valores de até três dígitos envia-se a centena,
dezena e unidade da variável.
lcd_init();
lcd_putc(cont/100+48);
lcd_putc(cont%100/10+48);
lcd_putc(cont%10+48);
Observe nos exemplos acima que operador de modulo % é
recursivo, isto, divide repetidamente até obter o resto da
divisão. Por exemplo, a operação 937%10 (lê-se 937 MOD 10)
dividirá 937 por 10 repetidamente 9 vezes até restar o valor 7.
Por isso, 937%10=7. Empregando corretamente de módulo
“%10” e divisão “/10” você deverá ser capaz de exibir números
de maior comprimento no display LCD.
O COMANDO PRINTF Se você está familiarizado com o C para computadores, poderá
utilizar a função printf disponível no PIC-C Compiler. A função
printf tem a seguinte sintaxe:
printf(lcd_putc, “texto %tipo”, variável);
Sendo que:
texto é uma string a ser exibida antes da variável (opcional);
%tipo é o tipo da variável que será exibida
Variável é a variável que será exibida no campo %tipo
Veja alguns exemplos:
int16 cont=12;
printf(lcd_putc, "Cont: %li", cont);
O que você verá no LCD: Cont: 12
int16 cont=12;
printf(lcd_putc, "Cont: %04li", cont);
O que você verá no LCD: Cont: 0012
int8 cont=12;
printf(lcd_putc, "Valor: %03i", cont);
O que você verá no LCD: Valor: 012
int16 cont1=12, cont2=47;
printf(lcd_putc, "Cont1: %04li Cont2: %04li",
cont1, cont2);
O que você verá no LCD: Cont1: 0012 Cont2:0047
Foram estes alguns exemplos de uso do comando printf.
Entretanto, você poderá explorar a função printf acessando o
help do compilador PCW (pressionando F1) e em seguida
pesquise o termo printf.
Figura 5: Acessando a ajuda do PIC-C Compiler
CONTADOR 0 A 9999 (COM PRINTF) O programa 10 exemplifica o uso da função printf para a
exibição da contagem de pulsos recebida no I/O C1.
#include<16F877A.h>
#fuses nowdt, nobrownout, xt, noput
#use fast_io(C)
#use delay(clock=4000000)
#include<lcd.h>
#define SOMAR PIN_C1
int16 cont=3;
int1 b1;
void main(){
set_tris_C(0b11111111);
lcd_init();
while(1){
if(input(SOMAR)==0 && b1==0){
b1=1;
cont++;
lcd_gotoxy(1,1);
printf(lcd_putc, "Cont: %04li", cont);
}
if(input(SOMAR)==1) b1=0;
}
}
EXIBINDO O CURSOR A função lcd_cursor envia o comando
para ativar o traço sublinhado no LCD.
Observe a imagem ao lado.
Esta função permite criar uma interface homem-máquina (IHM)
com reduzido número de botões, como por exemplo: um botão
para ajustar o valor e outro para navegar entre os valores
ajustáveis.
PROGRAMAÇÃO A seguir temos a programação para ajustar o valor de duas
variáveis exibidas no LCD utilizando a função lcd_cursor. O botão
AVANCAR define variável que será ajustada, bem como define
a coordenada de exibição do cursor.
TECLADO MATRICIAL - Página 7/8
// Programa 11 #include<16F877A.h>
#fuses nowdt, nobrownout, xt, noput
#use fast_io(C)
#use delay(clock=4000000)
#include<lcd.h>
#define AVANCAR PIN_C1
#define SOMAR PIN_C0
int1 b1,b2;
signed char dia=1, mes=3, pos;
signed int16 cont=0;
void atualizaLCD();
void atualizaCursor();
//******************************
void main(){
set_tris_C(0b11111111);
lcd_init();
atualizaLCD();
atualizaCursor();
while(1) {
if(input(SOMAR)==0 && b1==0) {
b1=1;
if(pos==0) dia++;
if(pos==1) mes++;
atualizaLCD();
}
if(input(SOMAR)==1) b1=0;
if(input(AVANCAR)==0 && b2==0){
b2=1;
pos++;
if(pos>1) pos=0;
atualizaCursor();
}
if(input(AVANCAR)==1) b2=0;
}
}
//******************************
void atualizaLCD(){
lcd_cursor(0);
lcd_gotoxy(1,1);
lcd_putc(dia/10+48);
lcd_putc(dia%10+48);
lcd_putc('/');
lcd_putc(mes/10+48);
lcd_putc(mes%10+48);
atualizaCursor();
}
//******************************
void atualizaCursor(){
if(pos==0) lcd_gotoxy(1,2);
if(pos==1) lcd_gotoxy(1,5);
lcd_cursor(1);
}
CONCLUSÃO Exploramos o funcionamento e a aplicação do display LCD
presente numa ampla diversidade de equipamentos
eletrônicos, servindo as informações apresentadas de
referência para integrar o microcontrolador a displays LCD,
inclusive com uma configuração de linhas e colunas diferente.
Vimos também que o display recebe um caractere por vez,
necessitando um algoritmo capaz de “quebrar” um número de
vários dígitos em vários caracteres, e que os operadores de
módulo e divisão desempenham uma função importante para
“quebrar” as variáveis. A secção Atividades Propostas tem como
objetivo aplicar os assuntos abordados. Vimos também que o
cursor piscante é recomendado para criar um sistema de
navegação na tela utilizando poucos botões de controle.
Quando utilizamos o PIC vimos a importância de definir os I/O’s
como entrada e saída bem como a necessidade de resistores
Pull Up para a leitura de botões. A secção de anexos traz as
bibliotecas lcd.h para cada chip, as quais implementam as
funções de uso do LCD em conjunto com 8051 e PIC.
LICENÇA DE USO DESTE MATERIAL Todas as informações apresentadas funcionam em nível de simulação de software. Você pode baixa-las no site www.u8051.com.br e utiliza-las de forma parcial ou integral e livremente como material didático.
Documento atualizado em 09/06/2022 11:08 Prof. Cristian M.G ([email protected])
www.u8051.com.br
TECLADO MATRICIAL - Página 8/8
ANEXOS: BIBLIOTECAS LCD Nesta página você encontra a biblioteca lcd.h para o microcontrolador 8051 e a biblioteca lcd.h para o microcontrolador PIC. Ambas implementam a comunicação entre o microcontrolador e o display LCD.
Biblioteca lcd.h para 8051 Você deve copiar o código lcd.h (logo abaixo) para 8051 e colar no JFE. Em seguida, deverá clicar no menu File > Save As... e salvar na pasta 8051\SDCC\INCLUDE e preencher o nome lcd.h e finalmente clicar no botão Salvar. // PINOS PIC PINOS LCD // P2_0 D4 // P2_1 D5 // P2_2 D6 // P2_3 D7 // P2_4 enable // P2_5 rs #define lcd_en P2_4 #define lcd_rs P2_5 #define lcd_DELAY 125 /* Delay for 1 ms */ #define lcd_clear() lcd_command(0x1) //Limpa o lcd #define lcd_origin() lcd_command(0x2) //Set to origin lcd /*************************************************** * Prototype(s) * ***************************************************/ void lcd_delay(unsigned char ms); void lcd_enable(void); void lcd_command(unsigned char command); void lcd_putchar(unsigned char ascii); void lcd_puts(unsigned char *lcd_string); void lcd_init(void); void lcd_gotoxy(char linha, char coluna); void lcd_cursor(bit blink); void lcd_shift_left(); void lcd_shift_right(); void lcd_cursor(bit blink){ if(blink) lcd_command(0x0F); else lcd_command(0x0C); } //*********************************************************** void lcd_gotoxy(char linha, char coluna){ //lcd_command(0x7F+coluna); switch(linha){ case 1: lcd_command(0x7F + coluna); break; case 2: lcd_command(0xBF + coluna); break; case 3: lcd_command(0x93 + coluna); break; case 4: lcd_command(0xD3 + coluna); break; } } //*********************************************************** void lcd_delay(unsigned char ms) { unsigned char n; unsigned int i; for (n=0; n<ms; n++) { for (i=0; i<lcd_DELAY; i++); /* For 1 ms */ } } //*********************************************************** void lcd_enable(void) { lcd_en = 0; /* Clear bit P2.4 */ lcd_delay(1); lcd_en = 1; /* Set bit P2.4 */ } //*********************************************************** void lcd_command(unsigned char command) { lcd_rs = 0; /* Clear bit P2.5 */ P2 = (P2 & 0xF0)|((command>>4) & 0x0F); lcd_enable(); P2 = (P2 & 0xF0)|(command & 0x0F); lcd_enable(); lcd_delay(1); } //*********************************************************** void lcd_putchar(unsigned char ascii) { lcd_rs = 1; /* Set bit P2.5 */ P2 = (P2 & 0xF0)|((ascii>>4) & 0x0F); lcd_enable(); P2 = (P2 & 0xF0)|(ascii & 0x0F); lcd_enable(); lcd_delay(1); } //*********************************************************** void lcd_puts(unsigned char *lcd_string) { while (*lcd_string){ lcd_putchar(*lcd_string++); } } //*********************************************************** void lcd_init(void) { lcd_en = 1; /* Set bit P2.4 */ lcd_rs = 0; /* Clear bit P2.5 */ lcd_command(0x33); lcd_command(0x32); lcd_command(0x28); lcd_command(0x0C); lcd_command(0x06); lcd_command(0x01); /* Clear */ lcd_delay(256); } //*********************************************************** void lcd_shift_left(){ lcd_command(0x18); } //*********************************************************** void lcd_shift_right(){ lcd_command(0x1C); }
Biblioteca lcd.h para PIC Você deve copiar o código lcd.h (logo abaixo) para PIC e colar no PIC-C Compiler. Em seguida, deverá clicar no menu File > Save As... e salvar na pasta C:\Arquivos de Programas(x86))\PICC\Devices e preencher o nome lcd.h e então clicar no botão Salvar.
// PINOS PIC PINOS LCD // B0 enable // B1 rs // B2 rw // B4 D4 // B5 D5 // B6 D6 // B7 D7 // // Os pinos D0 a D3 do LCD não são usados. struct lcd_pin_map { // This structure is overlayed BOOLEAN enable; // on to an I/O port to gain BOOLEAN rs; // access to the LCD pins. BOOLEAN rw; // The bits are allocated from BOOLEAN unused; // low order up. ENABLE will int data : 4; // be pin B0. } lcd; #byte lcd = 6 #define set_tris_lcd(x) set_tris_b(x) #define lcd_type 2 // 0=5x7, 1=5x10, 2=2 linhas #define lcd_line_two 0x40 // Endereco de RAM da aª linha BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6}; // Estes bytes sao enviados ao lcd para incicializa-lo struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; #separate void lcd_send_nibble( BYTE n ) { lcd.data = n; delay_cycles(1); lcd.enable = 1; delay_us(2); lcd.enable = 0; } #separate void lcd_send_byte( BYTE address, BYTE n ) { lcd.rs = 0; delay_us(50); lcd.rs = address; delay_cycles(1); lcd.rw = 0; delay_cycles(1); lcd.enable = 0; lcd_send_nibble(n >> 4); lcd_send_nibble(n & 0xf); } #separate void lcd_init() { BYTE i; set_tris_lcd(LCD_WRITE); lcd.rs = 0; lcd.rw = 0; lcd.enable = 0; delay_ms(15); for(i=1;i<=3;++i) { lcd_send_nibble(3); delay_ms(5); } lcd_send_nibble(2); for(i=0;i<=3;++i) lcd_send_byte(0,LCD_INIT_STRING[i]); delay_ms(10); } #separate void lcd_gotoxy( BYTE y, BYTE x) { BYTE address; if(y!=1) address=lcd_line_two; else address=0; address+=x-1; lcd_send_byte(0,0x80|address); } #separate void lcd_putc( char c) { lcd_send_byte(1,c); break; } // funcoes adicionadas por Daniel Corteletti #separate void lcd_cursor_on() { lcd_send_byte(0,0x0E); } #separate void lcd_cursor(int blink){ if(blink) lcd_send_byte(0,0x0F); else lcd_send_byte(0,0x0C); } #separate void lcd_shift_left() { lcd_send_byte(0,0x18); } #separate void lcd_shift_right() { lcd_send_byte(0,0x1C); }