Você está na página 1de 111

www.mecatronicadegaragem.blogspot.com.

br

Comunicao de LCD em 4 vias

Eduardo Souza Ramos 22 de setembro de 2005

www.mecatronicadegaragem.blogspot.com.br

NDICE
NDICE..........................................................................................................................................................................2 INTRODUO..............................................................................................................................................................5 Captulo 1 - O LCD ALFA-NUMRICO ........................................................................................................................9 Figura 1: Display 08X02 sem back-light.........................................................................................................9 Figura 2: Display 16X01 sem back-light.........................................................................................................9 Figura 3: Display 16X02 com back-light.........................................................................................................9 Figura 4: Display 16X04 com back-light.......................................................................................................10 Figura 5: Display 20X01 sem back-light.......................................................................................................10 Figura 6: Display 20X02 sem back-light.......................................................................................................10 Figura 7: Display 20X04 com back-light.......................................................................................................10 Parte 1 - Os caracteres .......................................................................................................................................11 Figura 8: O padro de cada clula de um display 5X7 (em mm).................................................................11 Parte 2 - Conexes..............................................................................................................................................12 Tabela 1: Descrio das funes dos pinos do LCD ...................................................................................12 Figura 9: Controle de contraste de um LCD ................................................................................................13 Parte 3 - Comandos do LCD ...............................................................................................................................14 Figura 10: LCD 16X02 energizado, mas no inicializado. ...........................................................................14 Tabela 2: Instrues para inicializao e configurao do LCD ..................................................................14 Tabela 3: Configuraes possveis para o LCD ..........................................................................................15 Parte 4 - Tabelas de Caracteres .........................................................................................................................17 Tabela 4: Os caracteres do ROM Code A00 ...............................................................................................17 Tabela 5: Os caracteres do ROM Code A02 ...............................................................................................18 Parte 5 - Endereamento ....................................................................................................................................19 Figura 11: Endereamento direto para um LCD 16X02...............................................................................19 Figura 12: Endereamento com deslocamento para um LCD 16X02 .........................................................19 Figura 13: Endereamentos com deslocamento para diversos LCDs.........................................................20 Parte 6 - Rotacionando o LCD ............................................................................................................................20 Parte 7 - A CGRAM Caracteres definidos pelo usurio ...................................................................................20 Figura 14: O modelo do caractere na CG RAM...........................................................................................21 Figura 15: Criando um rob na CG RAM.....................................................................................................21 Figura 16: O rob, traduzido em bits............................................................................................................21 Parte 8 - Transferncia em 8 bits ........................................................................................................................23 Figura 17: Inicializando em 8 vias................................................................................................................23 Parte 9 - Transferncia em 4 bits ........................................................................................................................24 Figura 18: Inicializando em 4 vias................................................................................................................25 Parte 10 - Timing .................................................................................................................................................26 Figura 19: Diagrama de temporizao para o LCD .....................................................................................26 6: Diagrama de temporizao real para o LCD............................................................................................27 Captulo 2 - O HARDWARE .......................................................................................................................................31 Figura 20: Esquemtico para a placa de testes de LCD .............................................................................31 Figura 21: PCI lado dos componentes.........................................................................................................32 Figura 22: PCI lado da solda (trilhas)...........................................................................................................32 Figura 23: Placa de testes conectada ao McPlus via conector ICSP..........................................................32 Captulo 3 - O SOFTWARE ........................................................................................................................................35 Parte 1 Comunicao em 8 vias pela McLAB2 ................................................................................................35 Parte 2 Comunicao em 4 vias pela McLAB2 ................................................................................................38 Definio de constantes ...............................................................................................................................38 Rotina de envio de um nibble ....................................................................................................................38 Rotina de envio de um Byte .........................................................................................................................39 Funo para Limpar o LCD..........................................................................................................................39 Inicializao do LCD.....................................................................................................................................40 Parte 3 Comunicao em 4 vias pela placa de testes .....................................................................................42 Definio de constantes ...............................................................................................................................42 Outras alteraes .........................................................................................................................................42 Exerccio 1 Inicializando o LCD e Ol Mundo.......................................................................................................45 McLAB2 ...............................................................................................................................................................45 Figura 24: Fluxograma para a placa McLAB2 .............................................................................................45 Placa de testes ....................................................................................................................................................50 Figura 25: Fluxograma para a placa de testes ............................................................................................50 Exerccio 2 A funo PRINTF() ...............................................................................................................................57 McLAB2 ...............................................................................................................................................................58 Tutorial LCD em 4 vias 2

www.mecatronicadegaragem.blogspot.com.br
Figura 26: Fluxograma para a placa McLAB2 .............................................................................................58 Placa de testes ....................................................................................................................................................63 Figura 27: Fluxograma para a placa de testes ............................................................................................63 Exerccio 3 Rotacionando o display ........................................................................................................................71 McLAB2 ...............................................................................................................................................................72 Placa de testes ....................................................................................................................................................76 Exerccio 4 Criando caracteres................................................................................................................................83 Figura 28: Fluxograma para o exemplo 4 ....................................................................................................83 McLAB2 ...............................................................................................................................................................84 Placa de testes ....................................................................................................................................................89 Exerccio 5 Uma pequena animao.......................................................................................................................97 Figura 29: Fluxograma para a animao nas placas McLAB2 e de testes .................................................97 McLAB2 ...............................................................................................................................................................98 Placa de testes ..................................................................................................................................................103 CONSIDERAES FINAIS......................................................................................................................................111

Tutorial LCD em 4 vias

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

www.mecatronicadegaragem.blogspot.com.br

INTRODUO
A idia deste material 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. Devido sua simplicidade, estes LCDs no so avanados e 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. Os testes foram executados em uma placa Mosaico McLAB2 e em uma placa confeccionada para esta finalidade. Os diagramas para esta placa encontram-se no captulo referente ao hardware. Este material foi desenvolvido utilizando o MPLAB 7.21 e o compilador PCWH 3.168 (verso gratuita). Estes procedimentos tambm foram testados em Assembly, mas est fora do escopo deste trabalho. Para programao e gravao do microcontrolador existente nas placas utilizei o McPLUS (tambm da Mosaico). Isto garantiu uma perfeita integrao ao MPLAB e s caractersticas de gravao in circuit (ICSP). Os PICs testados foram o PIC16F628A, PIC16F877A e o PIC18F452.

Tutorial LCD em 4 vias

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

www.mecatronicadegaragem.blogspot.com.br

Captulo 1 O LCD Alfa-numrico

Tutorial LCD em 4 vias

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

www.mecatronicadegaragem.blogspot.com.br

Captulo 1 - O LCD ALFA-NUMRICO


Existem, comercialmente, diversos tipos e tamanhos de LCD alfanumricos que podem ser incorporados a um microcontrolador PIC. Os mais comuns so os gerenciados por um processador Hitachi HD44780. Apesar de ter sido descontinuado, ainda o mais comumente encontrado, assim como os equivalentes de outros fabricantes. Maiores detalhes sobre este processador podem ser encontrados no data sheet do fabricante. Veja no link http://cn.renesas.com/media/products/lcd/discontinued_products/d_e780u.pdf . Os displays so fornecidos em diversos formatos e tamanhos e so sempre especificados em nmero de caracteres exibidos, no formato de colunas e linhas, sendo os mais comuns os 08x02 (oito colunas por duas linhas), 16X01 (16 colunas por 1 linha), 16X02 (16 colunas por 2 linhas), 16X04 (16 colunas por 4 linhas), 20X01 (20 colunas por 1 linha), 20X02 (20 colunas por 2 linhas) e 20X04 (20 colunas por 4 linhas). Estes so alguns exemplos:

Figura 1: Display 08X02 sem back-light

Figura 2: Display 16X01 sem back-light

Figura 3: Display 16X02 com back-light

Tutorial LCD em 4 vias

www.mecatronicadegaragem.blogspot.com.br

Figura 4: Display 16X04 com back-light

Figura 5: Display 20X01 sem back-light

Figura 6: Display 20X02 sem back-light

Figura 7: Display 20X04 com back-light

Alguns mdulos possuem iluminao em "back-light" e esto disponveis nas cores (monocromticas) azul, mbar, verde entre outras. Mas, no fundo, todos eles so compatveis e podem ser controlados pelo PIC exatamente da mesma maneira. Isto importante para que, no futuro, uma rotina desenvolvida para um LCD 16X02 possa ser utilizada para controlar um LCD 20X04 sem a necessidade de alterao de cdigo.
Tutorial LCD em 4 vias 10

www.mecatronicadegaragem.blogspot.com.br

Parte 1 - Os caracteres Basicamente, cada "clula" (caractere) do LCD composto de 8 pixels na horizontal e de 5 pixels na vertical, ou seja, cada "clula" representada da seguinte forma (todas as medidas so em mm):

Figura 8: O padro de cada clula de um display 5X7 (em mm)

Estes caracteres so conhecidos como 5X7, uma vez que a linha inferior normalmente reservada para o cursor. Existem tambm displays que possuem 11 pixels de altura. Os caracteres deste LCD so conhecidos como 5X10 e tem a vantagem de que no existe a distncia entre a primeira e a segunda linha. Os caracteres podem parecer contguos.

Tutorial LCD em 4 vias

11

www.mecatronicadegaragem.blogspot.com.br
Parte 2 - Conexes Basicamente os LCDs alfa numricos seguem um padro de especificao de interface, onde esto presentes 14 pinos de acesso (para os LCDs sem iluminao em "back-light") ou 16 pinos (para os que possuem iluminao em "back-light"). Na verdade, estes pinos so pads soldveis para a insero de conectores IDC e so classificados em 8 pinos para controle de dados, trs linhas de controle e trs linhas de alimentao. Iremos detalhar cada um a seguir. As conexes esto dispostas em 1 linha de 14 (ou 16) pinos lado a lado, onde podemos utilizar uma barra de pinos SIL ou em duas linhas de 7 (ou 8) pinos, onde nos valeremos de um conector DIL. Na figura 1 podemos ver um exemplo de conector DIL e na figura 2 o exemplo mostra um display com conexo SIL. Na maioria dos displays, a pinagem est impressa e torna mais fcil a identificao de cada um. Mas, nos casos onde no h identificao impressa, lembre-se que o pino 1 sempre o terra e deve possuir uma trilha mais larga ou estar aterrado na carcaa em algum ponto da trilha. A funo de cada pino resumida de acordo com a tabela abaixo:
Pino 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Nome Vss Vdd Vo RS R/W E D0 D1 D2 D3 D4 D5 D6 D7 A K Funo Terra Positivo (normalmente 5V)

Contraste do LCD. s vezes tambm chamado de Vee


Register Select Read/Write Enable Bit 0 do dado a ser escrito no LCD (ou lido dele). Bit 1 do dado a ser escrito no LCD (ou lido dele). Bit 2 do dado a ser escrito no LCD (ou lido dele). Bit 3 do dado a ser escrito no LCD (ou lido dele). Bit 4 do dado a ser escrito no LCD (ou lido dele). Bit 5 do dado a ser escrito no LCD (ou lido dele). Bit 6 do dado a ser escrito no LCD (ou lido dele). Bit 7 do dado a ser escrito no LCD (ou lido dele). Anodo do back-light (se existir back-light). Catodo do back-light (se existir back-light).

Tabela 1: Descrio das funes dos pinos do LCD

Apesar dos LCDs serem projetados para trabalharem com 5V, consumindo apenas alguns miliampres, tenses entre 4,5V e 6V funcionam perfeitamente. Alguns mdulos tambm funcionam com 3V. Por isso, o mais indicado sempre ler o data sheet do LCD que voc possui para saber melhor seus recursos e limitaes. Por estas razes que o LCD pode ser utilizado, sem problemas, em equipamentos alimentados por pilhas e baterias. O consumo deles bem menor que o de um simples LED! Como j dito antes, o pino 1 (Vss) o terra do mdulo LCD e pode ser ligado juntamente com o pino Vss do PIC. O Pino 2 (Vdd) o positivo e deve ser ligado juntamente com o Vdd do PIC O pino 3 (Vo) onde controlamos o contraste do LCD, ou seja, onde controlamos se o que ir aparecer no LCD ser "escuro" ou "claro". Para isso devemos lig-lo a um potencimetro ou trim-pot de 10KR conectado ao Vss e Vdd (atuando como um divisor de tenso) de acordo com o esquemtico a seguir:

Tutorial LCD em 4 vias

12

www.mecatronicadegaragem.blogspot.com.br

Figura 9: Controle de contraste de um LCD

O pino 4 (RS) o Seletor de Registros. Resumindo, 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. Para indicar se os dados sero lidos ou escritos no LCD, existe o pino 5 (R/W) que controla exatamente se a operao em andamento ser de leitura (quando estivem em nvel lgico alto - 1) ou gravao (quando estiver em nvel lgico baixo - 0). O pino 6 (E) a linha de habilitao para os comandos do LCD. 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 a 14 fazem parte do barramentos de dados. 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.

Tutorial LCD em 4 vias

13

www.mecatronicadegaragem.blogspot.com.br
Parte 3 - Comandos do LCD Ao ligar o LCD na alimentao, a primeira linha fica toda preenchida (veja foto abaixo). Para que ele fique operacional, precisamos inicializ-lo, passando diversas informaes de configurao. Para isso, existem alguns parmetros que precisam ser definidos. A tabela 2 a seguir mostra quais so estes comandos.

Figura 10: LCD 16X02 energizado, mas no inicializado.


Ciclos de Clock
0 165

Instruo
NOP Clear Display

RS
0 0

RW
0 0

D7
0 0

D6
0 0

D5
0 0

D4
0 0

D3
0 0

D2
0 0

D1
0 0

D0
0 1
Sem efeito

Descrio

Cursor Home Entry Mode Set Display Control Cursor / Display shift Function Set Set CGRAM Address Set DDRAM Address Busy Flag & Address Write Data Read Data
x : Sem importncia

0 0 0 0 0 0 0 1 1
I/D S D C B S/C

0 0 0 0 0 0 1 0 1
1 0 1 0 1 0 1 0 1 0 1 0

0 0 0 0 0 1 BF

0 0 0 0 1

0 0 0 1

0 0 1 DL

0 1 S/C N

1 D R/L F

I/D C x x

S B x x

Limpa o display e seta contador de endereo para zero. Seta contador de endereo para zero, retorna o cursor para a posio original. O contedo da DD RAM permanece inalterado. Seta a direo do movimento do cursor (I/D) e especifica deslocamento automtico (S). Liga e desliga o Display (D), cursor (C) e ativa cursor piscante, (B). Desloca o display ou move o cursor (S/C) e especifica a direo (R/L). Seta nmero de bits para comunicao (DL), nmero de linhas (N) e tamanho da fonte (F). Seta o endereo da CGRAM. O dado (endereo) enviado junto. Seta o endereo da DDRAM. O dado (endereo) enviado junto. Flag do Read busy (BF) e contador de endereos. Escreve dados na DDRAM ou na CGRAM L dados da DDRAM ou da CGRAM

3 3 3 3 3 3 0 3 3

Endereo CGRAM Endereo DDRAM

Address Counter (Contador de Endereo) Dado Dado

Incrementa Decrementa Deslocamento automtico do display Display ON (ligado) Display OFF (desligado) Cursor ON (ligado) Cursor OFF (desligado) Cursor piscando Deslocamento do display Movimento do Cursor

R/L DL N F

1 0 1 0 1 0 1 0

Deslocamento para a direita Deslocamento para a esquerda Interface de 8 bits Interface de 4 bits 2 linhas 1 linha Caracteres 5x10 Caracteres 5x7

DDRAM : Display Data RAM CGRAM : Character Generator RAM

Tabela 2: Instrues para inicializao e configurao do LCD Tutorial LCD em 4 vias 14

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

Tabela 3: Configuraes possveis para o LCD Tutorial LCD em 4 vias 15

www.mecatronicadegaragem.blogspot.com.br
Lembre-se que, antes de qualquer operao com o LCD ele precisa ser inicializado utilizando estas informaes da Tabela 3. 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.

Tutorial LCD em 4 vias

16

www.mecatronicadegaragem.blogspot.com.br

Parte 4 - Tabelas de Caracteres 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.

Tabela 4: Os caracteres do 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 importante
Tutorial LCD em 4 vias 17

www.mecatronicadegaragem.blogspot.com.br
ler 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:

Tabela 5: Os caracteres do 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 rea
Tutorial LCD em 4 vias 18

www.mecatronicadegaragem.blogspot.com.br
chama-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. Parte 5 - Endereamento Aps ligarmos o LCD e o iniciarmos, o cursor ir para a primeira posio que a 0x00 (primeira linha x primeira coluna). De acordo com que vamos inputando 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. fMas, 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 2, 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 0x80 ao endereo desejado. Para ilustrar, o endereamento de um display LCD 16X02 o seguinte:

Figura 11: Endereamento direto para um LCD 16X02

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:

Figura 12: Endereamento com deslocamento para um LCD 16X02

Tutorial LCD em 4 vias

19

www.mecatronicadegaragem.blogspot.com.br

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

Figura 13: Endereamentos com deslocamento para diversos LCDs

Parte 6 - Rotacionando o LCD 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. Este modo tambm ser estudado durante os exerccios.

Parte 7 - A CGRAM Caracteres definidos pelo usurio Os endereos 00000000 a 00000111 (0x00 a 0x07) so reservados para os caracteres criados pelo usurio. Temos, portanto, oito caracteres programveis. Esta programao realizada apontando para o endereo da CG RAM (character Generator RAM) onde desejamos armazenar o caractere. Os prximos 8 bytes enviados para a RAM representam cada linha do caractere, iniciando pelo top. Ficou confuso? Ento vamos explicar melhor. Como j vimos anteriormente, cada caractere formado por uma matriz de 8 linhas por 5 colunas, de acordo com a figura abaixo.

Tutorial LCD em 4 vias

20

www.mecatronicadegaragem.blogspot.com.br

Figura 14: O modelo do caractere na CG RAM

Se desejarmos criar um robozinho, devemos preencher esta matriz da seguinte forma:

Figura 15: Criando um rob na CG RAM

Durante a programao, cada linha tratada como um byte em separado. Portanto, imaginemos que cada linha seja tratada como um arranjo de bits, onde cada ponto preenchido representado por 1 e cada ponto apagado seja representado por 0. Teremos ento a seguinte configurao: Teremos ento a seguinte configurao:

Figura 16: O rob, traduzido em bits Tutorial LCD em 4 vias 21

www.mecatronicadegaragem.blogspot.com.br

Lembrando que, pelo fato do byte ter 8 bits e o caractere ter apenas 5 bits, os 3 bits mais significativos sero sempre 0. Agora fica fcil para entendermos que o rob pode ser traduzido nos seguintes bytes (sempre de cima para baixo): 00001110, 00010001, 00001110, 00000100, 00011111, 00000100, 00001010 e 00010001. Passando para hexadecimal, teremos que o robozinho decomposto nos bytes 0x0E, 0X11, 0X0E, 0X04, 0X1F, 0X04, 0X0A e 0X11. Agora que j vimos como decompor um caractere, vamos aprender a program-lo na CGRAM. De acordo com a Tabela 2, precisamos enviar o comando SET CGRAM ADRESS juntamente com o endereo do caractere inicial que desejamos gravar. Ento, para iniciar a programao pelo primeiro caractere disponvel, precisamos enviar o comando 00010000 para o LCD dizendo para posicionar o ponteiro no primeiro endereo da CGRAM. A seguir precisaremos enviar os 8 bytes que compes o caractere. Voil! O nosso robozinho comea a aparecer na tela e pode ser acessado normalmente pelo endereo 0x00! Agora, se continuarmos inserindo informaes de bytes, automaticamente o ponteiro passar para o segundo caractere na CG RAM e assim sucessivamente. Ento para programarmos os oitos caracteres, bastaria posicionar na posio inicial (0x00) e passarmos 64 bytes diretamente para o LCD. Maiores detalhes sero vistos durante os exerccios onde criaremos diversos caracteres para uso.

Tutorial LCD em 4 vias

22

www.mecatronicadegaragem.blogspot.com.br

Parte 8 - Transferncia em 8 bits O LCD baseado no controlador Hitachi HD44780 ou no controlador KS0066U possuem 8 vias de dados e so conhecidos como LCDs paralelos, pois os dados so enviados paralelamente ao LCD. Em nosso estudo no detalharemos este processo, visto que o nosso foco a comunicao em 4 vias de acesso. Todavia, o cdigo necessrio para se comunicar com o LCD usando todas as vias de dados tambm apresentado na seo SOFTWARE. Para iniciarmos o LCD neste modo, devemos adotar a seguinte seqncia de comandos:

Figura 17: Inicializando em 8 vias

Tutorial LCD em 4 vias

23

www.mecatronicadegaragem.blogspot.com.br

Parte 9 - Transferncia em 4 bits 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 (0x20) que o LCD entra no modo de 4 vias. A partir deste momento, 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:

Tutorial LCD em 4 vias

24

www.mecatronicadegaragem.blogspot.com.br

Figura 18: Inicializando em 4 vias

Tutorial LCD em 4 vias

25

www.mecatronicadegaragem.blogspot.com.br

Parte 10 - Timing Antes de passarmos definitivamente para a parte prtica deste tutorial, precisamos conhecer uma limitao dos LCDs: o tempo de sincronizao, tambm conhecido como TIMING. Independentemente da velocidade em que seu projeto/prottipo opera, existe um tempo mnimo que o LCD precisa para processar as informaes. Se este tempo no for respeitado, o LCD no funcionar. A figura abaixo ilustra o grfico de tempo que o LCD opera

Parmetro tAS tAH tDS tDH tDA tEH tEL tRF

Descrio Tempo de set-up do endereo (Address set-up time). Tempo de reteno do endereo (Address hold time). Tempo de ajuste do dado (Data set-up time). Tempo de reteno do dado (Data hold time). Tempo de acesso ao dado (Data access time). Tempo para habilitar nvel 1(Enable high time time). Tempo para habilitar nvel 0(Enable low time). Tempo de transio (Rise/Fall time).

Tempo Mnimo 140ns Mnimo 10ns Mnimo 200ns Mnimo 20ns Mnimo 320ns Mnimo 450ns Mnimo 500ns Mnimo 25ns

Figura 19: Diagrama de temporizao para o LCD

Mas cuidado Este diagrama no conta toda a histria. Apesar de o LCD precisar apenas destes tempos para a execuo, diversos flags internos precisam ser setados que, aliados a outros fatores, tornam o processo de temporizao muito maior. A maioria dos comandos ocupam o LCD por at 40us e outros podem demandar at 3ms para serem liberados. exatamente por isso que existe um flag chamado BUSY que indica se o display est pronto para executar outra instruo ou no. A funo para esta operao a READ STATUS. Em caso onde no utilizamos o modo de leitura do LCD, podemos nos basear em um tempo mnimo que cada operao precisa para ser completada. A tabela a seguir ilustra os tempos necessrios.

Tutorial LCD em 4 vias

26

www.mecatronicadegaragem.blogspot.com.br
Instruo Limpar ao Display (Clear Display) Ir para a posio inicial (display & Cursor Home) Entrada de caracteres (Character Entry Mode) Controles de Display e Cursor (Display On/Off & Cursor) Deslocamento do display e do cursor (Display/Cursor Shift) Ajustes de funes (Function Set) Setar endereo da CGRAM (Set CGRAM Address) Setar endereo do display (Set Display Address) Escrever dados (Write Data) Ler dados (Read Data) Led o estado (Read Status) 6: Diagrama de temporizao real para o LCD Tempo 82us a 4,1ms 40us a 4,1ms 40us 40us 40us 40us 40us 40us 40us 40us 1us

Novamente, apesar da tabela acima funcionar em qualquer LCD alfa-numrico, consulte o data sheet de seu LCD para determinar exatamente quais so os tempos mnimos necessrios.

Tutorial LCD em 4 vias

27

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

28

www.mecatronicadegaragem.blogspot.com.br

Captulo 2 O Hardware

Tutorial LCD em 4 vias

29

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

30

www.mecatronicadegaragem.blogspot.com.br

Captulo 2 - O HARDWARE
Apesar de este tutorial ter sido desenvolvido para utilizao na placa Mosaico McLAB2, quem no possuir esta placa poder fazer uma placa para testes. O esquemtico para tal placa de testes mostrado na figura abaixo. Para testes realizados na placa McLAB2 nenhuma alterao necessria.

Figura 20: Esquemtico para a placa de testes de LCD Tutorial LCD em 4 vias 31

www.mecatronicadegaragem.blogspot.com.br
A placa de circuito impresso sugerida mostrada nas figuras abaixo e tem 2.225 X 1.600 (aproximadamente 56,5mm X 40.6mm).

Figura 21: PCI lado dos componentes

Figura 22: PCI lado da solda (trilhas)

O conector ICSP foi dimensionado para utilizar diretamente com os programadores McFlash e McPlus, evitando assim que o PIC tenha que ser retirado do circuito para ser programado. Outro detalhe diz respeito ao regulador de tenso LM7805 que pode ser substitudo pelo 78L05, devido ao baixo consumo do circuito. Todos os componentes esto detalhados tanto no esquemtico quanto no desenho da PCI Lado dos componentes, so facilmente encontrados no mercado e so de baixo custo. A foto abaixo mostra a placa conectada diretamente no McPlus. Como este prottipo no utiliza oscilador ou ressonador externo, apenas o interno calibrado 4MHz, utilizou-se o pino CLOCKOUT para realizar aferies para calibragem. O PIC aqui utilizado foi o 16F628A.

Figura 23: Placa de testes conectada ao McPlus via conector ICSP

Tutorial LCD em 4 vias

32

www.mecatronicadegaragem.blogspot.com.br

Captulo 3 O Software

Tutorial LCD em 4 vias

33

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

34

www.mecatronicadegaragem.blogspot.com.br

Captulo 3 - O SOFTWARE
Esta seo ser dividida em trs partes. A primeira e a segunda sero inteiramente focadas na McLAB2, onde apresentaremos, na parte 1, o cdigo para comunicao em 8 vias e em seguida o cdigo necessrio para estabelecer a comunicao em 4 bits na parte 2. Todo o detalhamento explicitado no prprio cdigo. Na terceira parte iremos demonstrar a comunicao em 4 bits na placa de testes apresentada no captulo anterior. Como no h ligao fsica das 8 vias de dados nela, obviamente no iremos demonstrar esta comunicao. Mas ser facilmente verificado que o cdigo detalhado para a McLAB2 ser perfeitamente aproveitado com pequenas mudanas. Parte 1 Comunicao em 8 vias pela McLAB2 Este o cdigo necessrio para exibir uma mensagem no LCD, utilizando o PORTD do PIC16F877A da placa McLAB2
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 23/09/2005 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Este exemplo foi elaborado para explicar o funcionamento do mdulo de LCD. Foi utilizado um barramento de 8 vias de comunicao pelo PORTD dos

#include <16f877A.h> // microcontrolador utilizado #fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt // configurao fusveis #use delay(clock=4000000, RESTART_WDT) #use fast_io(a) #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e) #byte porta = 0x05 #byte portb = 0x06 #byte portc = 0x07 #byte portd = 0x08 #byte porte = 0x09 #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 comando portd = caracter; // carrega o portd com o caracter enable = 1 ; // gera pulso no enable delay_us(1); // espera 3 microssegundos enable = 0; // desce o pino de enable delay_us(40); // espera mnimo 40 microssegundos return; // retorna } Tutorial LCD em 4 vias

35

www.mecatronicadegaragem.blogspot.com.br

/************** Rotina que envia um DADO a ser escrito no LCD **************/ void escreve_lcd(int caracter) { rs = 1; // seleciona o envio de um comando portd = caracter; // carrega o portd com o caracter enable = 1; // gera pulso no enable delay_us(1); // espera 3 microssegundos enable = 0; // desce o pino de enable delay_us(40); // espera mnimo 40 microssegundos return; // retorna } /******************** Funo para limpar o LCD void limpa_lcd() { comando_lcd(0x01); // limpa LCD delay_ms (2); return; } ********************/

/******************** Inicializao do Display de LCD ********************/ void inicializa_lcd() { comando_lcd(0x30); // envia comando para inicializar display delay_ms(4); // espera 4 milissegundos comando_lcd(0x30); // envia comando para inicializar display delay_us(100); // espera 100 microssegundos comando_lcd(0x30); // envia comando para inicializar display comando_lcd(0x38); // configura LCD, 8 bits, matriz de 7x5, 2 linhas limpa_lcd(); // limpa LCD comando_lcd(0x0c); // display sem cursor comando_lcd(0x06); // desloca cursor para a direita return; // retorna } /******************** Tela Principal ********************/ void tela_principal() { // posiciona o cursor na linha 0, coluna 0 comando_lcd(0x80); // imprime mensagem no LCD printf (escreve_lcd, "Ola, mundo!"); // posiciona o cursor na linha 1, coluna 2 comando_lcd(0xC0); // imprime mensagem no LCD printf (escreve_lcd, "Oi, mundo"); // retorna da funo return; } /******************** Configuraes do PIC ********************/ void main() { // configura microcontrolador setup_adc_ports (no_analogs); setup_counters (rtcc_internal, WDT_2304MS); // configura os tris set_tris_a(0b11011111); // configurao da direo dos pinos de I/O set_tris_b(0b00000011); set_tris_c(0b11111101); set_tris_d(0b00000000); set_tris_e(0b00000100); // inicializa os ports porta=0x00; // limpa porta portb=0x00; // limpa portb Tutorial LCD em 4 vias 36

www.mecatronicadegaragem.blogspot.com.br
portc=0x00; portd=0x00; porte=0x00; tela_principal(); // limpa portc // limpa portd // limpa porte // imprime a tela principal no LCD

/******************** Rotina principal ********************/ loop: while(TRUE) // rotina principal { RESTART_WDT(); // incia o watch-dog timer } }

Tutorial LCD em 4 vias

37

www.mecatronicadegaragem.blogspot.com.br

Parte 2 Comunicao em 4 vias pela McLAB2 Como parte didtica, a codificao foi dividida em vrias partes que sero detalhadas a seguir. Observe que todas estas rotinas partem do princpio que o pino R/W do LCD est aterrado, garantindo sempre nvel lgico 0, ou seja, poderemos apenas enviar informaes (apenas escrita). As caractersticas de leitura do LCD ficam bloqueadas. Por isso, no poderemos verificar o STATUS BIT para saber quando ele estar pronto para processar outra informao. Devido a estes fatores, devemos nos basear no tempo mnimo par cada operao, estabelecida na Tabela 6. O fato de termos aterrado o pino R/W no uma deficincia no prottipo e sim uma caracterstica da maioria dos projetos comerciais.

Definio de constantes Antes de comearmos a programao propriamente dita, precisamos informar quais so os pinos de I/O que sero utilizados pelo nosso LCD. Este procedimento faz com que a portabilidade entre os cdigos e entre LCDs seja maximizada. Estas so as linhas que devemos incluir em nosso programa principal, juntamente com outras constantes internas: #define #define #define #define #define #define lcd_enable lcd_rs lcd_db4 lcd_db5 lcd_db6 lcd_db7 pin_e1 pin_e0 pin_d4 pin_d5 pin_d6 pin_d7 // // // // // // pino pino pino pino pino pino enable do LCD rs do LCD de dados d4 do de dados d5 do de dados d6 do de dados d7 do

LCD LCD LCD LCD

Rotina de envio de um nibble Esta a principal rotina para comunicao em 4 vias (depois da inicializao do LCD em si). justamente atravs dela que passaremos um nibble para o LCD. Esta rotina basicamente assume que um comando ou caractere especificado pela varivel DADO ser enviado para o LCD. Ela ento pega o nibble mais baixo da varivel e envia para o LCD. Outro ponto diz respeito ao tempo necessrio para a durao do pulso de enable. Como boa prtica, utilize sempre 1us para evitar instabilidades.
/*******************************************************************************/ /* 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 lido output_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 enable output_high(lcd_enable); // ENABLE = 1 delay_us(1); // Recomendado para estabilizar o LCD output_low(lcd_enable); // ENABLE = 0 } return; // Retorna ao ponto de chamada da funo 38

Tutorial LCD em 4 vias

www.mecatronicadegaragem.blogspot.com.br

Rotina de envio de um Byte Como o LCD precisa receber um byte inteiro antes de exibi-lo, precisamos montar esta rotina para que os 8 bits sejam enviados para ele. Outro destaque que esta rotina ainda diferencia se a varivel ir passar um comando ou um caractere a ser exibido. O grande truque desta rotina consiste em pegar a varivel DADO, deslocar os 4 bits mais significativos (DADOS<7:4>) e desloc-los para a direita para que ocupem as posies menos significativas (DADOS<3:0>), ou seja, passaremos o nibble superior (mais significativo) para a posio do nibble inferior (menos significativo). E por que isso feito? Lembre-se que a nossa rotina para enviar nibbles para o LCD s pega o nvel inferior da varivel. Ento a rotina envia_nibble_lcd() chamada, transferindo o contedo do nibble superior para o LCD. Lembre-se, tambm, que sempre devemos transferir primeiramente o nibble superior. Atente para o fato que na instruo envia_nibble_lcd(dado>>4); o valor da varivel passada deslocada, mas o contedo dela no alterado. como se utilizssemos uma varivel auxiliar para este procedimento. Como a varivel DADO permanece inalterada, podemos transferir agora o nibble inferior. Teoricamente, bastaramos chamar novamente a rotina envia_nibble_lcd(dado>>4); mas, como uma norma de boa prtica, ns primeiramente limpamos a parte alta do byte atravs da instruo dado & 0x0f. Isso faz com que os 4 bits mais significativos sejam forados para 0. Observe que aqui tambm a manipulao e alterao do valor passado como parmetro no altera o valor original da varivel DADO. Observe que aqui precisamos de, pelo menos 40us para que o LCD processe o byte (na verdade so dois nibbles) transmitido e exiba-o na tela. Para resumir, dizemos que este o tempo mnimo para estabilizar o LCD. Repare, tambm, que este o tempo mnimo estabelecido pela Tabela 6.
/********************************************************************************/ /* 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 caractere delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD output_low(lcd_enable); // Desativa a linha ENABLE envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/comando envia_nibble_lcd(dado & 0x0f);// Limpa a parte ALTA e envia a parte BAIXA do // dado/comando delay_us(40); // Aguarda 40us para estabilizar o LCD return; // Retorna ao ponto de chamada da funo }

Funo para Limpar o LCD. Como este um procedimento muito comum e pode ocorrer diversa vezes dentro de um programa, foi criada uma rotina simples especificamente para este fim. Este procedimento faz com que durante a compilao, seja gerada um rotina especfica e faz com que o cdigo fique mais otimizado aps a compilao. Atente tambm para o fato de precisarmos aguardar cerca de 2ms antes de retornarmos ao programa. Esta valor tambm est presente na Tabela 6. Caso esta rotina apresente
Tutorial LCD em 4 vias 39

www.mecatronicadegaragem.blogspot.com.br
instabilidade para o seu LCD em particular, experimente alterar o valor deste delay, lembrando que, como boa prtica e de acordo com a Tabela 6, este valor pode variar entre 82us e 4,1ms.
/********************************************************************************/ /* Funo para limpar o LCD */ /********************************************************************************/ // void limpa_lcd() { envia_byte_lcd(0,0x01); // Envia instruo para limpar o LCD delay_ms(2); // Aguarda 2ms para estabilizar o LCD return; // Retorna ao ponto de chamada da funo }

Inicializao do LCD A seguir, temos o cdigo para inicializar um LCD em 4 vias. A primeira ao da rotina forar todas as linhas para o nvel lgico 0. O passo seguinte aguardar 15ms para estabilizar o LCD, aps ser energizado. At este ponto, o mesmo procedimento para os modos de 8 e 4 vias. Aps este ponto, precisamos mandar as informaes para inicializao bsica do LCD que consiste em enviar trs vezes o nibble 0x03, ou enviar o byte 0x30. Para efeito de economia de cdigo e utilizando a caracterstica de que a rotina envia_nibble_lcd() trabalha com o nibble inferior, ser melhor enviarmos o comando 0x03. Repare que devemos aguardar um tempo para estabilizar o LCD. Como este um procedimento executado apenas 1 vez em todo o ciclo do PIC e verificando que o tempo determinado na maioria dos data sheets so inferiores ou muito prximos a 5ms, adotou-se este valor como intervalo mnimo entre as fases iniciais de configurao, onde devemos enviar 3 comando 0x03. Aps isso, vamos enviar o nibble para posicionar o cursor para a posio inicial e, ainda seguindo a Tabela 6, devemos aguardar de 40us a 4,1ms . Por padro foi adotado 1ms. Aqui tambm cabe a observao de que, se o display apresentar instabilidades, este tempo deve ser alterado. Em seguida enviado o nibble 0x20 que indica que o LCD ser configurado para 4 vias de dados, e 1 linha com matriz de 7X5 com cursor. Este valor pode ser alterado a fim de realizar testes, conforme descrito nas Tabelas 2 e 3. Repare que para este ltimo comando, necessrio enviar um byte completo e no apenas um nibble. Estes so os procedimentos iniciais e obrigatoriamente deve seguir esta seqncia. A partir deste ponto podemos entrar com as configuraes constantes nas Tabelas 2 e 3 em qualquer ordem. importante salientar tambm que as instrues constantes a partir deste ponto, assim como a de posicionamento do cursor (CURSOR HOME) podem ser utilizadas em qualquer ponto do programa e no apenas na inicializao do LCD. Com isso fica fcil implementar, por exemplo, uma rotina do tipo backspace. Os comando seguintes enviam um byte completo (e no apenas um nibble) para as configuraes de controle do display (Display control) e para os deslocamentos desejados (Entry Mode Set). Sempre use as Tabelas 2 e 3 como referncia. E para finalizar, existe o comando RETURN para retornar ao ponto onde a rotina foi chamada. Novamente esta uma boa prtica, mas este comando pode ser retirado, uma vez a funo sempre retorna ao ponto onde foi chamada.

Tutorial LCD em 4 vias

40

www.mecatronicadegaragem.blogspot.com.br
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 LCD envia_nibble_lcd(0x03); // Envia comando para inicializar o display delay_ms(5); // Aguarda 5ms para estabilizar o LCD envia_nibble_lcd(0x03); // Envia comando para inicializar o display delay_ms(5); // Aguarda 5ms para estabilizar o LCD envia_nibble_lcd(0x03); // Envia comando para inicializar o display delay_ms(5); // Aguarda 5ms para estabilizar o LCD envia_nibble_lcd(0x02);// CURSOR HOME - Envia comando para zerar o contador de // caracteres e retornar posio inicial (0x80). delay_ms(1); // Aguarda 1ms para estabilizar o LCD envia_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 cursor limpa_lcd(); // Limpa o LCD envia_byte_lcd(0,0x06); // ENTRY MODE SET - Desloca o cursor para a direita } return; // Retorna ao ponto de chamada da funo

Tutorial LCD em 4 vias

41

www.mecatronicadegaragem.blogspot.com.br

Parte 3 Comunicao em 4 vias pela placa de testes Para configurar a placa de testes sugerida neste documento, basta alterar as definies das constantes declaradas no incio do programa. Com isto fica muito fcil visualizar quo poderosa esta rotina. Ela pode ser implementada em qualquer projeto que voc estiver desenvolvendo. Definio de constantes Antes de comearmos a programao propriamente dita, precisamos informar quais so os pinos de I/O que sero utilizados pelo nosso LCD. Este procedimento faz com que a portabilidade entre os cdigos e entre LCDs seja maximizada. Estas so as linhas que devemos incluir em nosso programa principal, juntamente com outras constantes internas:
#define #define #define #define #define #define lcd_enable lcd_rs lcd_db4 lcd_db5 lcd_db6 lcd_db7 pin_b5 pin_b4 pin_b0 pin_b1 pin_b2 pin_b3 // // // // // // pino enable do LCD pino rs do LCD pino de dados d4 do LCD pino de dados d5 do LCD pino de dados d6 do LCD pino de dados d7 do LCD

Outras alteraes obvio que, alm destas configuraes, o tipo de processador, fuses, declarao e inicializao de PORTs e TRIS, assim como as configuraes bsicas do microcontrolador devero ser adequados, uma vez que utilizamos o PIC16F628A ao invs do PIC16F877A existente na McLAB2. Isso ficar bem claro ao comparar os dois cdigos referentes a um mesmo exerccio.

Tutorial LCD em 4 vias

42

www.mecatronicadegaragem.blogspot.com.br

Exerccio 1 Inicializando o LCD e Ol Mundo!

Tutorial LCD em 4 vias

43

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

44

www.mecatronicadegaragem.blogspot.com.br

Exerccio 1 Inicializando o LCD e Ol Mundo


Como primeiro exerccio vamos apenas inicializar o LCD e escrever a frase Ol Mundo no display da McLAB2 e da placa de testes. A seguir temos detalhado os testes para cada placa. McLAB2 O fluxograma necessrio para realizar este primeiro exerccio exibido na figura abaixo:
Incio

Define Microcontrolador

Define configuraes para gravao

Define configuraes para rotinas de delay

Define constantes internas

Define e inicializa os PORTs

Define bibliotecas para o LCD: envia_nibble_lcd(); envia_byte_lcd(); escreve_lcd(); limpa_lcd(); inicializa_lcd();

Configura o PIC: Reseta PORTs Configura TRIS Inicializa o LCD Escreve na tela

Define rotina principal

Final

Figura 24: Fluxograma para a placa McLAB2

Tutorial LCD em 4 vias

45

www.mecatronicadegaragem.blogspot.com.br
O cdigo que dever ser gravada na McLAB2 o seguinte:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tutorial LCD em 4 vias * Para uso na placa de testes * * Exerccio 1 - Ol Mundo! * * Criado por Eduardo de Souza Ramos * * Memory usage: ROM=4% RAM=3% * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 31/08/2005 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 6% * * * * * * * * * * * * * * * * * * * * * * */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Primeiro teste de LCD em 4 vias - Ol Mundo /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio do PIC utilizado * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877a.h> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP,NOCPD,NOWRT /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #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_e1 // pino enable do LCD #define lcd_rs pin_e0 // pino rs do LCD #define lcd_db4 pin_d4 // pino de dados d4 do #define lcd_db5 pin_d5 // pino de dados d5 do #define lcd_db6 pin_d6 // pino de dados d6 do #define lcd_db7 pin_d7 // pino de dados d7 do /* * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao * * * * * * * * * * * * * * * * * * * * * * * #use fast_io(a) // Inicializao rpida dos #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e) #byte #byte #byte #byte #byte porta portb portc portd porte = = = = = 0x05 0x06 0x07 0x08 0x09 * * * * * * * * * * * * * * * * * * */

LCD LCD LCD LCD

* * * * * * * * * * * * * * * dos port's * * * * * * * * * * * * * * * */ Pinos de I/O

/***************************************************************************/ /* Rotinas para o LCD */ /***************************************************************************/ Tutorial LCD em 4 vias 46

www.mecatronicadegaragem.blogspot.com.br
//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 lido output_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 enable output_high(lcd_enable); delay_us(1); output_low(lcd_enable); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 caractere delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD output_low(lcd_enable); // Desativa a linha ENABLE envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/coamndo envia_nibble_lcd(dado & 0x0f);// Limpa a parte ALTA e envia a parte BAIXA do delay_us(40); return; // dado/comando // Aguarda 40us para estabilizar o LCD // Retorna ao ponto de chamada da funo return; // ENABLE = 1 // Recomendado para estabilizar o LCD // ENABLE = 0 // 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,"<caractere a ser mostrado no lcd>"); ou envia_byte_lcd(1,<cdigo do caractere a ser mostrado no lcd>);

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 cvom que o cdigo compilado seja menor. void limpa_lcd() { envia_byte_lcd(0,0x01); // Envia instruo para limpar o LCD delay_ms(2); // Aguarda 2ms para estabilizar o LCD return; // Retorna ao ponto de chamada da funo } Tutorial LCD em 4 vias 47

www.mecatronicadegaragem.blogspot.com.br

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 LCD envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x02); // // // // // // // // delay_ms(1); // envia_byte_lcd(0,0x28); // // envia_byte_lcd(0,0x0c); // limpa_lcd(); // envia_byte_lcd(0,0x06); // } /***************************************************************************/ /* Final das rotinas para o LCD */ /***************************************************************************/ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ main() { // Configura o PIC setup_adc_ports(no_analogs); // Reseta portas porta = 0; portb = 0; portc = 0; portd = 0; porte = 0; // configura os tris set_tris_a(0b00111111); set_tris_b(0b11111111); set_tris_c(0b11111111); set_tris_d(0b00001111); set_tris_e(0b11111100); // Inicializa o LCD inicializa_lcd(); //Escreve tela escreve_lcd("O"); escreve_lcd("l"); escreve_lcd("a"); escreve_lcd(" "); Tutorial LCD em 4 vias 48 // configurao da direo dos pinos de I/O return; Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD CURSOR HOME - Envia comando para zerar o contador de caracteres e retornar posio inicial (0x80). Aguarda 1ms para estabilizar o LCD FUNCTION SET - Configura o LCD para 4 bits, 2 linhas, fonte 5X7. DISPLAY CONTROL - Display ligado, sem cursor Limpa o LCD ENTRY MODE SET - Desloca o cursor para a direita

// Retorna ao ponto de chamada da funo

www.mecatronicadegaragem.blogspot.com.br
escreve_lcd("M"); escreve_lcd("u"); escreve_lcd("n"); escreve_lcd("d"); escreve_lcd("o"); escreve_lcd("!"); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Como no h outra execuo, a rotina principal fica vazia while (true) { } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ }

Tutorial LCD em 4 vias

49

www.mecatronicadegaragem.blogspot.com.br

Placa de testes O fluxograma necessrio para realizar este primeiro exerccio exibido na figura abaixo:
Incio

Define Microcontrolador

Define configuraes para gravao

Define configuraes para rotinas de delay

Define constantes internas

Define e inicializa os PORTs

Define bibliotecas para o LCD: envia_nibble_lcd(); envia_byte_lcd(); escreve_lcd(); limpa_lcd(); inicializa_lcd();

Configura o PIC: Reseta PORTs Configura TRIS Inicializa o LCD Escreve na tela

Define rotina principal

Final

Figura 25: Fluxograma para a placa de testes

Tutorial LCD em 4 vias

50

www.mecatronicadegaragem.blogspot.com.br
Este o cdigo a ser programado em nossa placa de testes:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tutorial LCD em 4 vias * Para uso na placa de testes * * Exerccio 1 Ol Mundo! * * Criado por Eduardo de Souza Ramos * * Memory usage: ROM=15% RAM=3% * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 31/08/2005 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 6% * * * * * * * * * * * * * * * * * * * * * * */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Primeiro teste de LCD em 4 vias - Ol Mundo // // // /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio do PIC utilizado * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f628a.h> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses INTRC,NOWDT,PUT,MCLR,NOBROWNOUT,NOLVP #ROM 0x07ff = {0} //Calibragem do oscilador interno /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #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_b5 // pino enable do LCD #define lcd_rs pin_b4 // pino rs do LCD #define lcd_db4 pin_b0 // pino de dados d4 do #define lcd_db5 pin_b1 // pino de dados d5 do #define lcd_db6 pin_b2 // pino de dados d6 do #define lcd_db7 pin_b3 // pino de dados d7 do /* * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao * * * * * * * * * * * * * * * * * * * * * * * #use fast_io(a) // Inicializao rpida dos #use fast_io(b) #byte porta = 0x05 #byte portb = 0x06 /***************************************************************************/ /* Rotinas para o LCD */ /***************************************************************************/ Tutorial LCD em 4 vias 51 * * * * * * * * * * * * * * * * * * */

LCD LCD LCD LCD

* * * * * * * * * * * * * * * dos port's * * * * * * * * * * * * * * * */ Pinos de I/O

www.mecatronicadegaragem.blogspot.com.br
//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 lido output_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 enable output_high(lcd_enable); delay_us(1); output_low(lcd_enable); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 caractere delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD output_low(lcd_enable); // Desativa a linha ENABLE envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/comando envia_nibble_lcd(dado & 0x0f);// Limpa a parte ALTA e envia a parte BAIXA do // dado/comando delay_us(40); // Aguarda 40us para estabilizar o LCD return; // 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,"<caractere a ser mostrado no LCD>"); ou envia_byte_lcd(1,<cdigo do caractere a ser mostrado no LCD>); return; // ENABLE = 1 // Recomendado para estabilizar o LCD // ENABLE = 0 // Retorna ao ponto de chamada da funo

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,0x01); // Envia instruo para limpar o LCD delay_ms(2); // Aguarda 2ms para estabilizar o LCD return; // Retorna ao ponto de chamada da funo } Tutorial LCD em 4 vias 52

www.mecatronicadegaragem.blogspot.com.br
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 LCD envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x02); delay_ms(1); envia_byte_lcd(0,0x28); envia_byte_lcd(0,0x0c); limpa_lcd(); envia_byte_lcd(0,0x06); } return; // Envia comando para inicializar o display // Aguarda 5ms para estabilizar o LCD // Envia comando para inicializar o display // Aguarda 5ms para estabilizar o LCD // Envia comando para inicializar o display // Aguarda 5ms para estabilizar o LCD // CURSOR HOME - Envia comando para zerar o contador de // caracteres e retornar posio inicial (0x80). // Aguarda 1ms para estabilizar o LCD // FUNCTION SET - Configura o LCD para 4 bits, // 2 linhas, fonte 5X7. // DISPLAY CONTROL - Display ligado, sem cursor // Limpa o LCD // ENTRY MODE SET - Desloca o cursor para a direita // Retorna ao ponto de chamada da funo

/***************************************************************************/ /* Final das rotinas para o LCD */ /***************************************************************************/ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ main() { // Reseta portas porta = 0; portb = 0; // configura os tris set_tris_a(0b00111111); set_tris_b(0b11000000); // Inicializa o LCD inicializa_lcd(); //Escreve tela escreve_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("!"); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * Tutorial LCD em 4 vias 53 // configurao da direo dos pinos de I/O

www.mecatronicadegaragem.blogspot.com.br
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Como no h outra execuo, a rotina principal fica vazia while (true) { } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ }

Repare que neste programa exemplo, o uso de memria foi ROM=15% e RAM=3% 6%. Esta observao importante para que possamos comparar com os outros exerccios.

Tutorial LCD em 4 vias

54

www.mecatronicadegaragem.blogspot.com.br

Exerccio 2 A funo PRINTF();

Tutorial LCD em 4 vias

55

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

56

www.mecatronicadegaragem.blogspot.com.br

Exerccio 2 A funo PRINTF()


Depois de termos realizado o Exerccio 1, muito comum termos a seguinte dvida: Ok, mas no tem uma forma melhor de escrever no LCD sem ter que declarar caractere por caractere? Isso muito chato!. Sim, existe uma forma onde, alm de deixarmos o programa mais enxuto, ainda economizamos espao de memria! E qual a mgica? simples... vamos usar uma funo disponvel no compilador (neste caso o CCS) chamada PRINTF(). Para que tenhamos uma viso mais clara das vantagens que esta funo oferece, vamos manter o mesmo corpo do exerccio anterior, mudando apenas a forma de exibir as informaes no LCD. Como no Exerccio anterior, vamos abordar o uso desta rotina tanto na McLAB2 quanto na placa de testes.

Tutorial LCD em 4 vias

57

www.mecatronicadegaragem.blogspot.com.br

McLAB2 O fluxograma necessrio para realizar este exerccio exibido na figura abaixo:
Incio

Define Microcontrolador

Define configuraes para gravao

Define configuraes para rotinas de delay

Define constantes internas

Define e inicializa os PORTs

Define bibliotecas para o LCD: envia_nibble_lcd(); envia_byte_lcd(); escreve_lcd(); limpa_lcd(); inicializa_lcd();

Configura o PIC: Reseta PORTs Configura TRIS Inicializa o LCD Escreve na tela

Define rotina principal

Final

Figura 26: Fluxograma para a placa McLAB2

Tutorial LCD em 4 vias

58

www.mecatronicadegaragem.blogspot.com.br
Este o cdigo:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tutorial LCD em 4 vias * Para uso na placa de testes * * Exerccio 2 - A funo PRINTF() * * Criado por Eduardo de Souza Ramos * * Memory usage: ROM=3% RAM=3% - 6% * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 31/08/2005 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * Descrio * * * * * * * * * * * * * * * * * * * * // Segundo teste de LCD em 4 vias - Ol // // // * * * * * * * * * * * * */

* * * * * * * * * * * * * * * * * * geral * * * * * * * * * * * * * * * * * * */ Mundo utilizando a funo PRINTF()

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio do PIC utilizado * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877a.h> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP,NOCPD,NOWRT /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #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_e1 // pino enable do LCD #define lcd_rs pin_e0 // pino rs do LCD #define lcd_db4 pin_d4 // pino de dados d4 do #define lcd_db5 pin_d5 // pino de dados d5 do #define lcd_db6 pin_d6 // pino de dados d6 do #define lcd_db7 pin_d7 // pino de dados d7 do * * * * * * * * * * * * * * * * * * */

LCD LCD LCD LCD

/* * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao * * * * * * * * * * * * * * * * * * * * * * * #use fast_io(a) // Inicializao rpida dos #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e) #byte #byte #byte #byte porta portb portc portd = = = = 0x05 0x06 0x07 0x08

* * * * * * * * * * * * * * * dos port's * * * * * * * * * * * * * * * */ Pinos de I/O

Tutorial LCD em 4 vias

59

www.mecatronicadegaragem.blogspot.com.br
#byte porte = 0x09 /***************************************************************************/ /* 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 lido output_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 enable output_high(lcd_enable); delay_us(1); output_low(lcd_enable); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 caractere delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD output_low(lcd_enable); // Desativa a linha ENABLE envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/coamndo envia_nibble_lcd(dado & 0x0f);// Limpa a parte ALTA e envia a parte BAIXA do // dado/comando delay_us(40); // Aguarda 40us para estabilizar o LCD return; // 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,"<caractere a ser mostrado no lcd>"); ou envia_byte_lcd(1,<cdigo do caractere a ser mostrado no lcd>); return; // ENABLE = 1 // Recomendado para estabilizar o LCD // ENABLE = 0 // Retorna ao ponto de chamada da funo

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 cvom que o cdigo compilado seja menor. void limpa_lcd() Tutorial LCD em 4 vias 60

www.mecatronicadegaragem.blogspot.com.br
{

envia_byte_lcd(0,0x01); // Envia instruo para limpar o LCD delay_ms(2); // Aguarda 2ms para estabilizar o LCD return; // 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 LCD envia_nibble_lcd(0x03);// delay_ms(5); // envia_nibble_lcd(0x03);// delay_ms(5); // envia_nibble_lcd(0x03);// delay_ms(5); // envia_nibble_lcd(0x02);// // delay_ms(1); // envia_byte_lcd(0,0x28);// // envia_byte_lcd(0,0x0c);// limpa_lcd(); // envia_byte_lcd(0,0x06);// return; } /***************************************************************************/ /* Final das rotinas para o LCD */ /***************************************************************************/ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ main() { // Configura o PIC setup_adc_ports(no_analogs); // Reseta portas porta = 0; portb = 0; portc = 0; portd = 0; porte = 0; // configura os tris set_tris_a(0b00111111); set_tris_b(0b11111111); set_tris_c(0b11111111); set_tris_d(0b00001111); set_tris_e(0b11111100); // Inicializa o LCD inicializa_lcd(); Tutorial LCD em 4 vias 61 // configurao da direo dos pinos de I/O Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD CURSOR HOME - Envia comando para zerar o contador de caracteres e retornar posio inicial (0x80). Aguarda 1ms para estabilizar o LCD FUNCTION SET - Configura o LCD para 4 bits, 2 linhas, fonte 5X7. DISPLAY CONTROL - Display ligado, sem cursor Limpa o LCD ENTRY MODE SET - Desloca o cursor para a direita

// Retorna ao ponto de chamada da funo

www.mecatronicadegaragem.blogspot.com.br
//Escreve tela printf(escreve_lcd,"Ola Mundo!"); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Como no h outra execuo, a rotina principal fica vazia while (true) { } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ }

Tutorial LCD em 4 vias

62

www.mecatronicadegaragem.blogspot.com.br

Placa de testes O fluxograma necessrio para realizar este exerccio exibido na figura abaixo:
Incio

Define Microcontrolador

Define configuraes para gravao

Define configuraes para rotinas de delay

Define constantes internas

Define e inicializa os PORTs

Define bibliotecas para o LCD: envia_nibble_lcd(); envia_byte_lcd(); escreve_lcd(); limpa_lcd(); inicializa_lcd();

Configura o PIC: Reseta PORTs Configura TRIS Inicializa o LCD Escreve na tela

Define rotina principal

Final

Figura 27: Fluxograma para a placa de testes

Tutorial LCD em 4 vias

63

www.mecatronicadegaragem.blogspot.com.br
Este o cdigo para a nossa placa de testes:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tutorial LCD em 4 vias * * Para uso na placa de testes * * * * Exerccio 2 - A funo PRINTF() * * * * Criado por Eduardo de Souza Ramos * * * * Memory usage: ROM=9% RAM=3% - 6% * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 31/08/2005 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * Descrio * * * * * * * * * * * * * * * * * * * * // Segundo teste de LCD em 4 vias - Ol // * * * * * * * * * * * * * * * * * * geral * * * * * * * * * * * * * * * * * * */ Mundo utilizando a funo PRINTF()

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio do PIC utilizado * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f628a.h> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses INTRC,NOWDT,PUT,MCLR,NOBROWNOUT,NOLVP #ROM 0x07ff = {0} //Calibragem do oscilador interno /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #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_b5 // pino enable do LCD #define lcd_rs pin_b4 // pino rs do LCD #define lcd_db4 pin_b0 // pino de dados d4 do LCD #define lcd_db5 pin_b1 // pino de dados d5 do LCD #define lcd_db6 pin_b2 // pino de dados d6 do LCD #define lcd_db7 pin_b3 // pino de dados d7 do LCD /* * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao * * * * * * * * * * * * * * * * * * * * * * * #use fast_io(a) // Inicializao rpida dos #use fast_io(b) #byte porta = 0x05 #byte portb = 0x06 /***************************************************************************/ /* Rotinas para o LCD */ /***************************************************************************/ //Este o bloco com as rotinas necessrias para manipular o LCD /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Envio de "Nibble" para o LCD * Tutorial LCD em 4 vias 64 * * * * * * * * * * * * * * * dos port's * * * * * * * * * * * * * * * */ Pinos de I/O

www.mecatronicadegaragem.blogspot.com.br
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //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 lido output_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 enable output_high(lcd_enable); delay_us(1); output_low(lcd_enable); return; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 caractere delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD output_low(lcd_enable); // Desativa a linha ENABLE envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/comando envia_nibble_lcd(dado & 0x0f);// Limpa a parte ALTA e envia a parte BAIXA do // dado/comando delay_us(40); // Aguarda 40us para estabilizar o LCD return; // 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,"<caractere a ser mostrado no LCD>"); ou envia_byte_lcd(1,<cdigo do caractere a ser mostrado no LCD>); // ENABLE = 1 // Recomendado para estabilizar o LCD // ENABLE = 0 // Retorna ao ponto de chamada da funo

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,0x01); // Envia instruo para limpar o LCD delay_ms(2); // Aguarda 2ms para estabilizar o LCD return; // Retorna ao ponto de chamada da funo } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializa o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd() Tutorial LCD em 4 vias 65

www.mecatronicadegaragem.blogspot.com.br
{

output_low(lcd_db4); // Garante que o output_low(lcd_db5); // Garante output_low(lcd_db6); // Garante output_low(lcd_db7); // Garante output_low(lcd_rs); // Garante output_low(lcd_enable); // Garante delay_ms(15); // Aguarda envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x02); delay_ms(1); envia_byte_lcd(0,0x28); envia_byte_lcd(0,0x0c); limpa_lcd(); envia_byte_lcd(0,0x06);

pino DB4 esto em 0 (low) que o pino DB5 esto em 0 (low) que o pino DB6 esto em 0 (low) que o pino DB7 esto em 0 (low) que o pino RS esto em 0 (low) que o pino ENABLE esto em 0 (low) 15ms para estabilizar o LCD

// Envia comando para inicializar o display // Aguarda 5ms para estabilizar o LCD // Envia comando para inicializar o display // Aguarda 5ms para estabilizar o LCD // Envia comando para inicializar o display // Aguarda 5ms para estabilizar o LCD // CURSOR HOME - Envia comando para zerar o contador de // caracteres e retornar posio inicial (0x80). // Aguarda 1ms para estabilizar o LCD // FUNCTION SET - Configura o LCD para 4 bits, // 2 linhas, fonte 5X7. // DISPLAY CONTROL - Display ligado, sem cursor // Limpa o LCD // ENTRY MODE SET - Desloca o cursor para a direita // Retorna ao ponto de chamada da funo

} /***************************************************************************/ /* Final das rotinas para o LCD */ /***************************************************************************/ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ main() { // Reseta portas porta = 0; portb = 0; // configura os tris set_tris_a(0b00111111); set_tris_b(0b11000000); // Inicializa o LCD inicializa_lcd(); //Escreve tela printf(escreve_lcd,"Ola Mundo!"); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Como no h outra execuo, a rotina principal fica vazia while (true) { } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ } Tutorial LCD em 4 vias 66 // configurao da direo dos pinos de I/O

return;

www.mecatronicadegaragem.blogspot.com.br

Repare que neste programa exemplo, o uso de memria foi ROM=9% e RAM=3% - 6%. Se compararmos com o exerccio anterior, veremos que houve um ganho substancial de memria (6 pontos percentuais) que em alguns casos pode representar o sucesso de seu projeto! Portanto, use esta funo e seja feliz!!! Maiores detalhes sobre esta funo e como imprimir o contedo de variveis pode ser encontrada no help do compilador CCS

Tutorial LCD em 4 vias

67

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

68

www.mecatronicadegaragem.blogspot.com.br

Exerccio 3 Rotacionando o display

Tutorial LCD em 4 vias

69

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

70

www.mecatronicadegaragem.blogspot.com.br

Exerccio 3 Rotacionando o display


Conforme dito antes, independentemente do tamanho do display, h sempre 80 posies em cada linha do display para armazenar caracteres. Mas preste ateno que, nos displays de 4 linhas, a terceira linha continuao da primeira e a quarta e a continuao da segunda. Verifique isto na Figura 13. Mas, como no h espao disponvel para visualizar todos estes espaos, h um modo de deslocar a telado LCD de forma que temos acesso a todo o contedo armazenado em cada linha. Este um procedimento muito simples, mas h uma pegadinha... ele altera a relao dos endereos com as posies na tela. Portanto, se voc realizar diversas rotaes, uma boa prtica utilizar o comando envia_byte_lcd(0,0x02) para que o comando CURSOR HOME seja executado, direcionando o cursor para a posio 0x00 (ou 0x80 se levarmos em conta que o bit 7 deve ser sempre 1, ao nos referenciarmos a um endereo) e deslocando o display para o estado original. No se esquea que este comando no altera a memria RAM do LCD. No use o comando CLEAR DISPLAY (0x01), pois neste caso, todo o contedo da memria RAM poder ser perdido. Se entrarmos com mais de 16 caracteres por linha (no nosso caso, uma vez que usamos um LCD de 16 posies), os caracteres excedentes ficaro fora da linha de viso, no lado direito da tela. Ento, poderemos usar a funo envia_byte_lcd(0,0x18) para que todos os endereos da tela sejam deslocadas para a esquerda. Isto d a sensao de que a tela deslocou para a direita. como se tivssemos uma lupa em cima do texto. Da mesma forma, poderemos utilizar a funo envia_byte_lcd(0,0x1c) para realizar a operao inversa. Neste exemplo mostramos como podemos criar um mostrador onde o texto apresenta o clssico movimento de vai-e-vem. Como vocs j devem ter reparado nos dois exemplos anteriores, o fluxograma o mesmo, portanto, para este exemplo, no vamos fugir regra. Devido a isto, no iremos repetir o mesmo desenho, passando diretamente para a codificao para a placa McLAB2 e para a nossa placa de testes.

Tutorial LCD em 4 vias

71

www.mecatronicadegaragem.blogspot.com.br

McLAB2 Este o cdigo para a McLAB2


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tutorial LCD em 4 vias * Para uso na placa de testes * * Exerccio 3 - Deslocando e rotacionando o display * * Criado por Eduardo de Souza Ramos * * Memory usage: ROM=4% RAM=3% - 7% * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 31/08/2005 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Neste exerccio, o display ser deslocado para a esquerda e, ao final // da mensagem ele ser deslocado para a direita, criando um efeito de // vai-e-vem. Sero utilizadas as duas linhas do LCD para ter uma melhor // visualizao. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio do PIC utilizado * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #include <16f877a.h> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP,NOCPD,NOWRT /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #use delay(clock=4000000) * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Estas so as definies dos pinos que o LCD utiliza. #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 /* * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao * * * * * * * * * * * * * * * * * * * * * * * #use fast_io(a) // Inicializao rpida dos #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e) #byte #byte #byte #byte #byte porta portb portc portd porte = = = = = 0x05 0x06 0x07 0x08 0x09 72 * * * * * * * * * * * * * * * dos port's * * * * * * * * * * * * * * * */ Pinos de I/O

Tutorial LCD em 4 vias

www.mecatronicadegaragem.blogspot.com.br

/***************************************************************************/ /* 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 lido output_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 enable output_high(lcd_enable); // ENABLE = 1 delay_us(1); // Recomendado para estabilizar o LCD output_low(lcd_enable); // ENABLE = 0 return; // 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 caractere delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD output_low(lcd_enable); // Desativa a linha ENABLE envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/coamndo envia_nibble_lcd(dado & 0x0f);// Limpa a parte ALTA e envia a parte BAIXA do // dado/comando delay_us(40); // Aguarda 40us para estabilizar o LCD return; // 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,"<caractere a ser mostrado no lcd>"); ou envia_byte_lcd(1,<cdigo do caractere a ser mostrado no lcd>);

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 cvom que o cdigo compilado seja menor. void limpa_lcd() { envia_byte_lcd(0,0x01); // Envia instruo para limpar o LCD delay_ms(2); // Aguarda 2ms para estabilizar o LCD return; // Retorna ao ponto de chamada da funo } Tutorial LCD em 4 vias 73

www.mecatronicadegaragem.blogspot.com.br

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 LCD envia_nibble_lcd(0x03);// Envia comando para inicializar o display delay_ms(5); // Aguarda 5ms para estabilizar o LCD envia_nibble_lcd(0x03);// Envia comando para inicializar o display delay_ms(5); // Aguarda 5ms para estabilizar o LCD envia_nibble_lcd(0x03);// Envia comando para inicializar o display delay_ms(5); // Aguarda 5ms para estabilizar o LCD envia_nibble_lcd(0x02);// CURSOR HOME - Envia comando para zerar o contador de // caracteres e retornar posio inicial (0x80). delay_ms(1); // Aguarda 1ms para estabilizar o LCD envia_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 cursor limpa_lcd(); // Limpa o LCD envia_byte_lcd(0,0x06);// ENTRY MODE SET - Desloca o cursor para a direita return; // Retorna ao ponto de chamada da funo } /***************************************************************************/ /* Final das rotinas para o LCD */ /***************************************************************************/ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ main() { // Configura o PIC setup_adc_ports(no_analogs); // Reseta portas porta = 0; portb = 0; portc = 0; portd = 0; porte = 0; // configura os tris set_tris_a(0b00111111); // configurao da direo dos pinos de I/O set_tris_b(0b11111111); set_tris_c(0b11111111); set_tris_d(0b00001111); set_tris_e(0b11111100); // Inicializa o LCD inicializa_lcd(); //Escreve tela printf(escreve_lcd,"Teste 1-linha com mais de 16 caracteres"); envia_byte_lcd(0,0xc0); //Desloca o cursor para a segunda linha do LCD printf(escreve_lcd,"Teste 2-linha comum, + de 16 caracteres"); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Esta rotina a responsvel pelo movimento de vai-e-vem do display. // Ela fica em loop infinito.; while (true) Tutorial LCD em 4 vias 74

www.mecatronicadegaragem.blogspot.com.br
{

int i; //Desloca os caracteres do LCD para a esquerda for(i=0;i<=22;i++) { envia_byte_lcd(0,0x18); //0x18 = 0b00011000 delay_ms(250); } //Desloca os caracteres do LCD para a direita for(i=0;i<=22;i++) { envia_byte_lcd(0,0x1c); //0x1c = 0b00011100 delay_ms(250); }

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ }

Tutorial LCD em 4 vias

75

www.mecatronicadegaragem.blogspot.com.br

Placa de testes O seguinte cdigo o que dever ser executado em nossa placa de testes:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * Tutorial LCD em 4 vias * Para uso na placa de testes * * Exerccio 3 - Deslocando e rotacionando o * * Criado por Eduardo de Souza Ramos * * Memory usage: ROM=15% RAM=3% * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 31/08/2005 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * display * * * * 7% * * * * * * * * * * * * * * * * * * * * * * * * */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Neste exerccio, o display ser deslocado para a esquerda e, ao final // da mensagem ele ser deslocado para a direita, criando um efeito de // vai-e-vem. Sero utilizadas as duas linhas do LCD para ter uma melhor // visualizao. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio do PIC utilizado * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f628a.h> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses INTRC,NOWDT,PUT,MCLR,NOBROWNOUT,NOLVP #ROM 0x07ff = {0} //Calibragem do oscilador interno /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #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_b5 // pino enable do LCD #define lcd_rs pin_b4 // pino rs do LCD #define lcd_db4 pin_b0 // pino de dados d4 do LCD #define lcd_db5 pin_b1 // pino de dados d5 do LCD #define lcd_db6 pin_b2 // pino de dados d6 do LCD #define lcd_db7 pin_b3 // pino de dados d7 do LCD /* * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao * * * * * * * * * * * * * * * * * * * * * * * #use fast_io(a) // Inicializao rpida dos #use fast_io(b) #byte porta = 0x05 #byte portb = 0x06 /***************************************************************************/ Tutorial LCD em 4 vias 76 * * * * * * * * * * * * * * * dos port's * * * * * * * * * * * * * * * */ Pinos de I/O

www.mecatronicadegaragem.blogspot.com.br
/* 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 lido output_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 enable output_high(lcd_enable); delay_us(1); output_low(lcd_enable); return; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 caractere delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD output_low(lcd_enable); // Desativa a linha ENABLE envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/comando envia_nibble_lcd(dado & 0x0f);// Limpa a parte ALTA e envia a parte BAIXA do // dado/comando delay_us(40); // Aguarda 40us para estabilizar o LCD return; // 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,"<caractere a ser mostrado no LCD>"); ou envia_byte_lcd(1,<cdigo do caractere a ser mostrado no LCD>); // // // // ENABLE = 1 Recomendado para estabilizar o LCD ENABLE = 0 Retorna ao ponto de chamada da funo

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,0x01); // Envia instruo para limpar o LCD delay_ms(2); // Aguarda 2ms para estabilizar o LCD return; // Retorna ao ponto de chamada da funo } Tutorial LCD em 4 vias 77

www.mecatronicadegaragem.blogspot.com.br

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 LCD envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x02); delay_ms(1); envia_byte_lcd(0,0x28); envia_byte_lcd(0,0x0c); limpa_lcd(); envia_byte_lcd(0,0x06); } /***************************************************************************/ /* Final das rotinas para o LCD */ /***************************************************************************/ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ main() { // Reseta portas porta = 0; portb = 0; // configura os tris set_tris_a(0b00111111); set_tris_b(0b11000000); // Inicializa o LCD inicializa_lcd(); //Escreve tela printf(escreve_lcd,"Teste 1-linha com mais de 16 caracteres"); envia_byte_lcd(0,0xc0); //Desloca o cursor para a segunda linha do LCD printf(escreve_lcd,"Teste 2-linha comum, + de 16 caracteres"); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Esta rotina a responsvel pelo movimento de vai-e-vem do display. // Ela fica em loop infinito.; while (true) { int i; //Desloca os caracteres do LCD para a esquerda Tutorial LCD em 4 vias 78 // configurao da direo dos pinos de I/O return; // // // // // // // // // // // // // // Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD CURSOR HOME - Envia comando para zerar o contador de caracteres e retornar posio inicial (0x80). Aguarda 1ms para estabilizar o LCD FUNCTION SET - Configura o LCD para 4 bits, 2 linhas, fonte 5X7. DISPLAY CONTROL - Display ligado, sem cursor Limpa o LCD ENTRY MODE SET - Desloca o cursor para a direita

// Retorna ao ponto de chamada da funo

www.mecatronicadegaragem.blogspot.com.br
for(i=0;i<=22;i++) { envia_byte_lcd(0,0x18); //0x18 = 0b00011000 delay_ms(250); } //Desloca os caracteres do LCD para a direita for(i=0;i<=22;i++) { envia_byte_lcd(0,0x1c); //0x1c = 0b00011100 delay_ms(250); }

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ }

Faa um teste... Comentes as linhas que direcionam os caracteres do LCD para a direita e veja o que acontece...

Tutorial LCD em 4 vias

79

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

80

www.mecatronicadegaragem.blogspot.com.br

Exerccio 4 Criando caracteres

Tutorial LCD em 4 vias

81

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

82

www.mecatronicadegaragem.blogspot.com.br

Exerccio 4 Criando caracteres


Os endereos da CGRAM de 0x40 at 0x7F so usados para que armazenemos os caracteres desenhados por ns. Para isso, precisaremos, logo no incio do programa, definir quais so os valores dos caracteres, conforme explicado no Captulo 1 Parte 7. Este exemplo, para as placas McLAB2 e a nossa placa de testes, utiliza o mesmo fluxograma, que exibido a seguir.
Incio cria_cgram();

Define microcontrolador

Vai para a primeira posio da CGRAM (0x40)

Define configuraes para gravao

Entra com os 8 dados do primeiro caractere

Define configuraes para rotinas de delay

Entra com os 8 dados do segundo caractere

Define constantes internas

Entra com os 8 dados do terceiro caractere

Define e inicializa os PORTs

Entra com os 8 dados do quarto caractere

Define bibliotecas para o LCD: envia_nibble_lcd(); envia_byte_lcd(); escreve_lcd(); limpa_lcd(); inicializa_lcd(); cria_cgram(); anima_cgram();

Entra com os 8 dados do quinto caractere

Entra com os 8 dados do sexto caractere

Configura o PIC: Reseta PORTs Configura TRIS Inicializa o LCD Escreve na tela

Entra com os 8 dados do stimo caractere

Entra com os 8 dados do oitavo caractere

Define rotina principal

Limpa o LCD

Fim

Retorna

Figura 28: Fluxograma para o exemplo 4

Tutorial LCD em 4 vias

83

www.mecatronicadegaragem.blogspot.com.br

McLAB2 Este o cdigo que dever ser implementado em nossa placa de testes:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tutorial LCD em 4 vias * * Para uso na placa de testes * * * * Exerccio 4 - Criando caracteres na CGRAM * * * * Criado por Eduardo de Souza Ramos * * * * Memory usage: ROM=7% RAM=3% - 6% * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 31/08/2005 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Neste exerccio, criaremos 8 caracteres especiais (desenhos) na CGRAM // para utilizarmos em qualquer ponto do LCD // A priori eles sero exibidos nas 8 primeiras posies da primeira // linha do LCD. Maseles podero ser utilizados em qualquer ponto. // Como estes caracteres ficam na CGRAM, so volteis, ou seja, ao // desligarmos o mdulo e o ligarmos novamente, precisarmos reintroduzir // o cdigo para a criao de caracteres. // Reparem que, apesar de termos 16 posies disponveis na CGRAM, // somente poderemos criar 8 caracteres. As 8 posies adjacentes (posies // 0x08 a 0x0f) so espelho da primeira (0x00 a 0x07) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio do PIC utilizado * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877a.h> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP,NOCPD,NOWRT /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #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_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 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Tutorial LCD em 4 vias 84

www.mecatronicadegaragem.blogspot.com.br
#use #use #use #use #use #byte #byte #byte #byte #byte fast_io(a) fast_io(b) fast_io(c) fast_io(d) fast_io(e) porta portb portc portd porte = = = = = 0x05 0x06 0x07 0x08 0x09 // Inicializao rpida dos Pinos de I/O

/***************************************************************************/ /* 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 lido output_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 enable output_high(lcd_enable); delay_us(1); output_low(lcd_enable); return; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 caractere delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD output_low(lcd_enable); // Desativa a linha ENABLE envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/coamndo envia_nibble_lcd(dado & 0x0f);// Limpa a parte ALTA e envia a parte BAIXA do // dado/comando delay_us(40); // Aguarda 40us para estabilizar o LCD return; // 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,"<caractere a ser mostrado no lcd>"); ou envia_byte_lcd(1,<cdigo do caractere a ser mostrado no lcd>); // ENABLE = 1 // Recomendado para estabilizar o LCD // ENABLE = 0 // Retorna ao ponto de chamada da funo

void escreve_lcd(char c) // envia caractere para o display { Tutorial LCD em 4 vias 85

www.mecatronicadegaragem.blogspot.com.br
envia_byte_lcd(1,c);

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Como esta operao pode ser muito utilizada, transformando-a em funo // faz cvom que o cdigo compilado seja menor. void limpa_lcd() { envia_byte_lcd(0,0x01); // Envia instruo para limpar o LCD delay_ms(2); // Aguarda 2ms para estabilizar o LCD return; // Retorna ao ponto de chamada da funo } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * void inicializa_lcd() { output_low(lcd_db4); // output_low(lcd_db5); // output_low(lcd_db6); // output_low(lcd_db7); // output_low(lcd_rs); // output_low(lcd_enable); // delay_ms(15); // envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x02); // // // // // // // // delay_ms(1); // envia_byte_lcd(0,0x28); // // envia_byte_lcd(0,0x0c); // limpa_lcd(); // envia_byte_lcd(0,0x06); // } return; * * * * * * * * * * * * * * * * * * * * * * * * Inicializa o LCD * * * * * * * * * * * * * * * * * * * * * * * * */ Garante Garante Garante Garante Garante Garante Aguarda que o pino DB4 esto em 0 (low) que o pino DB5 esto em 0 (low) que o pino DB6 esto em 0 (low) que o pino DB7 esto em 0 (low) que o pino RS esto em 0 (low) que o pino ENABLE esto em 0 (low) 15ms para estabilizar o LCD

Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD CURSOR HOME - Envia comando para zerar o contador de caracteres e retornar posio inicial (0x80). Aguarda 1ms para estabilizar o LCD FUNCTION SET - Configura o LCD para 4 bits, 2 linhas, fonte 5X7. DISPLAY CONTROL - Display ligado, sem cursor Limpa o LCD ENTRY MODE SET - Desloca o cursor para a direita

// Retorna ao ponto de chamada da funo

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Cria caracteres na CG RAM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void cria_cgram() { envia_byte_lcd(0,0b01000000); // Vai para primeira posio da CGRAM envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010100); Tutorial LCD em 4 vias // // // // // // // // // // // // Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria a a a a a a a a a a a a primeira linha de nosso robozinho segunda linha de nosso robozinho terceira linha de nosso robozinho quarta linha de nosso robozinho quinta linha de nosso robozinho sexta linha de nosso robozinho stima linha de nosso robozinho oitava linha de nosso robozinho primeira linha de nosso robozinho 2 segunda linha de nosso robozinho 2 terceira linha de nosso robozinho 2 quarta linha de nosso robozinho 2 86

www.mecatronicadegaragem.blogspot.com.br
envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000101); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000101); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); limpa_lcd(); return; } /***************************************************************************/ Tutorial LCD em 4 vias 87 // Retorna ao ponto de chamada da funo // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a quinta linha de nosso robozinho 2 sexta linha de nosso robozinho 2 stima linha de nosso robozinho 2 oitava linha de nosso robozinho 2 primeira linha de nosso robozinho 3 segunda linha de nosso robozinho 3 terceira linha de nosso robozinho 3 quarta linha de nosso robozinho 3 quinta linha de nosso robozinho 3 sexta linha de nosso robozinho 3 stima linha de nosso robozinho 3 oitava linha de nosso robozinho 3 primeira linha de nosso robozinho 4 segunda linha de nosso robozinho 4 terceira linha de nosso robozinho 4 quarta linha de nosso robozinho 4 quinta linha de nosso robozinho 4 sexta linha de nosso robozinho 4 stima linha de nosso robozinho 4 oitava linha de nosso robozinho 4 primeira linha de nosso janelinha segunda linha de nosso janelinha terceira linha de nosso janelinha quarta linha de nosso janelinha quinta linha de nosso janelinha sexta linha de nosso janelinha stima linha de nosso janelinha oitava linha de nosso janelinha primeira linha de nossa ampulheta 1 segunda linha de nossa ampulheta 1 terceira linha de nossa ampulheta 1 quarta linha de nossa ampulheta 1 quinta linha de nossa ampulheta 1 sexta linha de nossa ampulheta 1 stima linha de nossa ampulheta 1 oitava linha de nossa ampulheta 1 primeira linha de nossa ampulheta 2 segunda linha de nossa ampulheta 2 terceira linha de nossa ampulheta 2 quarta linha de nossa ampulheta 2 quinta linha de nossa ampulheta 2 sexta linha de nossa ampulheta 2 stima linha de nossa ampulheta 2 oitava linha de nossa ampulheta 2 primeira linha de nossa ampulheta 3 segunda linha de nossa ampulheta 3 terceira linha de nossa ampulheta 3 quarta linha de nossa ampulheta 3 quinta linha de nossa ampulheta 3 sexta linha de nossa ampulheta 3 stima linha de nossa ampulheta 3 oitava linha de nossa ampulheta 3

www.mecatronicadegaragem.blogspot.com.br
/* Final das rotinas para o LCD */ /***************************************************************************/ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ main() { // Configura o PIC setup_adc_ports(no_analogs); // Reseta portas porta = 0; portb = 0; portc = 0; portd = 0; porte = 0; // configura os tris set_tris_a(0b00111111); set_tris_b(0b11111111); set_tris_c(0b11111111); set_tris_d(0b00001111); set_tris_e(0b11111100); // Inicializa o LCD inicializa_lcd(); //Escreve tela limpa_lcd(); cria_cgram(); //Escreve os caracteres da CGRAM nas duas linhas do LCD escreve_lcd(0b00000000); escreve_lcd(0b00000001); escreve_lcd(0b00000010); escreve_lcd(0b00000011); escreve_lcd(0b00000100); escreve_lcd(0b00000101); escreve_lcd(0b00000110); escreve_lcd(0b00000111); envia_byte_lcd(0,0xc0); escreve_lcd(0b00001000); escreve_lcd(0b00001001); escreve_lcd(0b00001010); escreve_lcd(0b00001011); escreve_lcd(0b00001100); escreve_lcd(0b00001101); escreve_lcd(0b00001110); escreve_lcd(0b00001111); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // while (true) { } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ } Tutorial LCD em 4 vias 88 // configurao da direo dos pinos de I/O

www.mecatronicadegaragem.blogspot.com.br

Placa de testes Este o cdigo que dever ser implementado em nossa placa de testes:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tutorial LCD em 4 vias * * Para uso na placa de testes * * * * Exerccio 4 - Criando caracteres na CGRAM * * * * Criado por Eduardo de Souza Ramos * * * * Memory usage: ROM=26% RAM=3% - 6% * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 31/08/2005 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Neste exerccio, criaremos 8 caracteres especiais (desenhos) na CGRAM // para utilizarmos em qualquer ponto do LCD // A priori eles sero exibidos nas 8 primeiras posies da primeira // linha do LCD. Mas eles podero ser utilizados em qualquer ponto. // Como estes caracteres ficam na CGRAM, so volteis, ou seja, ao // desligarmos o mdulo e o ligarmos novamente, precisarmos reintroduzir // o cdigo para a criao de caracteres. // Reparem que, apesar de termos 16 posies disponveis na CGRAM, // somente poderemos criar 8 caracteres. As 8 posies adjacentes (posies // 0x08 a 0x0f) so espelho da primeira (0x00 a 0x07) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio do PIC utilizado * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f628a.h> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses INTRC,NOWDT,PUT,MCLR,NOBROWNOUT,NOLVP #ROM 0x07ff = {0} //Calibragem do oscilador interno /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #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_b5 // pino enable do LCD #define lcd_rs pin_b4 // pino rs do LCD #define lcd_db4 pin_b0 // pino de dados d4 do LCD #define lcd_db5 pin_b1 // pino de dados d5 do LCD #define lcd_db6 pin_b2 // pino de dados d6 do LCD #define lcd_db7 pin_b3 // pino de dados d7 do LCD /* * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao * * * * * * * * * * * * * * * * * * * * * * * #use fast_io(a) // Inicializao rpida dos Tutorial LCD em 4 vias * * * * * * * * * * * * * * * dos port's * * * * * * * * * * * * * * * */ Pinos de I/O 89

www.mecatronicadegaragem.blogspot.com.br
#use fast_io(b)

#byte porta = 0x05 #byte portb = 0x06 /***************************************************************************/ /* 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 lido output_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 enable output_high(lcd_enable); delay_us(1); output_low(lcd_enable); return; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 caractere delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD output_low(lcd_enable); // Desativa a linha ENABLE envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/comando envia_nibble_lcd(dado & 0x0f);// Limpa a parte ALTA e envia a parte BAIXA do // dado/comando delay_us(40); // Aguarda 40us para estabilizar o LCD return; // 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,"<caractere a ser mostrado no LCD>"); ou envia_byte_lcd(1,<cdigo do caractere a ser mostrado no LCD>); // ENABLE = 1 // Recomendado para estabilizar o LCD // ENABLE = 0 // Retorna ao ponto de chamada da funo

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 Tutorial LCD em 4 vias 90

www.mecatronicadegaragem.blogspot.com.br
// faz com que o cdigo compilado seja menor. void limpa_lcd() { envia_byte_lcd(0,0x01); // Envia instruo para limpar o LCD delay_ms(2); // Aguarda 2ms para estabilizar o LCD return; // Retorna ao ponto de chamada da funo } /* * * * * * * * * * * * * * * * * * * * * * * * * * * void inicializa_lcd() { output_low(lcd_db4); // output_low(lcd_db5); output_low(lcd_db6); output_low(lcd_db7); output_low(lcd_rs); output_low(lcd_enable); delay_ms(15); // envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x02); delay_ms(1); envia_byte_lcd(0,0x28); envia_byte_lcd(0,0x0c); limpa_lcd(); envia_byte_lcd(0,0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Cria caracteres na CG RAM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void cria_cgram() { envia_byte_lcd(0,0b01000000); // Vai para primeira posio da CGRAM envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010100); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000101); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); // // // // // // // // // // // // // // // // Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria a a a a a a a a a a a a a a a a primeira linha de nosso robozinho segunda linha de nosso robozinho terceira linha de nosso robozinho quarta linha de nosso robozinho quinta linha de nosso robozinho sexta linha de nosso robozinho stima linha de nosso robozinho oitava linha de nosso robozinho primeira linha de nosso robozinho 2 segunda linha de nosso robozinho 2 terceira linha de nosso robozinho 2 quarta linha de nosso robozinho 2 quinta linha de nosso robozinho 2 sexta linha de nosso robozinho 2 stima linha de nosso robozinho 2 oitava linha de nosso robozinho 2 return; * * * * * * * * * * * * * * * * * * * * * * * * * Inicializa o LCD * * * * * * * * * * * * * * * * * * * * * * * * * */ Garante que o pino DB4 esto em 0 (low) // Garante que o pino DB5 esto em 0 (low) // Garante que o pino DB6 esto em 0 (low) // Garante que o pino DB7 esto em 0 (low) // Garante que o pino RS esto em 0 (low) // Garante que o pino ENABLE esto em 0 (low) Aguarda 15ms para estabilizar o LCD // // // // // // // // // // // // // // Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD CURSOR HOME - Envia comando para zerar o contador de caracteres e retornar posio inicial (0x80). Aguarda 1ms para estabilizar o LCD FUNCTION SET - Configura o LCD para 4 bits, 2 linhas, fonte 5X7. DISPLAY CONTROL - Display ligado, sem cursor Limpa o LCD ENTRY MODE SET - Desloca o cursor para a direita

// Retorna ao ponto de chamada da funo

envia_byte_lcd(1,0b00001110); // Cria a primeira linha de nosso robozinho 3 envia_byte_lcd(1,0b00010001); // Cria a segunda linha de nosso robozinho 3 Tutorial LCD em 4 vias 91

www.mecatronicadegaragem.blogspot.com.br
envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000101); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00011111); limpa_lcd(); } /***************************************************************************/ /* Final das rotinas para o LCD */ /***************************************************************************/ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ main() Tutorial LCD em 4 vias 92 return; // Retorna ao ponto de chamada da funo // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a terceira linha de nosso robozinho 3 quarta linha de nosso robozinho 3 quinta linha de nosso robozinho 3 sexta linha de nosso robozinho 3 stima linha de nosso robozinho 3 oitava linha de nosso robozinho 3 primeira linha de nosso robozinho 4 segunda linha de nosso robozinho 4 terceira linha de nosso robozinho 4 quarta linha de nosso robozinho 4 quinta linha de nosso robozinho 4 sexta linha de nosso robozinho 4 stima linha de nosso robozinho 4 oitava linha de nosso robozinho 4 primeira linha de nosso janelinha segunda linha de nosso janelinha terceira linha de nosso janelinha quarta linha de nosso janelinha quinta linha de nosso janelinha sexta linha de nosso janelinha stima linha de nosso janelinha oitava linha de nosso janelinha primeira linha de nossa ampulheta 1 segunda linha de nossa ampulheta 1 terceira linha de nossa ampulheta 1 quarta linha de nossa ampulheta 1 quinta linha de nossa ampulheta 1 sexta linha de nossa ampulheta 1 stima linha de nossa ampulheta 1 oitava linha de nossa ampulheta 1 primeira linha de nossa ampulheta 2 segunda linha de nossa ampulheta 2 terceira linha de nossa ampulheta 2 quarta linha de nossa ampulheta 2 quinta linha de nossa ampulheta 2 sexta linha de nossa ampulheta 2 stima linha de nossa ampulheta 2 oitava linha de nossa ampulheta 2 primeira linha de nossa ampulheta 3 segunda linha de nossa ampulheta 3 terceira linha de nossa ampulheta 3 quarta linha de nossa ampulheta 3 quinta linha de nossa ampulheta 3 sexta linha de nossa ampulheta 3 stima linha de nossa ampulheta 3 oitava linha de nossa ampulheta 3

www.mecatronicadegaragem.blogspot.com.br
{

// Reseta portas porta = 0; portb = 0; // configura os tris set_tris_a(0b00111111); set_tris_b(0b11000000); // Inicializa o LCD inicializa_lcd(); //Escreve tela limpa_lcd(); cria_cgram(); //envia_byte_lcd(0,0x80); escreve_lcd(0b00000000); escreve_lcd(0b00000001); escreve_lcd(0b00000010); escreve_lcd(0b00000011); escreve_lcd(0b00000100); escreve_lcd(0b00000101); escreve_lcd(0b00000110); escreve_lcd(0b00000111); envia_byte_lcd(0,0xc0); escreve_lcd(0b00001000); escreve_lcd(0b00001001); escreve_lcd(0b00001010); escreve_lcd(0b00001011); escreve_lcd(0b00001100); escreve_lcd(0b00001101); escreve_lcd(0b00001110); escreve_lcd(0b00001111); // configurao da direo dos pinos de I/O

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // while (true) { } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ }

Tutorial LCD em 4 vias

93

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

94

www.mecatronicadegaragem.blogspot.com.br

Exerccio 5 Uma pequena animao

Tutorial LCD em 4 vias

95

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

96

www.mecatronicadegaragem.blogspot.com.br

Exerccio 5 Uma pequena animao


E agora, como exerccio final, vamos fazer uma pequena animao com os caracteres criados no exerccio anterior e vamos introduzir o conceito de backspace automaticamente pelo LCD. O organograma o mesmo para a McLAB2 e para a nossa placa de testes:
Incio cria_cgram(); anima_cgram();

Define microcontrolador

Vai para a primeira posio da CGRAM (0x40)

Define nmero de interaes

Define configuraes para gravao

Entra com os 8 dados do primeiro caractere

Envia o primeiro caractere

Define configuraes para rotinas de delay

Entra com os 8 dados do segundo caractere

Executa um backspace

Define constantes internas

Entra com os 8 dados do terceiro caractere

Envia o segundo caractere

Define e inicializa os PORTs

Entra com os 8 dados do quarto caractere

Executa um backspace

Define bibliotecas para o LCD: envia_nibble_lcd(); envia_byte_lcd(); escreve_lcd(); limpa_lcd(); inicializa_lcd(); cria_cgram(); anima_cgram();

Entra com os 8 dados do quinto caractere

Envia o terceiro caractere

Entra com os 8 dados do sexto caractere

Executa um backspace

Configura o PIC: Reseta PORTs Configura TRIS Inicializa o LCD Escreve na tela

Entra com os 8 dados do stimo caractere

Apaga o caractere anterior

Entra com os 8 dados do oitavo caractere Interao acabou?

No

Define rotina principal

Limpa o LCD

Sim
Fim Retorna Retorna

Figura 29: Fluxograma para a animao nas placas McLAB2 e de testes

Tutorial LCD em 4 vias

97

www.mecatronicadegaragem.blogspot.com.br

McLAB2 O cdigo a seguir deve ser programado na McLAB2:


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tutorial LCD em 4 vias * * Para uso na placa de testes * * * * Exerccio 5 - Uma pequena animao * * * * Memory usage: ROM=5% RAM=3% - 7% * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 31/08/2005 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Pequena animao para exemplificar o uso dos caracteres gerados na CGRAM // e testar a funo de backspace. // O tempo de animao controlado pela constante tempo /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio do PIC utilizado * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877a.h> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP,NOCPD,NOWRT /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #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_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 #define tempo 150 /* * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao * * * * * * * * * * * * * * * * * * * * * * * #use fast_io(a) // Inicializao rpida dos #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e) #byte #byte #byte #byte porta portb portc portd = = = = 0x05 0x06 0x07 0x08 98 * * * * * * * * * * * * * * * dos port's * * * * * * * * * * * * * * * */ Pinos de I/O

Tutorial LCD em 4 vias

www.mecatronicadegaragem.blogspot.com.br
#byte porte = 0x09 /***************************************************************************/ /* 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 lido output_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 enable output_high(lcd_enable); // ENABLE = 1 delay_us(1); // Recomendado para estabilizar o LCD output_low(lcd_enable); // ENABLE = 0 return; // 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 caractere delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD output_low(lcd_enable); // Desativa a linha ENABLE envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/coamndo envia_nibble_lcd(dado & 0x0f);// Limpa a parte ALTA e envia a parte BAIXA do // dado/comando delay_us(40); // Aguarda 40us para estabilizar o LCD return; // 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,"<caractere a ser mostrado no lcd>"); ou envia_byte_lcd(1,<cdigo do caractere a ser mostrado no lcd>);

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 cvom que o cdigo compilado seja menor. void limpa_lcd() { envia_byte_lcd(0,0x01); // Envia instruo para limpar o LCD delay_ms(2); // Aguarda 2ms para estabilizar o LCD Tutorial LCD em 4 vias 99

www.mecatronicadegaragem.blogspot.com.br
return; // Retorna ao ponto de chamada da funo * * * * * * * * * * * * * * * * * * * * * * * * Inicializa o LCD * * * * * * * * * * * * * * * * * * * * * * * * */ Garante que o pino DB4 esto em 0 (low) Garante que o pino DB5 esto em 0 (low) Garante que o pino DB6 esto em 0 (low) Garante que o pino DB7 esto em 0 (low) Garante que o pino RS esto em 0 (low) Garante que o pino ENABLE esto em 0 (low) Aguarda 15ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD CURSOR HOME - Envia comando para zerar o contador de caracteres e retornar posio inicial (0x80). Aguarda 1ms para estabilizar o LCD FUNCTION SET - Configura o LCD para 4 bits, 2 linhas, fonte 5X7. DISPLAY CONTROL - Display ligado, sem cursor Limpa o LCD ENTRY MODE SET - Desloca o cursor para a direita Retorna ao ponto de chamada da funo

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * void inicializa_lcd() { output_low(lcd_db4); // output_low(lcd_db5); // output_low(lcd_db6); // output_low(lcd_db7); // output_low(lcd_rs); // output_low(lcd_enable); // delay_ms(15); // envia_nibble_lcd(0x03); // delay_ms(5); // envia_nibble_lcd(0x03); // delay_ms(5); // envia_nibble_lcd(0x03); // delay_ms(5); // envia_nibble_lcd(0x02); // // delay_ms(1); // envia_byte_lcd(0,0x28); // // envia_byte_lcd(0,0x0c); // limpa_lcd(); // envia_byte_lcd(0,0x06); // return; // }

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Cria caracteres na CG RAM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void cria_cgram() { //escreve_lcd(0b00000000); //escreve_lcd(0b00000001); //escreve_lcd(0b00000010); //escreve_lcd(0b00000011); //escreve_lcd(0b00000100); //escreve_lcd(0b00000101); //escreve_lcd(0b00000110); //escreve_lcd(0b00000111); envia_byte_lcd(0,0b01000000); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010100); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000101); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); // // // // // // // // // // // // // // // // // Vai para primeira posio da CGRAM Cria a primeira linha de nosso robozinho 1 Cria a segunda linha de nosso robozinho 1 Cria a terceira linha de nosso robozinho 1 Cria a quarta linha de nosso robozinho 1 Cria a quinta linha de nosso robozinho 1 Cria a sexta linha de nosso robozinho 1 Cria a stima linha de nosso robozinho 1 Cria a oitava linha de nosso robozinho 1 Cria Cria Cria Cria Cria Cria Cria Cria a a a a a a a a primeira linha de nosso robozinho 2 segunda linha de nosso robozinho 2 terceira linha de nosso robozinho 2 quarta linha de nosso robozinho 2 quinta linha de nosso robozinho 2 sexta linha de nosso robozinho 2 stima linha de nosso robozinho 2 oitava linha de nosso robozinho 2

envia_byte_lcd(1,0b00001110); // Cria a primeira linha de nosso robozinho 3 Tutorial LCD em 4 vias 100

www.mecatronicadegaragem.blogspot.com.br
envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000101); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00001010); limpa_lcd(); return; // // // // // // // // // // // // // // // Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria a a a a a a a a a a a a a a a segunda linha de nosso robozinho 3 terceira linha de nosso robozinho 3 quarta linha de nosso robozinho 3 quinta linha de nosso robozinho 3 sexta linha de nosso robozinho 3 stima linha de nosso robozinho 3 oitava linha de nosso robozinho 3 primeira linha de nosso robozinho 4 segunda linha de nosso robozinho 4 terceira linha de nosso robozinho 4 quarta linha de nosso robozinho 4 quinta linha de nosso robozinho 4 sexta linha de nosso robozinho 4 stima linha de nosso robozinho 4 oitava linha de nosso robozinho 4

// Retorna ao ponto de chamada da funo

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Cria uma animao na CG RAM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void anima_cgram() { int i; for (i=0;i<=15;i++) { escreve_lcd(0b00000000); delay_ms(tempo); envia_byte_lcd(0,0b00010000); //backspace escreve_lcd(0b00000001); delay_ms(tempo); envia_byte_lcd(0,0b00010000); //backspace escreve_lcd(0b00000010); delay_ms(tempo); envia_byte_lcd(0,0b00010000); //backspace escreve_lcd(0b00000011); delay_ms(tempo); envia_byte_lcd(0,0b00010000); //backspace escreve_lcd(" "); } return; } /***************************************************************************/ /* Final das rotinas para o LCD */ /***************************************************************************/ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ main() { // Configura o PIC setup_adc_ports(no_analogs); // Reseta portas porta = 0; portb = 0; portc = 0; portd = 0; porte = 0; // configura os tris Tutorial LCD em 4 vias 101

www.mecatronicadegaragem.blogspot.com.br
set_tris_a(0b00111111); set_tris_b(0b11111111); set_tris_c(0b11111111); set_tris_d(0b00001111); set_tris_e(0b11111100); // Inicializa o LCD inicializa_lcd(); //Escreve tela limpa_lcd(); cria_cgram(); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Esta rotina a responsvel pelo movimento de vai-e-vem do display. while (true) { //Faz uma animao do robozinho envia_byte_lcd(0,0x80); anima_cgram(); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ } // configurao da direo dos pinos de I/O

Tutorial LCD em 4 vias

102

www.mecatronicadegaragem.blogspot.com.br

Placa de testes O cdigo a seguir deve ser programado na nossa placa de testes:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tutorial LCD em 4 vias * * Para uso na placa de testes * * * * Exerccio 5 - Uma pequena animao * * * * Memory usage: ROM=19% RAM=3% - 7% * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 31/08/2005 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Pequena animao para exemplificar o uso dos caracteres gerados na CGRAM // e testar a funo de backspace. // O tempo de animao controlado pela constante tempo /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio do PIC utilizado * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f628a.h> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses INTRC,NOWDT,PUT,MCLR,NOBROWNOUT,NOLVP #ROM 0x07ff = {0} //Calibragem do oscilador interno /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #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_b5 // pino enable do LCD #define lcd_rs pin_b4 // pino rs do LCD #define lcd_db4 pin_b0 // pino de dados d4 do LCD #define lcd_db5 pin_b1 // pino de dados d5 do LCD #define lcd_db6 pin_b2 // pino de dados d6 do LCD #define lcd_db7 pin_b3 // pino de dados d7 do LCD #define tempo 150 /* * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao * * * * * * * * * * * * * * * * * * * * * * * #use fast_io(a) // Inicializao rpida dos #use fast_io(b) #byte porta = 0x05 #byte portb = 0x06 /***************************************************************************/ /* Rotinas para o LCD */ Tutorial LCD em 4 vias 103 * * * * * * * * * * * * * * * dos port's * * * * * * * * * * * * * * * */ Pinos de I/O

www.mecatronicadegaragem.blogspot.com.br
/***************************************************************************/ //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 lido output_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 enable output_high(lcd_enable); delay_us(1); output_low(lcd_enable); return; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 caractere delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD output_low(lcd_enable); // Desativa a linha ENABLE envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/comando envia_nibble_lcd(dado & 0x0f);// Limpa a parte ALTA e envia a parte BAIXA do // dado/comando delay_us(40); // Aguarda 40us para estabilizar o LCD return; // 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,"<caractere a ser mostrado no LCD>"); ou envia_byte_lcd(1,<cdigo do caractere a ser mostrado no LCD>); // ENABLE = 1 // Recomendado para estabilizar o LCD // ENABLE = 0 // Retorna ao ponto de chamada da funo

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,0x01); // Envia instruo para limpar o LCD delay_ms(2); // Aguarda 2ms para estabilizar o LCD return; // Retorna ao ponto de chamada da funo } Tutorial LCD em 4 vias 104

www.mecatronicadegaragem.blogspot.com.br

/* * * * * * * * * * * * * * * * * * * * * * * * * * * void inicializa_lcd() { output_low(lcd_db4); output_low(lcd_db5); output_low(lcd_db6); output_low(lcd_db7); output_low(lcd_rs); output_low(lcd_enable); delay_ms(15); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x03); delay_ms(5); envia_nibble_lcd(0x02); delay_ms(1); envia_byte_lcd(0,0x28); envia_byte_lcd(0,0x0c); limpa_lcd(); envia_byte_lcd(0,0x06); } return;

* * * * * * * * * * * * * * * * * * * * * * * * * Inicializa o LCD * * * * * * * * * * * * * * * * * * * * * * * * * */ // // // // // // // // // // // // // // // // // // // // // Garante Garante Garante Garante Garante Garante Aguarda que o pino DB4 esto em 0 (low) que o pino DB5 esto em 0 (low) que o pino DB6 esto em 0 (low) que o pino DB7 esto em 0 (low) que o pino RS esto em 0 (low) que o pino ENABLE esto em 0 (low) 15ms para estabilizar o LCD

Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD Envia comando para inicializar o display Aguarda 5ms para estabilizar o LCD CURSOR HOME - Envia comando para zerar o contador de caracteres e retornar posio inicial (0x80). Aguarda 1ms para estabilizar o LCD FUNCTION SET - Configura o LCD para 4 bits, 2 linhas, fonte 5X7. DISPLAY CONTROL - Display ligado, sem cursor Limpa o LCD ENTRY MODE SET - Desloca o cursor para a direita

// Retorna ao ponto de chamada da funo

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Cria caracteres na CG RAM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void cria_cgram() { //escreve_lcd(0b00000000); //escreve_lcd(0b00000001); //escreve_lcd(0b00000010); //escreve_lcd(0b00000011); //escreve_lcd(0b00000100); //escreve_lcd(0b00000101); //escreve_lcd(0b00000110); //escreve_lcd(0b00000111); envia_byte_lcd(0,0b01000000); // Vai para primeira posio da CGRAM envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00011111); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010100); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000101); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); Tutorial LCD em 4 vias // // // // // // // // // // // // // // // // Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria a a a a a a a a a a a a a a a a primeira linha de nosso robozinho 1 segunda linha de nosso robozinho 1 terceira linha de nosso robozinho 1 quarta linha de nosso robozinho 1 quinta linha de nosso robozinho 1 sexta linha de nosso robozinho 1 stima linha de nosso robozinho 1 oitava linha de nosso robozinho 1 primeira linha de nosso robozinho 2 segunda linha de nosso robozinho 2 terceira linha de nosso robozinho 2 quarta linha de nosso robozinho 2 quinta linha de nosso robozinho 2 sexta linha de nosso robozinho 2 stima linha de nosso robozinho 2 oitava linha de nosso robozinho 2 105

www.mecatronicadegaragem.blogspot.com.br
envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000101); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010001); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00010101); envia_byte_lcd(1,0b00001110); envia_byte_lcd(1,0b00000100); envia_byte_lcd(1,0b00001010); envia_byte_lcd(1,0b00001010); limpa_lcd(); return; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Cria uma animao na CG RAM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void anima_cgram() { int i; for (i=0;i<=15;i++) { escreve_lcd(0b00000000); delay_ms(tempo); envia_byte_lcd(0,0b00010000); //backspace escreve_lcd(0b00000001); delay_ms(tempo); envia_byte_lcd(0,0b00010000); //backspace escreve_lcd(0b00000010); delay_ms(tempo); envia_byte_lcd(0,0b00010000); //backspace escreve_lcd(0b00000011); delay_ms(tempo); envia_byte_lcd(0,0b00010000); //backspace escreve_lcd(" "); } return; } /***************************************************************************/ /* Final das rotinas para o LCD */ /***************************************************************************/ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ main() { // Reseta portas porta = 0; portb = 0; // configura os tris set_tris_a(0b00111111); set_tris_b(0b11000000); Tutorial LCD em 4 vias // configurao da direo dos pinos de I/O 106 // Retorna ao ponto de chamada da funo // // // // // // // // // // // // // // // // Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria Cria a a a a a a a a a a a a a a a a primeira linha de nosso robozinho 3 segunda linha de nosso robozinho 3 terceira linha de nosso robozinho 3 quarta linha de nosso robozinho 3 quinta linha de nosso robozinho 3 sexta linha de nosso robozinho 3 stima linha de nosso robozinho 3 oitava linha de nosso robozinho 3 primeira linha de nosso robozinho 4 segunda linha de nosso robozinho 4 terceira linha de nosso robozinho 4 quarta linha de nosso robozinho 4 quinta linha de nosso robozinho 4 sexta linha de nosso robozinho 4 stima linha de nosso robozinho 4 oitava linha de nosso robozinho 4

www.mecatronicadegaragem.blogspot.com.br

// Inicializa o LCD inicializa_lcd(); //Escreve tela limpa_lcd(); cria_cgram(); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Esta rotina a responsvel pelo movimento de vai-e-vem do display. // Ela fica em loop infinito.; while (true) { //Faz uma animao do robozinho envia_byte_lcd(0,0x80); anima_cgram(); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ }

Tutorial LCD em 4 vias

107

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

108

www.mecatronicadegaragem.blogspot.com.br

Consideraes finais

Tutorial LCD em 4 vias

109

www.mecatronicadegaragem.blogspot.com.br

Tutorial LCD em 4 vias

110

www.mecatronicadegaragem.blogspot.com.br

CONSIDERAES FINAIS
Acreditamos que este material cobriu todos os tpicos que abordam a configurao de um mdulo LCD baseado nos processadores HD44780, KS0066U ou equivalentes. Com este material, voc ser capaz de introduzir ou modificar um LCD em seus projetos. Portanto, mos obra e boa sorte!

Eduardo Souza Ramos

Tutorial LCD em 4 vias

111