Click here to load reader
Upload
reinaldo-oliveira
View
7
Download
1
Embed Size (px)
DESCRIPTION
Microcontroladores
Citation preview
LIGANDO DISPLAY LCD 16×2 AO PIC 16F628A
26 DE MAIO DE 2014 PIC 14 COMENTÁRIOS 9
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 fios, 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 :
Os pinos de controle do display LCD 16×2 são o RS, o R/W e o E.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 configuraçã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 :123456789101112131415161718192021222324252627282930313233343536373839404142
/***************************************************************************//* Rotinas para o LCD *//***************************************************************************/ //Este é o bloco com as rotinas necessárias para manipular o LCD /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Envio de "Nibble" para o LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Esta rotina lê o "Nibble" inferior de uma variável e envia para o LCD.void envia_nibble_lcd(int dado){//Carrega as vias de dados (pinos) do LCD de acordo com o nibble lidooutput_bit(lcd_db4, bit_test(dado,0)); //Carrega DB4 do LCD com o bit DADO<0>output_bit(lcd_db5, bit_test(dado,1)); //Carrega DB5 do LCD com o bit DADO<1>output_bit(lcd_db6, bit_test(dado,2)); //Carrega DB6 do LCD com o bit DADO<2>output_bit(lcd_db7, bit_test(dado,3)); //Carrega DB7 do LCD com o bit DADO<3> //Gera um pulso de enableoutput_high(lcd_enable); // ENABLE = 1delay_us(1); // Recomendado para estabilizar o LCDoutput_low(lcd_enable); // ENABLE = 0return; // Retorna ao ponto de chamada da função} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Envio de Byte para o LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Esta rotina irá enviar um dado ou um comando para o LCD conforme abaixo:// ENDEREÇO = 0 -> a variável DADO será uma instrução// ENDEREÇO = 1 -> a variável DADO será um caractere
4344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
void envia_byte_lcd(boolean endereco, int dado){output_bit(lcd_rs,endereco); // Seta o bit RS para instrução ou caracteredelay_us(100); // Aguarda 100 us para estabilizar o pino do LCDoutput_low(lcd_enable); // Desativa a linha ENABLEenvia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/comandoenvia_nibble_lcd(dado & 0x0f); // Limpa a parte ALTA e envia a parte BAIXA do // dado/comandodelay_us(40); // Aguarda 40us para estabilizar o LCDreturn; // Retorna ao ponto de chamada da função} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Envio de caractere para o LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */// Esta rotina serve apenas como uma forma mais fácil de escrever um caractere// no display. Ela pode ser eliminada e ao invés dela usaremos diretamente a// função envia_byte_lcd(1,"<caractere a ser mostrado no LCD>"); ou// envia_byte_lcd(1,<código do caractere a ser mostrado no LCD>); void escreve_lcd(char c)// envia caractere para o display{envia_byte_lcd(1,c);} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Função para limpar o LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */// Como esta operação pode ser muito utilizada, transformando-a em função// faz com que o código compilado seja menor. void limpa_lcd(){envia_byte_lcd(0,0x01); // Envia instrução para limpar o LCDdelay_ms(2); // Aguarda 2ms para estabilizar o LCDreturn; // Retorna ao ponto de chamada da função} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Inicializa o LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
9394959697989910010110210310410510610710810911011111211311411511611711811912012
* * * */ void inicializa_lcd(){output_low(lcd_db4); // Garante que o pino DB4 estão em 0 (low)output_low(lcd_db5); // Garante que o pino DB5 estão em 0 (low)output_low(lcd_db6); // Garante que o pino DB6 estão em 0 (low)output_low(lcd_db7); // Garante que o pino DB7 estão em 0 (low)output_low(lcd_rs); // Garante que o pino RS estão em 0 (low)output_low(lcd_enable); // Garante que o pino ENABLE estão em 0 (low)delay_ms(15); // Aguarda 15ms para estabilizar o LCDenvia_nibble_lcd(0x03); // Envia comando para inicializar o displaydelay_ms(5); // Aguarda 5ms para estabilizar o LCDenvia_nibble_lcd(0x03); // Envia comando para inicializar o displaydelay_ms(5); // Aguarda 5ms para estabilizar o LCDenvia_nibble_lcd(0x03); // Envia comando para inicializar o displaydelay_ms(5); // Aguarda 5ms para estabilizar o LCDenvia_nibble_lcd(0x02); // CURSOR HOME - Envia comando para zerar o //contador de caracteres e retornar à posição // inicial (0x80).delay_ms(1); // Aguarda 1ms para estabilizar o LCDenvia_byte_lcd(0,0x28); // FUNCTION SET - Configura o LCD para 4 bits, // 2 linhas, fonte 5X7.envia_byte_lcd(0,0x0c); // DISPLAY CONTROL - Display ligado, sem cursorlimpa_lcd(); // Limpa o LCDenvia_byte_lcd(0,0x06); // ENTRY MODE SET - Desloca o cursor para a direitareturn; // Retorna ao ponto de chamada da função} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Define inicio da escrita ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *///Esta função foi adicionada e serve para se definir em que posição do //LCD deseja-se iniciar a escrita. Para isto basta chamar a Função //"caracter_Inicio()" indicando a linha e a coluna onde o cursor será // posicionado antes de se mandar escrever void caracter_inicio(int linha, int coluna)//define a posicão de inicio da frase{int16 posicao=0; if(linha == 1) { posicao=0x80; //Se setado linha 1, end incial 0x80 } if(linha == 2) { posicao=0xc0; //Se setado linha 2, end incial 0xc0 } posicao=posicao+coluna; //soma ao end inicial, o numero da
1122123124125126127128129130131132133134
colunaposicao--; //subtrai 1 para corrigir posição envia_byte_lcd(0,posicao);return;}/***************************************************************************//* Final das rotinas para o LCD *//***************************************************************************/
A estrutura da pasta do projeto vai ficar mais ou menos assim :
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:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
#include <16F628A.h> //Define o modelo do microcontrolador // Fusíveis de configuração do microcontrolador #FUSES NOWDT //Watch Dog Timer desabilitado#FUSES HS //oscilador cristal#FUSES PUT //Power Up Timer#FUSES NOPROTECT //sem proteção para leitura da eprom#FUSES BROWNOUT //Resetar quando detectar brownout#FUSES NOMCLR //Reset desabilitado#FUSES NOLVP //prog. baixa voltagem desabilitado#FUSES NOCPD //Sem travar o chip #use delay(clock=16000000) //Define o cristal utilizado //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 // Estas são as definições dos pinos que o LCD utiliza.// Definem quais pinos do PIC controlarão os pinos do LCD #define lcd_enable pin_a1 // pino enable do LCD#define lcd_rs pin_a0 // pino rs (register select)do LCD // (0) para comandos (1) para dados #define lcd_db4 pin_b4 // pino de dados d4 do LCD#define lcd_db5 pin_b5 // pino de dados d5 do LCD#define lcd_db6 pin_b6 // pino de dados d6 do LCD#define lcd_db7 pin_b7 // pino de dados d7 do LCD#include <lcd.h> //declaração da biblioteca do LCD //Programa principalvoid main(){ inicializa_lcd(); //Inicializa o LCD while(1){ //limpa_lcd(); //Limpa o display do LCD caracter_inicio(2,6);
5152535455565758
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.
A alimentação do circuito é de 5v e o potenciômetro é de 10 K, utilizado para controle do contraste do display LCD 16×2. Se necessário, coloque um resistor no pino 15 ou 16 para reduzir a intensidade da luz de fundo.
Gostou ? Ajude-nos a melhorar o blog atribuindo uma nota aos posts (estrelas no início ou no final do artigo) e visite nossa loja FILIPEFLOP !