64
Conectando um display LCD no PIC Um diferencial em qualquer projeto microcontrolado é utilização de um display LCD para indicação de parâmetros e informações diversas. Um simples Display LCD 16×2 torna o projeto muito mais amigável ao usuário além de aumentar a gama de funções e operações com um custo relativamente baixo. O fato da simplicidade de como se configura um Display LCD para trabalhar em conjunto com um microcontrolador PIC faz com que se pense duas vezes em não utilizá-lo em seus projetos. A seguir um tutorial de configuração do Display LCD 16×2 em um programa para o PIC escrito em linguagem C.

Conectando um display LCD no PIC.docx

Embed Size (px)

Citation preview

Conectando um display LCD no PIC

Um diferencial em qualquer projeto microcontrolado utilizao de um display LCD para indicao de parmetros e informaes diversas.Um simples Display LCD 162 torna o projeto muito mais amigvel ao usurio alm de aumentar a gama de funes e operaes com um custo relativamente baixo.O fato da simplicidade de como se configura um Display LCD para trabalhar em conjunto com um microcontrolador PIC faz com que se pense duas vezes em no utiliz-lo em seus projetos.A seguir um tutorial de configurao do Display LCD 162 em um programa para o PIC escrito em linguagem C.

Vamos realizar a conexo de um LCD paralelo que utiliza o processador Hitachi HD44780 ou KS0066U a um microcontrolador PIC , utilizando apenas 4 vias de dados.

Estes LCDs so muito simples, no possuem recursos como gerenciamento automtico de pixels, no so coloridos (full color), no possuem iluminao ativa entre outras limitaes, mas ainda so largamente utilizados na indstria. Basta ver que muitas registradoras, equipamentos hand-held, sistemas de informao de computadores servidores entre outros, ainda utilizam largamente este dispositivo.

Exemplo de equipamentos comerciais que utilizam display LCDPodemos fazer um paralelo utilizao de Displays de 7 seguimentos para constatar a simplicidade do uso e economia de recursos do microcontrolador quando escolhemos um Display LCD (Hitachi HD44780 ou KS0066U):

Display 7 seguimentosAbaixo temos um pequeno exemplo de conexo de 4 displays de 7 seguimentos que mostram o resultado de uma operao Fatorial. O funcionamento do circuito no importante neste exemplo, basta observarmos a necessidade de reserva de 11 pinos do microcontrolador para mostrarmos apenas 4 caracteres apenas numricos. Para cada dgito acrescentado, precisamos de mais um pino do microcontrolador.

Utilizao de Display 7 segmentosAo utilizarmos um Display LCD, reservamos apenas 7 pinos de controle. Este nmero o mesmo para um display 162 ( 32 caracteres alfa numricos) ou um display 204 (80 caracteres alfa numricos).

Utilizao de Display LCD 162

Existem displays LCD de diversos tipos de formatos e tamanhos, todos eles so especificados de acordo com o numero de caracteres exibidos, divididos em linhas e colunas. Alguns possuem back-light e as cores dos caracteres podem varias, de modelo para modelo, em azul, mbar, verde, cinza, entre outras.

Display 1601 Apenas uma linha com 16 caracteres

Display 1602 2 linhas com 16 caracteres cada

Display 1604 4 linhas com 16 caracteres cada

Display 2001 Apenas uma linha com 20 caracteres

Display 2002 2 linhas com 20 caracteres cada

Display 2004 4 linhas com 20 caracteres cada

Basicamente, cada clula (Caracter) do LCD compostode 8 pixels na horizontal e 5 pixels na vertical

Estes LCDs so conhecidos como 57, uma vez que a linhainferior reservada para o cursor.

Existem tambm displays com 11 pixels de altura, conhecidoscomo 510.

Apresenta 14 pinos de acesso ( sem iluminao back-light)ou 16 pinos de acesso ( com iluminao back-light). 8 pinos de dados, 3 pinos de controle, 3 pinos de alimentao 2 pinos para iluminao back-light ( se houver)

A disposio dos pinos pode variar de modelo para modelo, veja abaixo uma outra disposio muito comum nos LCDs. Na dvida consulte o datasheet do fabricante.

Abaixo a tabela com a funo e descrio de cada pino de controle:

A alimentao padro de 5V ( de 4,5 6V) ,consumindoalguns miliampres.Alguns modelos trabalham com 3V e oconsumo total do LCD pode ser menor que de umnico LED!!!Os pinos (1) Vss(GND) e (2) Vdd (Vcc) podem ser ligadosjuntamente com o PIC mesma alimentao.

O pino (3) controla o contraste do LCD, para isso basta aplicar um sinal de 0V +5Vcc.Podemos utilizar um potencimetro entre 10k e 20kpara este ajuste conforme a figura abaixo:

O pino (4) RS o seletor de Registros. Isso quer dizer que quando este pino est em nvel lgico baixo (0) os dados enviados para o LCD so tratados como comandos e os dados lidos do LCD indicam o seu estado atual (status). Quando este pino est em nvel lgico alto (1), os dados so tratados como caracteres, tanto para leitura como para escrita.Nvel lgico (0): ComandosNvel lgico (1): DadosO pino (5) R/W controla se a operao ser de leitura (1)ou gravao (0)O pino (6) Enable, habilita os comandos do LCD em bordade descida (de 1 para 0). utilizado para iniciar a transferncia de comandos ou caracteres entre o mdulo e as linhas de dados. Quando estiver escrevendo para o display, os dados sero transmitidos apenas a partir de uma transio de high para low (H -> L) deste sinal. No entanto, para ler informaes do display, as informaes estaro disponveis imediatamente aps uma transio L -> H e permanecer l at que o sinal volte para o nvel lgico baixo (0) novamente.Os pinos (7) (14) so o barramento de dados ( 8 bits).Ele trabalha com os oito sinais em paralelo ou ainda pode trabalhar com um barramento de 4 vias (normalmente D4 a D7), mas os dados devem ser transmitidos em dois pacotes. Cada pacote de quatro bits conhecido como nibble. Este um excelente recurso para minimizar o uso de pinos de I/O do microcontrolador, mas ocupa um pouco mais de memria. A deciso de utilizar 8 vias ou 4 vias exclusiva do desenvolvedor do projeto.

Ao alimentar o LCD, a primeira linha fica toda preenchida indicando que o LCD est alimentado corretamente e que no existe nenhum pixel queimado.

Para deix-lo operacional precisamos inici-lo, enviandouma sequncia de comandos com a configurao desejada.A tabela a seguir mostra quais so estes comandos.

Baseados na tabela anterior verificamos que existem diversas configuraes que podem ser atribudas ao LCD. A tabela a seguir mostra as opes disponveis.

Lembre-se que, antes de qualquer operao com o LCD ele precisa ser inicializado utilizando estas informaes da tabela acima. importante salientar que no existe uma ordem especfica para os itens de configurao especificados acima. Eles podem ser enviados em qualquer ordem, uma vez que o bit mais significativo de cada categoria indica o seu grupo de configurao. No entanto para o processo de inicializao, importante que antes de entrarmos nos grupos acima, existe uma ordem que deve ser respeitada. Isso ser visto em um captulo especfico que ir abordar a rotina de inicializao do display.

Como parte integrante do controlador que o LCD utiliza, h uma tabela de caracteres pr-programados que esto prontos para uso imediato. Com isso, todo o trabalho de definir pixel por pixel para os caracteres foi eliminado. Mas h uma desvantagem. Como a maioria dos LCDs so produzidos na sia, ele vem com um conjunto de caracteres especficos. A figura a seguir mostra a tabela existente na maioria dos LCDs. Ela conhecida como ROM Code A00.

Existe outra tabela que tambm encontrada nos LCDs, mas so mais raras. Geralmente os LCDs mais caros possuem esta opo. Novamente, sempre muito importanteler o data sheet do seu mdulo de LCD antes de prosseguir com o desenvolvimento do projeto. A tabela a seguir ilustra os caracteres pertencentes ao ROM Code A02:

Como voc pode reparar, os caracteres acentuados que temos em portugus somente estaro disponveis nesta verso de ROM. Os LCDs so fornecidos com apenas um tabela de caracteres.

Para evitar que os mdulos sejam rgidos no que diz respeito a caracteres exibidos, todos eles possuem uma rea especfica para caracteres criados pelo usurio. Esta reachama-se CG RAM e voltil, ou seja, se desligarmos o LCD ou o reiniciarmos, todas estas informaes sero perdidas. Termos um captulo especfico sobre a CGRAM. Os endereos 000 007 so reservados para caracterescriados pelo usurio. So gravados em memria RAM (CGRAM) e se perdem aodesligar o LCD. Enviamos para o LCD a condio (0 ou 1) de cada pixel docaracter. Sero enviados 8 bytes para cada caracter.

Para cri-lo, definimos como ser nosso caracter com baseem uma matriz 58:

Para criarmos um robozinho, preenchemos a matriz daseguinte forma:

Cada linha tratada como um byte em separado. Cada pontopreenchido representa 1 e cada ponto apagado representa 0

Pelo fato de um byte ter 8 bits e cada linha apenas 5, os3 bits mais significativos sero sempre 0; Agora, basta escrever os bytes:

Com o caracter pronto, basta program-lo na CGRAM enviandoa sequncia de comando correta; Primeiro, o comando SET CGRAM ADRESS + o endereoinicial; Para o primeiro caracter disponvel : 00010000; Em seguida, enviamos os 8 bytes que formam o caracter. Se continuarmos inserindo informaes de bytes, o ponteiropassar para o segundo caracter e assim por diante; Ento, para programarmos os 8 caracteres disponveis,basta enviar o comando SET CGRAM ADRESS+ o endereo000 e passarmos, em seguida, os 64 bytes que formaro os8 novos caracteres; Maiores detalhes sero vistos nos exerccios

Aps ligarmos o LCD e o iniciarmos, o cursor ir para a primeira posio que a 000 (primeira linha x primeira coluna). De acordo com que vamos imputando dados nele, o cursor ir deslocar para as posies seguintes. Este auto-incremento uma facilidade muito interessante, pois dispensa especificar cada posio para cada caractere em separado, economizando (e muito) em linhas de cdigos necessrias.Mas, e se quisermos escrever em um ponto especfico do LCD?Neste caso, podemos especificar exatamente qual o endereo que o cursor dever estar para exibir o caractere desejado. Este dado ser passado para o LCD pelas mesmas vias de dados que passamos um caractere, s que dessa vez ser um comando. De acordo com a Tabela, para entrarmos com um comando para setar um endereo na DDRAM do LCD precisaremos ter o pino RS e RW em nvel lgico baixo e o bit mais significativo precisa estar obrigatoriamente em nvel lgico alto. Com isso podemos enderear at 128 posies e, ao passar o endereo, deveremos somar este bit, ou seja, precisaremos somar o valor 080 ao endereo desejado.Para ilustrar, o endereamento de um display LCD 16X02 o seguinte:

Como devemos, obrigatoriamente fazer com que o bit mais significativo do endereo seja 1, o valor que devemos passar para o LCD obedece figura abaixo:

Para facilitar as contas, segue abaixo o endereamento para a maioria dos LCDs comerciais:

Independente do tamanho do LCD existem sempre 80 posies por linha que podem ser usadas. Como no existem posies suficientes no mostrador do LCD, o texto rotacionado ou deslocado, tanto para a direita como para a esquerda. Portanto este processo deve ser feito cuidadosamente para que no haja confuses durante o endereamento.

Timing uma limitao do LCD e diz respeito ao tempo desincronizao; Independente da velocidade do PIC, existe um tempo mnimoque o LCD precisa para processar as informaes; Se este tempo no for respeitado, o LCD no Funcionar; Este tempos so apresentados no Datasheet do LCD:

Na prtica, podemos utilizar os seguintes tempos:

O LCD baseado nos controladores HD44780 ou KS0066Upossui 8 vias de dados que so enviado de forma paralela; Estes LCDs foram construdos para serem compatveis commicrontroladores antigos de 4 bits; Essa caracterstica nos permite decidir se usaremos o LCDcom 4 ou 8 vias de dados; Lembre-se: os dados continuaro a ter 8 bits, apenas optamospor transmiti-los usando 4 ou 8 vias Para iniciarmos o LCD no modo de transferncia em 8 bitsenviamos o comando:

O controlador HD44780 ou o KS0066U, encontrados na maioria dos mdulos de LCDs alfa-numricos existentes atualmente foram desenvolvidos para serem 100% compatveis com microprocessadores antigos de 4 bits. No entanto esta caracterstica muito til quando precisamos interfacear um microcontrolador.Muitas vezes, durante o desenvolvimento de um projeto, precisamos ter muito cuidado com o nmero de pinos de I/O utilizados, pois normalmente, este o componente mais caro do projeto. Por isso precisamos racionar o uso destes pinos. J pensou voc desenvolvendo um equipamento com um PIC16F628A e ter que migrar para o, por exemplo, PIC16F873A apenas por que faltaram alguns pinos para ligar um LCD?Outro ponto diz respeito miniaturizao, pois atualmente um grande diferencial de cada projeto est neste ponto. Cada vez mais precisamos ter equipamentos que exeram mais funes e ocupem cada vez menos espao. aqui que reside a grande vantagem de se comunicar em quatro vias de dados.Mas como eu vou mandar 1 byte (8 bits) se eu s tenho 4 vias de dados? Uma vez que o display posto no modo de 4 vias, basta mandarmos 2 pacotes de 4 bits cada que o display se encarrega de fazer o resto. Cada pacote de 4 bits conhecido como nibble.Neste modo, apenas as vias de dados D4 a D7 so utilizadas, e as vias D0 a D3 devem ser deixadas flutuando (sem conexo alguma) ou conectadas ao positivo da alimentao, via resistor limitador que tem seu valor entre 4K7 e 47K. No aconselhvel aterr-los, a no ser que o pino R/W tambm esteja aterrado, prevenindo que os pinos sejam configurados como sada. Se o pino for configurado erroneamente como sada e os pinos estiverem diretamente aterrados, os pinos que estiverem com valor lgico 1 podero se queimar.Ao energizar o LCD, ele automaticamente posto no mode de comunicao em 8 vias. Por isso, precisamos inicializ-lo para que possa operar corretamente. Neste ponto h uma pegadinha Como eu fao para inicializar o LCD se ele s possui as vias D4 a D7 e ele est no modo 8 vias?Foi pensando neste problema que os projetistas dos controladores determinaram que o bit que ir configurar o modo 4 vias seria o D4, por isso no precisamos nos preocupar. Basta enviar um comando com o valor 0b001000000 (020) que o LCD entra no modo de 4 vias.A partir destemomento, todas as informaes que sero passadas para o LCD devero ser divididas em 2 nibbles, sendo que o nibble mais significativo deve ser enviado primeiramente, e o nibble menos significativo dever ser enviado logo em seguida.Para inicializarmos em 4 bits, devemos adotar a seguinte seqncia de comandos:

O LCD composto por 6 camadas de materiais distintos que, agrupados, do as caractersticas do display, veja:

1 Filme filtro vertical para polarizar a luz que entra

2 Carcaa de vidro com eletrodos . As formas desses eletrodosiro determinar as formas escuras que aparecem quando o LCDest ligado

3 Tranado

4 Carcaa de vidro com a pelcula de eletrodo comum , comsulcos horizontais para alinhar com o filtro horizontal.

5 Filme filtro horizontal para bloquear / permitir atravs da luz

6 Superfcie reflexiva para enviar luz de volta para espectador

Conhecendo como composto o Display LCD passemos para a parte prtica.A seguir uma configurao muito bsica de um circuito que integra um microcontrolador PIC 16F628A. Para a utilizao com outro modelo de microcontrolador PIC basta escolher os pinos que queremos para cada funo e indic-los no programa.

Vamos analisar o cdigo, todo comentado, necessrio para exibir uma mensagemno LCD, utilizando o PORTD de um PIC16F877a/************************************* INICIO ************************************/#include // microcontrolador utilizado#fuses xt,nowdt,noprotect,put,brownout,nolvp,nocpd,nowrt// configurao dos fusveis#use delay(clock=4000000)#byte porta = 005#byte portb = 006#byte portc = 007#byte portd = 008#byte porte = 009#bit rs = porte.0 // via do LCD que sinaliza recepo de dados ou comando#bit enable = porte.1 // enable do lcd/************* Rotina que envia um COMANDO para o LCD **************/

void comando_lcd(int caracter){rs = 0; // seleciona o envio de um comandoportd = caracter; // carrega o portd com o caracterenable = 1 ; // gera pulso no enabledelay_us(1); // espera 1 microssegundosenable = 0; // desce o pino de enabledelay_us(40); // espera mnimo 40 microssegundosreturn; // retorna}

/************* Rotina que envia um DADO a ser escrito no LCD *************/

void escreve_lcd(int caracter){rs = 1; // seleciona o envio de um dadoportd = caracter; // carrega o portd com o caracterenable = 1; // gera pulso no enabledelay_us(1); // espera 1 microssegundosenable = 0; // desce o pino de enabledelay_us(40); // espera mnimo 40 microssegundosreturn; // retorna}

/******************** Funo para limpar o LCD ********************/

void limpa_lcd(){comando_lcd(001); // limpa LCDdelay_ms (2);return;}

/******************* Inicializao do Display de LCD ********************/

void inicializa_lcd(){comando_lcd(030); // envia comando para inicializar displaydelay_ms(4); // espera 4 milissegundoscomando_lcd(038); // configura LCD, 8 bits, matriz de 75, 2 linhaslimpa_lcd(); // limpa LCDcomando_lcd(0x0c); // display sem cursorcomando_lcd(006); // desloca cursor para a direitareturn; // retorna}

/******************** Configuraes do PIC ********************/

void main(){

// configura microcontroladorsetup_adc_ports (no_analogs);

// configura os trisset_tris_a(0b11011111); // configurao da direo dos pinos de I/Oset_tris_b(0b00000011);set_tris_c(0b11111101);set_tris_d(0b00000000);set_tris_e(0b00000100);

// inicializa os portsporta=000; // limpa portaportb=000; // limpa portbportc=000; // limpa portcportd=000; // limpa portdporte=000; // limpa porteinicializa_lcd(); // inicializa o LCD

/************************* Rotina principal **************************/

while(TRUE) // rotina principal{//Local onde o programa ser escrito}}

Para simplificar o projeto, podemos manter o pino R/W doLCD aterrado, habilitando assim, apenas o modo de gravaoque nos importa; No poderemos ler o STATUS BIT para saber quando p LCDest pronto para o prximo dado; Basta apenas esperar o tempo mnimo para cada funo eexecutar a prxima; Isso no uma deficincia do projeto e sim uma caractersticada maioria dos projetos comerciais; Antes de comearmos a programao, precisamos informarquais os pinos de I/O sero utilizados pelo LCD;

Isso facilitar a portabilidade do projeto para outros PICsou LCDs

#define lcd_enable pin_e1 // pino enable do LCD#define lcd_rs pin_e0 // pino rs do LCD#define lcd_db4 pin_d4 // pino de dados d4 do LCD#define lcd_db5 pin_d5 // pino de dados d5 do LCD#define lcd_db6 pin_d6 // pino de dados d6 do LCD#define lcd_db7 pin_d7 // pino de dados d7 do LCD

/*****************************************************************//* Envio de Nibble para o LCD *//*****************************************************************/

//Esta rotina l o Nibble inferior de uma varivel 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 DADOoutput_bit(lcd_db5, bit_test(dado,1)); //Carrega DB5 do LCD com o bit DADOoutput_bit(lcd_db6, bit_test(dado,2)); //Carrega DB6 do LCD com o bit DADOoutput_bit(lcd_db7, bit_test(dado,3)); //Carrega DB7 do LCD com o bit DADO

//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}

/*****************************************************************//* Envio de Byte para o LCD *//*****************************************************************/

//Esta rotina ir enviar um dado ou um comando para o LCD conforme abaixo:// ENDEREO = 0 -> a varivel DADO ser uma instruo// ENDEREO = 1 -> a varivel DADO ser um caractere

void envia_byte_lcd(boolean endereco, int dado){output_bit(lcd_rs,endereco); // Seta o bit RS para instruo 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 funo}

/*****************************************************************//* Funo para limpar o LCD *//*****************************************************************/

void limpa_lcd(){envia_byte_lcd(0,001); // Envia instruo para limpar o LCDdelay_ms(2); // Aguarda 2ms para estabilizar o LCDreturn; // Retorna ao ponto de chamada da funo}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **/* Inicializa o LCD * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void inicializa_lcd(){output_low(lcd_db4); // Garante que o pino DB4 esto em 0 (low)output_low(lcd_db5); // Garante que o pino DB5 esto em 0 (low)output_low(lcd_db6); // Garante que o pino DB6 esto em 0 (low)output_low(lcd_db7); // Garante que o pino DB7 esto em 0 (low)output_low(lcd_rs); // Garante que o pino RS esto em 0 (low)output_low(lcd_enable); // Garante que o pino ENABLE esto em 0 (low)delay_ms(15); // Aguarda 15ms para estabilizar o LCDenvia_nibble_lcd(003); // Envia comando para inicializar o displaydelay_ms(5); // Aguarda 5ms para estabilizar o LCDenvia_nibble_lcd(002); // CURSOR HOME Envia comando para zerar o //contador de caracteres e retornar posio inicialdelay_ms(1); // Aguarda 1ms para estabilizar o LCDenvia_byte_lcd(0,028); // 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,006); // ENTRY MODE SET Desloca o cursor para a direitareturn; // Retorna ao ponto de chamada da funo}

Vamos fazer um exerccio prtico. O Hardware utilizado o que segue:

Abaixo, o programa correspondente:#include#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP,NOCPD,NOWRT#use delay(clock=4000000)

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** CONSTANTES INTERNAS ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

// Estas so as definies dos pinos que o LCD utiliza.// Definem quais pinos do PIC controlaro os pinos do LCD

#define lcd_enable pin_d1 // pino enable do LCD#define lcd_rs pin_d0 // pino rs (register select)do LCD // (0) para comandos (1) para dados#define lcd_db4 pin_d4 // pino de dados d4 do LCD#define lcd_db5 pin_d5 // pino de dados d5 do LCD#define lcd_db6 pin_d6 // pino de dados d6 do LCD#define lcd_db7 pin_d7 // pino de dados d7 do LCD

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** DEFINIO E INICIALIZAO DOS PORTS ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#byte porta = 005#byte portb = 006#byte portc = 007#byte portd = 008#byte porte = 009

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ENVIO DE NIBBLE PARA O LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

//Esta rotina l o Nibble inferior de uma varivel e envia para o LCD.//1byte = 8 bits = 2 Nibbles//Sero enviados para os pinos db4, db5, db6, db7 do 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 DADOoutput_bit(lcd_db5, bit_test(dado,1)); //Carrega DB5 do LCD com o bit DADOoutput_bit(lcd_db6, bit_test(dado,2)); //Carrega DB6 do LCD com o bit DADOoutput_bit(lcd_db7, bit_test(dado,3)); //Carrega DB7 do LCD com o bit DADO //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}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ENVIO DE BYTE PARA O LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

// Esta rotina ir enviar um dado ou um comando para o LCD conforme abaixo:// ENDEREO = 0 -> a varivel DADO ser uma instruo// ENDEREO = 1 -> a varivel DADO ser um caractere

void envia_byte_lcd(boolean endereco, int dado){output_bit(lcd_rs,endereco); // Seta o bit RS para instruo 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 funo}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * ** * ** ENVIO DE CARACTER PARA O LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /

// Esta rotina serve apenas como uma forma mais fcil de escrever um caractere no display.

void escreve_lcd(char c) // envia caractere para o display{envia_byte_lcd(1,c);}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * ** * ** FUNO PARA LIMPAR O LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * ** * * /

// Como esta operao pode ser muito utilizada, transformando-a em funo// faz com que o cdigo compilado seja menor.

void limpa_lcd(){envia_byte_lcd(0,001); // Envia instruo para limpar o LCD // 0 envio de instruo // 0X01 mostrar tabeladelay_ms(2); // Aguarda 2ms para estabilizar o LCDreturn; // Retorna ao ponto de chamada da funo}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** INICIALIZA O LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /

void inicializa_lcd(){output_low(lcd_db4); // Garante que o pino DB4 esto em 0 (low)output_low(lcd_db5); // Garante que o pino DB5 esto em 0 (low)output_low(lcd_db6); // Garante que o pino DB6 esto em 0 (low)output_low(lcd_db7); // Garante que o pino DB7 esto em 0 (low)output_low(lcd_rs); // Garante que o pino RS esto em 0 (low)output_low(lcd_enable); // Garante que o pino ENABLE esto em 0 (low)delay_ms(15); // Aguarda 15ms para estabilizar o LCDenvia_nibble_lcd(002); // CURSOR HOME Envia comando para zerar o //contador decaracteres e retornar posio inicial (080)delay_ms(1); // Aguarda 1ms para estabilizar o LCDenvia_byte_lcd(0,020); // FUNCTION SET Configura o LCD para //4 bits, 1 linha, fonte 5X7. // 0 envio de instruo 020 mostrar tabelaenvia_byte_lcd(0,0x0C); // DISPLAY CONTROL Display ligado, sem cursor // 0 envio de instruo 0x0C mostrar tabelalimpa_lcd(); // Limpa o LCDenvia_byte_lcd(0,006); // ENTRY MODE SET A cada caracter, incrementa uma posio // 0 envio de instruo 006 mostrar tabelareturn; // Retorna ao ponto de chamada da funo}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** CONFIGURAES DO PIC ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * /

main(){

// Reseta portasporta = 0;portb = 0;portc = 0;portd = 0;porte = 0;

// configura os trisset_tris_a(0xFF); // configurao da direo dos pinos de I/Oset_tris_b(0xFF);set_tris_c(0xFF);set_tris_d(0xFF);set_tris_e(0xFF);

// Inicializa o LCDinicializa_lcd();

//Escreve telaescreve_lcd(O);escreve_lcd(L);escreve_lcd(A);escreve_lcd();escreve_lcd(M);escreve_lcd(U);escreve_lcd(N);escreve_lcd(D);escreve_lcd(O);escreve_lcd(!);

//printf(escreve_lcd,");

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ROTINA PRINCIPAL ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * /

// Como no h outra execuo, a rotina principal fica vazia

while (true){}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** FIM DO PROGRAMA* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ***/}

Normalmente a utilizao do Display LCD apenas uma das funes de uma aplicao prtica, por este motivo, podemos criar uma biblioteca contendo todas as funes de controledo LCD em um arquivo separado do programa principal. E esta biblioteca ser chamada por cada um dos muitos projetos futuros que sero realizados e que utilizem Displays LCD sem a necessidade de reescrev-lo a cada vez.

Para isso criamos um arquivo no bloco de notas ou em qualquer editor de texto e salvamos com o nome de LCD.h. Este arquivo dever ser salvo na mesma pasta onde se encontra o programa principal do seu projeto, no qual dever serincludauma linha de comando que inclua todas as funes desta biblioteca e as tornem disponveis no programa principal.

Exemplo de declarao da biblioteca LCD.h no programa principal:

#include#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP,NOCPD,NOWRT#use delay(clock=4000000)/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** CONSTANTES INTERNAS ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */// Estas so as definies dos pinos que o LCD utiliza.// Definem quais pinos do PIC controlaro os pinos do LCD#define lcd_enable pin_d1 // pino enable do LCD#define lcd_rs pin_d0 // pino rs (register select)do LCD // (0) para comandos (1) para dados#define lcd_db4 pin_d4 // pino de dados d4 do LCD#define lcd_db5 pin_d5 // pino de dados d5 do LCD#define lcd_db6 pin_d6 // pino de dados d6 do LCD#define lcd_db7 pin_d7 // pino de dados d7 do LCD#INCLUDE // Declarao da biblioteca do LCD//Continuao do programa.

Abaixo mostrado todo ocontedodo arquivo lcd.h, incluindo novas funes que foram includas a pedido dos leitores do Blog e que sero explicadas no prprio cdigo.

Conteudo do arquivo lcd.h:

/***************************************************************************//* Rotinas para o LCD *//***************************************************************************/

//Este o bloco com as rotinas necessrias para manipular o LCD

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Envio de Nibble para o LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

//Esta rotina l o Nibble inferior de uma varivel 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 DADOoutput_bit(lcd_db5, bit_test(dado,1)); //Carrega DB5 do LCD com o bit DADOoutput_bit(lcd_db6, bit_test(dado,2)); //Carrega DB6 do LCD com o bit DADOoutput_bit(lcd_db7, bit_test(dado,3)); //Carrega DB7 do LCD com o bit DADO

//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 funo}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Envio de Byte para o LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

//Esta rotina ir enviar um dado ou um comando para o LCD conforme abaixo:// ENDEREO = 0 -> a varivel DADO ser uma instruo// ENDEREO = 1 -> a varivel DADO ser um caractere

void envia_byte_lcd(boolean endereco, int dado){output_bit(lcd_rs,endereco); // Seta o bit RS para instruo 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 funo}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Envio de caractere para o LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */// Esta rotina serve apenas como uma forma mais fcil de escrever um caractere// no display. Ela pode ser eliminada e ao invs dela usaremos diretamente a// funo envia_byte_lcd(1,"); ou// envia_byte_lcd(1,);

void escreve_lcd(char c)// envia caractere para o display{envia_byte_lcd(1,c);}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Funo para limpar o LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */// Como esta operao pode ser muito utilizada, transformando-a em funo// faz com que o cdigo compilado seja menor.

void limpa_lcd(){envia_byte_lcd(0,001); // Envia instruo para limpar o LCDdelay_ms(2); // Aguarda 2ms para estabilizar o LCDreturn; // Retorna ao ponto de chamada da funo}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Inicializa o LCD ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void inicializa_lcd(){output_low(lcd_db4); // Garante que o pino DB4 esto em 0 (low)output_low(lcd_db5); // Garante que o pino DB5 esto em 0 (low)output_low(lcd_db6); // Garante que o pino DB6 esto em 0 (low)output_low(lcd_db7); // Garante que o pino DB7 esto em 0 (low)output_low(lcd_rs); // Garante que o pino RS esto em 0 (low)output_low(lcd_enable); // Garante que o pino ENABLE esto em 0 (low)delay_ms(15); // Aguarda 15ms para estabilizar o LCDenvia_nibble_lcd(003); // Envia comando para inicializar o displaydelay_ms(5); // Aguarda 5ms para estabilizar o LCDenvia_nibble_lcd(003); // Envia comando para inicializar o displaydelay_ms(5); // Aguarda 5ms para estabilizar o LCDenvia_nibble_lcd(003); // Envia comando para inicializar o displaydelay_ms(5); // Aguarda 5ms para estabilizar o LCDenvia_nibble_lcd(002); // CURSOR HOME Envia comando para zerar o//contador de caracteres e retornar posio// inicial (080).delay_ms(1); // Aguarda 1ms para estabilizar o LCDenvia_byte_lcd(0,028); // 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,006); // ENTRY MODE SET Desloca o cursor para a direitareturn; // Retorna ao ponto de chamada da funo}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Define inicio da escrita ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *///Esta funo foi adicionada e serve para se definir em que posio do LCD deseja-se//iniciar a escrita. Para isto basta chamar a Funo caracter_Inicio() indicando a//linha e a coluna onde o cursor ser posicionado antes de se mandar escrevervoid caracter_inicio(int linha, int coluna)//define a posico de inicio da frase{int16 posicao=0;if(linha == 1){posicao=080; //Se setado linha 1, end incial 080}if(linha == 2){posicao=0xc0; //Se setado linha 2, end incial 0xc0}posicao=posicao+coluna; //soma ao end inicial, o numero da colunaposicao; //subtrai 1 para corrigir posioenvia_byte_lcd(0,posicao);return;}/***************************************************************************//* Final das rotinas para o LCD *//***************************************************************************/

Agora veremos um exemplo de aplicao prtica da utilizao desta biblioteca:#include#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP,NOCPD,NOWRT#use delay(clock=4000000)

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** CONSTANTES INTERNAS ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

// Estas so as definies dos pinos que o LCD utiliza.// Definem quais pinos do PIC controlaro os pinos do LCD

#define lcd_enable pin_d1 // pino enable do LCD#define lcd_rs pin_d0 // pino rs (register select)do LCD // (0) para comandos (1) para dados#define lcd_db4 pin_d4 // pino de dados d4 do LCD#define lcd_db5 pin_d5 // pino de dados d5 do LCD#define lcd_db6 pin_d6 // pino de dados d6 do LCD#define lcd_db7 pin_d7 // pino de dados d7 do LCD

#INCLUDE // Declarao da biblioteca do LCD/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** DEFINIO E INICIALIZAO DOS PORTS ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */#byte porta = 005#byte portb = 006#byte portc = 007#byte portd = 008#byte porte = 009/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** CONFIGURAES DO PIC ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * /main(){// Reseta portasporta = 0;portb = 0;portc = 0;portd = 0;porte = 0;// configura os trisset_tris_a(0xFF); // configurao da direo dos pinos de I/Oset_tris_b(0xFF);set_tris_c(0xFF);set_tris_d(0xFF);set_tris_e(0xFF);// Inicializa o LCDinicializa_lcd();//Limpa a tela do LCDlimpa_lcd();/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ROTINA PRINCIPAL ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * /while (true){caracter_inicio(1,6); //define o ponto de inicio da frase //Linha 1 e coluna 6printf(escreve_lcd,O BLOG); //escreve no LCD

caracter_inicio(2,4); //define o ponto de inicio da frase //Linha 2 e coluna 4printf(escreve_lcd,DO MARCELO); //escreve no LCD}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** FIM DO PROGRAMA* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ***/}

Controlando um Display LCD(Liquid Crystal Display)O objetivo desta aula criar uma interface Serial para controlar um display LCD 16x2, compatvel comHD44780.Os LCDs compatveis com processadores HD44780 trabalham com um bus de dados paralelo (interfaces entre dispositivos externos de 4 ou 8 bits). Mas atualmente voc pode comprar displays LCD que utilizam comunicao Serial. Isso possvel, pois algumas empresas adaptam uma plaquinha contendo um microcontrolador PIC ou quaisquer outros, para torn-los seriais. A maioria desses displays seriais usam um microcontrolador PIC 16F627 ou 16F628 de 18 pinos, mais que suficiente para interfacear um display LCD configurado para trabalhar com um Bus de dado de 4 bits. Como estamos usando a verso free do compilador da CCS, iremos criar nosso driver para tornar um LCD serial, um PIC 16F877 (a maioria dos pinos no sero usados), portanto, o ideal seria usar um microcontrolador pequeno, para tornar o circuito compacto e menos dispendioso.As vantagens de se criar um dirver e tornar um display bus serial, so:

Usa somente um fio para fazer a comunicao com o LCD;Facilidade em escrever dados no display LCD;Facilidade em desenvolver circuitos microcontrolados usando LCD;Produtividade no desenvolvimento de projetos baseados em LCD.Figura 1- Display LCD 16x2 com backlight

Os mdulosLCDsso compostos de memriaROM, memriaRAMe dois ou mais micro processadores. A maioria deles dispe de um espao de memria chamada CGRAM, que permite ao usurio desenhar at 8 caracteres personalizados (para cada caracter so necessrios 8 bytes).H display LCD de vrios tamahos e caractersticas venda no mercado. Nesta aula iremos usar um MduloLCDde2x16(2 linhas por 16 caracteres) combacklight(luz de fundo), e compatvel com o processadorHD44780.Tabela 1- Pinagem do mdulo LCD 2x16 compatvel (HD44780)PinoDescrio

1VSS-Terra/GND (Alimentao 0v).

2VDD- (Alimentao +5v ).

3VO- Tenso para ajuste do contraste.

4RS- (Register Select) Seleciona Dado/Comando.

5R/W- (Read/Write) Seleciona leitura/escrita.

6E- (Enable) Habilita/desabilita sinal.

7D0Barramento de dados.

8D1

9D2

10D3

11D4

12D5

13D6

14D7

15LED+Alimentao (Anodo Backlight).

16LED-Alimentao (Catodo Backlight).

A tabela acima descreve as caractersticas de cada pino do mduloLCD. O pino1(VSS) ligado ao negativo da fonte de alimentao (0v), e o pino2(VDD) ao positivo (+5v). O pino3(VO) usado para ajustar o contraste dos caracteres; ligado a um Trim-pot de10kohm. O pino4(RS) utilizado para avisar ao mduloLCDse o que ser enviado posteriormente umaInstruo(comando de controle), ou umDado(caracter a ser impresso no display). J o pino 5 (R/W) usado paraEscreverouLum dado noLCD. Como nesse projeto s iremos escrever no LCD, esse pino poder ficar aterrado (0v). O pino6(E) usado para habilitar ou desabilitar oLCD. Deveremos ativ-lo (E= 1) apenas quando o display for acessado. Os pinos7..14(D0...D7) so usados para interfacear o LCD com microcontroladores (no nosso caso, o PIC 16F877).Os pinos15e16(LED+eLED-) s estaro disponveis se o mdulo adquirido tiverbacklight(luz de fundo). Para controlar a luminosidade acrescenta-se um Trim-pot de100ohmentre esses pinos. O objetivo dobacklight facilitar a leitura das informaes no escuro pelo usurio.Tabela 2- Informaes sobre configurao e instrues para controle do mdulo LCD.INSTRUORSR/WD7D6D5D4D3D2D1D0DESCRIOTempo

Limpa Display0000000001Limpa o display e toda a memria. Retorna o curso para a primeira linha e primeira coluna.1,6 ms

Cursor no incio da tela.000000001xRetorna o curso para seu lugar de origem e o display volta ao estado normal de funcionamento.1,6 ms

Fixa modo defuncionamento00000001IDSHDefine a direo de movimento do cursor ou da tela. ID incrementa/decrementa o endereo de memria.Quando:ID=0 cursor move-se p/ esquerda.Quando:ID=1 cursor move-se p/ direita.Quando:SH=1 o texto move-se com a entrada de um novo caracter. SeSH=0, o texto no movido.1,6 ms

Controle do display0000001DCBD=1 liga o display,D=0 desliga.C=1 liga o cursor,C=0 desliga.B=1 cursor piscante, seC=1.40us

Move o cursor ou texto000001SCRLxxSC=0 move o cursor.SC=1 move o texto.RL=1 move para a direita.RL=0 move para a esquerda.40us

INSTRUORSR/WD7D6D5D4D3D2D1D0DESCRIOTempo

Configurao do LCD00001DLNFxxComunicao:DL=1, se comunica com 8 bits.DL=0, se comunica com 4 bits.Quantidade de linha:N=0, somente 1 linha.N=1, de 2 ou mais linhas.Tamanho da fonte dos caracter:F=0, matriz 5x7.F=1, matriz 5x10.40us

Posiciona na memria001AAAAAAAA - Define o endereo de memria para gravao ou leitura.40us

Leitura do Flag Busy01FCCCCCCCLeitura do contador de endereos (C) e do flag (F). O flagF, indica que uma operao est sendo executada.SeF=0, controlador ocioso e pronto para receber comandos.40us

Escreve na memria10DDDDDDDDGrava o byte (DDDDDDDD) no endereo de memria apontado pelo contador de endereos.40us

L dado na memria11DDDDDDDDL o byte (DDDDDDDD) na memria, apontado pelo contador de endereos.40us

Figura 2- Procedimentos para inicializar o Mdulo LCD compatvel (HD44780).

Observe no fluxograma acima que aps ligar o mdulo LCD, espera-se por mais de 30ms antes de se enviar os comandos de controle. Isso necessrio para que a tenso no mdulo LCD estabilize.

Veja abaixo a seqncia detalhada para inicializar o mdulo LCD:a)Ligar o LCD;b)Aguardar 30ms;c)Habilitar o envio de comandos (RS=0);d)Colocar o byte comando/dados na via de dados (DB7...DB0);e)Fazer com que o pino6(E) doLCDv a nvel0(zero);f)Aguardar uns 20ms;g)Fazer com que o pino6(E) doLCDv a nvel 1 (um);h)Aguardar uns 20ms.Para escrever um byte deCOMANDOno display LCD, proceda conforme a seqncia abaixo:a)RS=0,R/W=0,E=0

b)Einvia-se o byte decomandona via (DB7...DB0)

c)RS=0, R/W=0, E=1

d)RS=0, R/W=0, E=0

c)Habilitar o envio de comandos (RS=0);d)Colocar o byte decomandona via de dados (DB7...DB0);e)Fazer com que o pino6(E) doLCDv a nvel 0 (zero);f)Aguardar uns 40us;g)Fazer com que o pino6(E)doLCDv a nvel 1 (um);h)Aguardar uns 40us;

Para enviar qualquer comando para oLCDrepetir os passos:d),e),f),g)eh).

Para escrever um byte deDADOno display LCD, proceda conforme a seqncia abaixo:a)RS=1,R/W=0,E=0

b)Einvia-se o byte dedadosna via (DB7...DB0)

c)RS=1,R/W=0,E=1

d)RS=1,R/W=0,E=0

c)Habilitar o envio de comandos (RS=1);d)Colocar o byte de dados na via de dados (DB7...DB0);e)Fazer com que o pino6(E) do LCD v a nvel 0 (zero);f)Aguardar uns 40us;g)Fazer com que o pino6(E) do LCD v a nvel 1 (um);h)Aguardar uns 40us.

Para enviar qualquer dado para oLCDrepetir os passos:d),e),f),g)eh).Fonte 1 -Driver para controle de LCD usando o PIC16F877//--------------------------------------------------------------------------------------------------//Curso USB/Serial//Programa:DriverLCD.c//Driver para controle de LCD no modo 4 bits.//Configurado para o PIC16F877 - 4Mhz.//Com pequenas mudanas possvel usar PIC16F627 ou 16F628.//LCD Padro: Microprocessador HD44780.//www.rogercom.com//[email protected]//Antonio Rogrio Messias//Data: 20/11/2005//---------------------------------------------------------------------------//Pinos do PIC16F877 para interfacear o LCD//---------------------------------------------------------------------------#defineLCD_PIN_RS pin_d7 //Seleciona Registrador.#defineLCD_PIN_ENABLE pin_d6 //Habilita LCD.#defineLCD_PIN_RW pin_d5 //Nvel 0 = Escrita no LCD.//---------------------------------------------------------------//Bus de 4 bits#defineLCD_DADO_7 pin_b7 // --> pino 14 LCD.#defineLCD_DADO_6 pin_b6 // --> pino 13 LCD.#defineLCD_DADO_5 pin_b5 // --> pino 12 LCD.#defineLCD_DADO_4 pin_b4 // --> pino 11 LCD.//---------------------------------------------------------------------------#defineLCD_MOVE_CURSOR_ESQ 0x10 //Move cursor para esquerda.#defineLCD_MOVE_CURSOR_DIR 0x14 //Move cursor para direita.#defineLCD_MOVE_DISPLAY_ESQ 0x18 //Move o texto para a esquerda.#defineLCD_MOVE_DISPLAY_DIR 0x1C //Move o texto para a direita.#defineLCD_MODO_8_BITS 0x38 //8 bit de dados, 2 linhas (fonte 5x7).#defineLCD_MODO_4_BITS 0x28 //4 bit de dados, 2 linhas (fonte 5x7).#defineLCD_CONTROLE_DISPLAY 0x0E //00001110#defineLCD_FIXA_MODO 0x06 //Fixa modo de funcionamento do display.#defineLCD_DISPLAY_ON 0x0C //Liga display.#defineLCD_DISPLAY_OFF 0x08 //Desliga Display sem apagar os dados na memria.#defineLCD_SET_DD_RAM 0x80 //Linha 1 posio 1.#defineLCD_LINHA_1 0x80//DDRAM nicio da primeira linha.#defineLCD_LINHA_2 0xC0 //DDRAM nicio da segunda linha.#defineLCD_LIMPA_DISPLAY 0x01 //Limpa o display e apaga a memria.#defineLCD_CURSOR_HOME 0x02 //Pe curso no incio da tela.#defineLCD_CURSOR_OFF 0x0C //desliga cursor.#defineLCD_CURSOR_PISCANTE 0x0D //cursor barra piscante.#defineLCD_CURSOR_LINHA 0x0E //linha fixa.#defineLCD_CURSOR_LINHA_BARRA 0x0F //linha fixa e barra piscante.//---------------------------------------------------------------------------//Funes para controle do LCD//---------------------------------------------------------------------------voidLCD_Modo_Comando(void);voidLCD_Modo_Dado(void);voidLCD_Escreve_Modo_4_bits(charByteValor);voidLCD_EnviaChar(charcarac);voidLCD_EnviaString(char*Str);voidLCD_Gotoxy(intcolunaX,intLinhaY);voidLCD_StringCentro(char*Texto,intLinhaY);voidLCD_LimpaDisplay(void);voidLCD_CursorHome(void);voidLCD_TrocaCursor(intTipo);voidLCD_PiscaString(intColunaX,intLinhaY,char*String,intVezes);voidLCD_Cria_Car_CGRAM(intEndereco,unsigned charcodigo[]);voidLCD_Configura(void);//---------------------------------------------------------------------------//Faz o LCD aceitar Comandos.//---------------------------------------------------------------------------voidLCD_Modo_Comando(void){output_low( LCD_PIN_RS );//RS em 0 - COMANDO.delay_us(50);}//---------------------------------------------------------------------------//Faz o LCD aceitar Dados.//---------------------------------------------------------------------------voidLCD_Modo_Dado(void){output_high( LCD_PIN_RS );//RS em 1 - DADO.delay_us(50);}//---------------------------------------------------------------------------//Escreve 8 bits de dados no modo 4 bits no LCD.//---------------------------------------------------------------------------voidLCD_Escreve_Modo_4_bits(intByteValor){//===> 20Mhz usar delay de 20us. //===> 4Mhz usar delay de 2us.//Envia o nibble mais significante (MSB) para o LCD.output_bit(LCD_DADO_7,bit_test(ByteValor, 7) );output_bit(LCD_DADO_6,bit_test(ByteValor, 6) );output_bit(LCD_DADO_5,bit_test(ByteValor, 5) );output_bit(LCD_DADO_4,bit_test(ByteValor, 4) );delay_us(2);output_high( LCD_PIN_ENABLE );delay_us(2);output_low( LCD_PIN_ENABLE );//Clock.delay_us(2);//Envia o nibble menos significante (LSB) para o LCD.output_bit(LCD_DADO_7,bit_test(ByteValor, 3) );output_bit(LCD_DADO_6,bit_test(ByteValor, 2) );output_bit(LCD_DADO_5,bit_test(ByteValor, 1) );output_bit(LCD_DADO_4,bit_test(ByteValor, 0) );delay_us(2);output_high( LCD_PIN_ENABLE );delay_us(2);output_low( LCD_PIN_ENABLE );//Clock.}//---------------------------------------------------------------------------//Envia um caracter para o LCD.//---------------------------------------------------------------------------voidLCD_EnviaChar(charcarac){LCD_Escreve_Modo_4_bits(carac);}//---------------------------------------------------------------------------//Envia uma string de caracteres para o LCD.//---------------------------------------------------------------------------voidLCD_EnviaString(char*Str)//Envia um texto para o LCD.{LCD_Modo_Dado();while(*Str) //Loop enquanto no for 'encontrado '\0' (final da string).LCD_EnviaChar(*Str++); //Envia caracter a caracter para o display LCD.}//---------------------------------------------------------------------------//Posisiona o cursor na na coluna X linha do LCD.//---------------------------------------------------------------------------voidLCD_Gotoxy(intcolunaX,intLinhaY)//Posiciona na coluna e linha do display de LCD.{LCD_Modo_Comando();if(LinhaY < 2)//se for a linha 1.LCD_EnviaChar(LCD_LINHA_1+colunaX);//Endereo de memria da 1a. linha do LCD (0x80).else//se no 2a linha.LCD_EnviaChar(LCD_LINHA_2+colunaX);//Endereo de memria da 2a. linha do LCD (0xC0).LCD_Modo_Dado();//Volta ao modo Dado.}//---------------------------------------------------------------------------//Envia uma string no centro da linha do LCD.//---------------------------------------------------------------------------voidLCD_StringCentro(char*Texto,intLinhaY){intMetade;Metade=strlen(Texto)/2;//Acha a metade do texto.LCD_Gotoxy(8-Metade, LinhaY);//Centraliza. O 8 o centro da tela do display (16 Div. 2).LCD_EnviaString(Texto);}//---------------------------------------------------------------------------//Limpa o LCD.//---------------------------------------------------------------------------voidLCD_LimpaDisplay(void)//Limpa o display e a memria do LCD posicionando na primeira linha.{LCD_Modo_Comando();//Pe no modo Comando.LCD_EnviaChar(LCD_LIMPA_DISPLAY);//Limpa o display.LCD_Modo_Dado();//Volta ao modo Dado.}//-------------------------------------------------------------------------------//Pe o curso na posio superior esquerda do display.//-------------------------------------------------------------------------------voidLCD_CursorHome(void)//Limpa o display e a memria do LCD posicionando na primeira linha.{LCD_Modo_Comando();//Pe no modo Comando.LCD_EnviaChar(LCD_CURSOR_HOME);//Pe o curso na posio superior esquerda do display.LCD_Modo_Dado();//Volta ao modo Dado.}//---------------------------------------------------------------------------//Muda o tipo de cursor do LCD.//---------------------------------------------------------------------------voidLCD_TrocaCursor(intTipo)//Muda o tipo de cursor do display do LCD.{LCD_Modo_Comando();//Pe no modo Comando.LCD_EnviaChar(Tipo);//Muda o tipo de cursor.LCD_Modo_Dado();//Volta ao modo Dado.}//--------------------------------------------------------------------------------------------//Pisca uma string na linha/coluna do LCD, definindo um intervalo.//--------------------------------------------------------------------------------------------voidLCD_PiscaString(intColunaX,intLinhaY,char*String,intVezes){charApaga[16];//para armazenar 16 espaos.intConta=0;intTamaString;TamaString =strlen(String);//acha o tamanho do texto.memset(Apaga,' ',TamaString);//preenche com espaos a varivel 'Apaga'.Apaga[TamaString] = '\0'; //finaliza a string.while( Conta < Vezes )//enquanto nenhuma tecla for pressionada.{LCD_Gotoxy(ColunaX, LinhaY);//posiciona texto.LCD_EnviaString(String);//escreve texto.delay_ms(200);//aguarda.LCD_Gotoxy(ColunaX, LinhaY);//posiciona espaos.LCD_EnviaString(Apaga);//apaga texto.delay_ms(200);//aguarda.Conta++;}}//-----------------------------------------------------------------------------------------------------------------//Cria at 8 caracteres personalizados na CGRAM.//Endereo para cada caracter: 0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78//Aps a criao, os novos caracteres podem ser acessados respectivamente//atravs dos seguintes caracteres ASC: 0, 1, 2, 3, 4, 5, 6 e 7.//Para cada caracter so necessrios passa 8 bytes atravs da matriz codigo[].//-----------------------------------------------------------------------------------------------------------------voidLCD_Cria_Car_CGRAM(intEndereco,unsignedcharcodigo[] ){inti;LCD_Modo_Comando();LCD_EnviaChar(Endereco);//Endereo para criar o caracter.LCD_Modo_Dado();for(i=0; i