Você está na página 1de 118

1

Engenharia Eltrica
6 / 7 Semestre

ELETRNICA DIGITAL APOSTILA 01


Prof Daniel Hasse

Displays de Cristal Lquido


Comunicao a quatro vias entre LCD e Microcontroladores
Converso Analgica - Digital em Microcontroladores

SO JOS DOS CAMPOS, SP

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

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

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

Captulo 1 O LCD Alfa-numrico

Tutorial LCD em 4 vias

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

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

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

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

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

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.

Instruo

RS

RW

D7

D6

D5

D4

D3

D2

D1

D0

NOP

Clear Display

Cursor Home

Entry Mode
Set

I/D

S/C

R/L

DL

Endereo DDRAM

BF

Address Counter (Contador de Endereo)

Write Data

Dado

Flag do Read busy (BF) e contador


de endereos.
Escreve dados na DDRAM ou na
CGRAM

Read Data

Dado

L dados da DDRAM ou da CGRAM

Display
Control
Cursor /
Display shift
Function Set
Set CGRAM
Address
Set DDRAM
Address
Busy Flag &
Address

x : Sem
importncia

I/D
S
D
C
B
S/C

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

Endereo CGRAM

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

R/L
DL
N
F

Descrio
Sem efeito
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.

1
0
1
0
1
0
1
0

Ciclos
de
Clock
0
165

3
3
3
3
3
3
0
3
3

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


Deslocamento do display
Movimento do Cursor

CGRAM : Character Generator RAM

Tabela 2: Instrues para inicializao e configurao do LCD


Tutorial LCD em 4 vias

14

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

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

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

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

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

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

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

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

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

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

Figura 18: Inicializando em 4 vias

Tutorial LCD em 4 vias

25

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

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)

Tempo
82us a 4,1ms
40us a 4,1ms
40us
40us
40us
40us
40us
40us
40us
40us
1us

6: Diagrama de temporizao real para o LCD

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

Captulo 2 O Hardware

Tutorial LCD em 4 vias

29

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

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

Captulo 3 O Software

Tutorial LCD em 4 vias

33

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

#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

dos

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

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

portc=0x00;
portd=0x00;
porte=0x00;

// limpa portc
// limpa portd
// limpa porte

tela_principal();

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

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;

Tutorial LCD em 4 vias

// Retorna ao ponto de chamada da funo


38

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

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

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
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;

Tutorial LCD em 4 vias

// Retorna ao ponto de chamada da funo

41

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

Exerccio 1 Inicializando o LCD e Ol Mundo!

Tutorial LCD em 4 vias

43

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

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

=
=
=
=
=

* * * * * * * * *
*
* * * * * * * * */

LCD
LCD
LCD
LCD

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

0x05
0x06
0x07
0x08
0x09

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

46

//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);

// ENABLE = 1
// Recomendado para estabilizar o LCD
// 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

delay_us(40);
return;

/*
*
*
//
//
//
//

// dado/comando
// Aguarda 40us para estabilizar o LCD
// 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

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
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()
{
// 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);

// configurao da direo dos pinos de I/O

// Inicializa o LCD
inicializa_lcd();
//Escreve tela
escreve_lcd("O");
escreve_lcd("l");
escreve_lcd("a");
escreve_lcd(" ");
Tutorial LCD em 4 vias

48

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

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

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)

* * * * * * * * *
*
* * * * * * * * */

LCD
LCD
LCD
LCD

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

#byte porta = 0x05


#byte portb = 0x06
/***************************************************************************/
/*
Rotinas para o LCD
*/
/***************************************************************************/
Tutorial LCD em 4 vias

51

//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);

// ENABLE = 1
// Recomendado para estabilizar o LCD
// 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/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>);

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

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
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);

// configurao da direo dos pinos de I/O

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

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

Exerccio 2 A funo PRINTF();

Tutorial LCD em 4 vias

55

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

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

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

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

=
=
=
=

* * * * * * * * *
*
* * * * * * * * */

LCD
LCD
LCD
LCD

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

0x05
0x06
0x07
0x08

Tutorial LCD em 4 vias

59

#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);

// ENABLE = 1
// Recomendado para estabilizar o LCD
// 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()
Tutorial LCD em 4 vias

60

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;

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()
{
// 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);

// configurao da direo dos pinos de I/O

// Inicializa o LCD
inicializa_lcd();
Tutorial LCD em 4 vias

61

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

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

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)

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

#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

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//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);

// ENABLE = 1
// Recomendado para estabilizar o LCD
// 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/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>);

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

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);

return;

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);

// configurao da direo dos pinos de I/O

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

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

Exerccio 3 Rotacionando o display

Tutorial LCD em 4 vias

69

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

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

=
=
=
=
=

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

0x05
0x06
0x07
0x08
0x09

Tutorial LCD em 4 vias

72

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

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

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

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)

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

#byte porta = 0x05


#byte portb = 0x06
/***************************************************************************/
Tutorial LCD em 4 vias

76

/*
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;

//
//
//
//

ENABLE = 1
Recomendado para estabilizar o LCD
ENABLE = 0
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/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>);

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

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
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);

envia_byte_lcd(0,0x0c);
limpa_lcd();
envia_byte_lcd(0,0x06);

//
//
//
//
//
//
//
//
//
//
//
//
//
//

return;

// Retorna ao ponto de chamada da funo

delay_ms(1);
envia_byte_lcd(0,0x28);

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

/***************************************************************************/
/*
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);

// configurao da direo dos pinos de I/O

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

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

Exerccio 4 Criando caracteres

Tutorial LCD em 4 vias

81

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();

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

Entra com os 8 dados do


quinto caractere

Entra com os 8 dados do


sexto caractere

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

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

#use
#use
#use
#use
#use

fast_io(a)
fast_io(b)
fast_io(c)
fast_io(d)
fast_io(e)

#byte
#byte
#byte
#byte
#byte

porta
portb
portc
portd
porte

=
=
=
=
=

// Inicializao rpida dos Pinos de I/O

0x05
0x06
0x07
0x08
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);

// ENABLE = 1
// Recomendado para estabilizar o LCD
// 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
{
Tutorial LCD em 4 vias

85

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

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

envia_byte_lcd(1,0b00001110);
envia_byte_lcd(1,0b00010001);
envia_byte_lcd(1,0b00001110);
envia_byte_lcd(1,0b00010100);

//
//
//
//

Cria
Cria
Cria
Cria

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

Tutorial LCD em 4 vias

86

envia_byte_lcd(1,0b00001110);
envia_byte_lcd(1,0b00000101);
envia_byte_lcd(1,0b00001010);
envia_byte_lcd(1,0b00010001);

//
//
//
//

Cria
Cria
Cria
Cria

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

a
a
a
a
a
a
a
a

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

a
a
a
a
a
a
a
a

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

a
a
a
a
a
a
a
a

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

a
a
a
a
a
a
a
a

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

a
a
a
a
a
a
a
a

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

limpa_lcd();

return;

// Retorna ao ponto de chamada da funo

/***************************************************************************/
Tutorial LCD em 4 vias

87

/*
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);

// configurao da direo dos pinos de I/O

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

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

#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);

// ENABLE = 1
// Recomendado para estabilizar o LCD
// 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/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>);

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

// 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);

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_byte_lcd(0,0x0c);
limpa_lcd();
envia_byte_lcd(0,0x06);

//
//
//
//
//
//
//
//
//
//
//
//
//
//

return;

// Retorna ao ponto de chamada da funo

delay_ms(1);
envia_byte_lcd(0,0x28);

* * * * * * * * * * * * * * * * * * * * * * * * *
Inicializa 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

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

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

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

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


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

91

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);

//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

a
a
a
a
a
a
a
a

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

a
a
a
a
a
a
a
a

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

a
a
a
a
a
a
a
a

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

a
a
a
a
a
a
a
a

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

a
a
a
a
a
a
a
a

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

limpa_lcd();
}

return;

// Retorna ao ponto de chamada da funo

/***************************************************************************/
/*
Final das rotinas para o LCD
*/
/***************************************************************************/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Configuraes do PIC
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
main()
Tutorial LCD em 4 vias

92

// Reseta portas
porta = 0;
portb = 0;
// configura os tris
set_tris_a(0b00111111);
set_tris_b(0b11000000);

// configurao da direo dos pinos de I/O

// 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);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Rotina principal
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//
while (true)
{
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
Fim do Programa
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
}

Tutorial LCD em 4 vias

93

Exerccio 5 Uma pequena animao

Tutorial LCD em 4 vias

95

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

Entra com os 8 dados do


quinto caractere

Envia o terceiro caractere

Entra com os 8 dados do


sexto caractere

Executa um backspace

Entra com os 8 dados do


stimo caractere

Apaga o caractere anterior

Define bibliotecas para o LCD:


envia_nibble_lcd();
envia_byte_lcd();
escreve_lcd();
limpa_lcd();
inicializa_lcd();
cria_cgram();
anima_cgram();

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

Entra com os 8 dados do


oitavo caractere
Interao
acabou?

Define rotina principal

No

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

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

=
=
=
=

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

0x05
0x06
0x07
0x08

Tutorial LCD em 4 vias

98

#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

return;

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

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

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
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);

//
//
//
//
//
//
//
//
//

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

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

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

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);

//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

a
a
a
a
a
a
a
a

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

limpa_lcd();
return;

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

set_tris_a(0b00111111);
set_tris_b(0b11111111);
set_tris_c(0b11111111);
set_tris_d(0b00001111);
set_tris_e(0b11111100);

// configurao da direo dos pinos de I/O

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

Tutorial LCD em 4 vias

102

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)

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

#byte porta = 0x05


#byte portb = 0x06
/***************************************************************************/
/*
Rotinas para o LCD
*/
Tutorial LCD em 4 vias

103

/***************************************************************************/
//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);

// ENABLE = 1
// Recomendado para estabilizar o LCD
// 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/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>);

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

/* * * * * * * * * * * * *
*
* * * * * * * * * * * * *
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);

//
//
//
//
//
//
//

Garante
Garante
Garante
Garante
Garante
Garante
Aguarda

envia_byte_lcd(0,0x0c);
limpa_lcd();
envia_byte_lcd(0,0x06);

//
//
//
//
//
//
//
//
//
//
//
//
//
//

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

return;

// Retorna ao ponto de chamada da funo

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);

* * * * * * * * * * * * * * * * * * * * * * * * *
Inicializa o LCD
*
* * * * * * * * * * * * * * * * * * * * * * * * */
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

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

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

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

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

Tutorial LCD em 4 vias

105

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

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

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);

//
//
//
//
//
//
//
//

Cria
Cria
Cria
Cria
Cria
Cria
Cria
Cria

a
a
a
a
a
a
a
a

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

limpa_lcd();
}

return;

// 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()
{
// 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

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

Display LCD

01. INTRODUO
Os mdulos LCD so interfaces de sada muito til em sistemas microprocessados. Estes mdulos podem ser grficos e a caracter.
Os mdulos LCD grficos so encontrados com resulues de 122x32, 128x64, 240x64 e 240x128 dots pixel, e geralmente esto
disponveis com 20 pinos para conexo. Os LCD comuns (tipo caracter) so especificados em nmero de linhas por colunas e so
encontrados nas configuraes previstas na Tabela 1.

Nmero de
Colunas

Nmero de
Linhas

Quantidade de
pinos

14

12

14/15

16

14/16

16

14/16

16

14/16

20

14/16

20

14/16

20

14/16

24

14/16

24

14/16

40

16

16

40

Tabela 1 - Mdulos LCD disponveis

Os mdulos podem ser encontrados com LED backlight (com uma iluminao de fundo) para facilitar as leituras durante a noite.
Neste caso, a alimentao deste led faz-se normalmente pelos pinos 15 e 16 para os mdulos comuns e 19 e 20 para os mdulos
grficos, sendo os pinos 15 e 19 para ligao ao anodo e os pinos 16 e 20 para o catodo. A corrente de alimentao deste led varia
de 100 a 200mA, dependendo do modelo.
Estes mdulos utilizam um controlador prprio, permitindo sua interligao com com outras placas atravs de seus pinos, onde
deve ser alimentado o mdulo e interligado o barramento de dados e controle do mdulo com a placa do usurio. Naturalmente
que alm de alimentar e conectar os pinos do mdulo com a placa do usurio dever haver um protocolo de comunicao entre as
partes, que envolve o envio de bytes de instrues e bytes de dados pelo sistema do usurio.

Assim como em um rdio relgio todo mdulo LCD permite um ajuste na intensidade da luz emitida ou ajuste
de contraste, isto possvel variando-se a tenso no pino 3. A Figura 1 mostra um circuito tpico e
recomendado pela maioria dos fabricantes para efetuar este ajuste. Alguns fabricantes recomenda o uso de um
resistor de 4K7 em srie com o potencimetro de 10K.
A Tabela 2 descreve cada pino do mdulo ou do display para conexo deste a outras placas:

Display LCD

Pino

Funo

Descrio

Alimentao

Terra ou GND

Alimentao

VCC ou +5V

V0

Tenso para ajuste de contraste (ver Figura 1)

RS

Seleo:

1 - Dado, 0 - Instruo

R/W

Seleo:

1 - Leitura, 0 - Escrita

Chip select

1 ou (1 0) - Habilita, 0 - Desabilitado

B0

LSB

B1

B2

Barramento

10

B3

de

11

B4

Dados

12

B5

13

B6

14

B7

15

A (qdo existir)

16

K (qdo existir)

MSB
Anodo p/ LED backlight
Catodo p/ LED backlight
Tabela 2 - Pinagem dos Mdulos LCD

Figura 1 - Detalhe do controle de contraste do mdulo LCD

Display LCD

02. INTERFACE COM CPU


Os mdulos LCD so projetados para conectar-se com a maioria das CPUs disponveis no mercado, bastando para isso que esta
CPU atenda as temporizaes de leitura e escrita de instrues e dados, fornecido pelo fabricante do mdulo. A Figura 2 mostra
um exemplo de diagrama de tempos tpico requeridos para operao de escrita no mdulo LCD, estes tempos variam em funo
do clock da CPU do usurio.

Figura 2 - (a) Escrita no LCD (b) Ciclo de Escrita da CPU 8051

A Tabela 3 a seguir mostra a relao entre a freqncia da CPU e a temporizao de leitura/escrita da maioria dos mdulos LCD.
Em geral, podemos conectar o barramento de dados da CPU ao barramento do mdulo, mapeando-o convenientemente na placa
de usurio, e efetuarmos uma operao normal de leitura/escrita sem mais problemas.

Clock da CPU

AS

(MHz)

PW

EH

(nS)

(nS )

08 MHz

325

650

75

10 MHz

250

500

50

12 MHz

200

400

33,3

16 MHz

138

275

12,5

Tabela 3 - Relao clock da CPU x Temporizao do Mdulo LCD

A Figura 3 mostra um exemplo de conexo de uma placa baseada nos microcontroladores da linha Intel de 8 bits (8051), ao
mdulo LCD. Neste caso como os sinais A0 e A1 esto conectados aos pinos 4 e 5, teremos ento 04 (quatro) endereos distintos
para comunicao entre a CPU e o mdulo LCD. A Tabela 4 mostra estes endereos.

Display LCD

Figura 3 - Sistema baseado na CPU 8051 com mdulo LCD

Display LCD

ENDEREO

R/W

RS

4000

Instruo - Escrita no modulo

4001

Dados

4002

Instruo - Leitura no modulo

Dados

4003

DESCRIO
- Escrita no modulo
- Leitura no modulo

Tabela 4 - Endereamento do mdulo LCD para Figura 3

O exemplo apresentado na Figura 3 refere-se a conexo do mdulo LCD com comunicao/transmisso de 8 bits, mas podemos
conectar o mdulo com transmisso a cada 4 bits, conforme mostrado na Figura 4. Neste caso no utilizamos os pinos 7, 8, 9 e
10. Isto muito til quando a CPU do usurio possui poucos pinos de I/O, caso tpico da linha de microprocessadores PIC, como
por exemplo o Basic Stamp. Agora surge a dvida, um mesmo mdulo pode conectar-se com 8 ou 4 bits? como isto possvel?
Ocorre que o mdulo LCD quando alimentado necessita de algumas instrues de inicializao que identificar qual a forma de
transmisso de dados que ser estabelecida entre a CPU e o mdulo.

Figura 4 - Modulo LCD comunicando-se com 4 bits

Display LCD

03. PROGRAMAO / INSTRUES


A Tabela 5 traz um resumo das instrues mais usadas na comunicao com os mdulos LCD.

DESCRIO

RS

R/W

Cdigo h

Liga (sem cursor)

0C

Desliga

0A / 08

01

Liga

0E

Desliga

0C

Desloca para Esquerda

10

Desloca para Direita

14

Cursor Home

02

Cursor Piscante

0D

Cursor com Alternncia

0F

Sentido de deslocamento do

Para a esquerda

04

cursor ao entrar com caracter

Para a direita

06

Deslocamento da mensagem

Para a esquerda

07

ao entrar com caracter

Para a direita

05

Deslocamento da mensagem

Para a esquerda

18

sem entrada de caracter

Para a direita

1C

End. da primeira posio

primeira linha

80

segunda linha

C0

Display

MODO

Limpa Display com


Home cursor
Controle do Cursor

Tabela 5 - Instrues mais comuns

A Tabela 6 apresenta o conjunto de instrues, levando-se em considerao que a comunicao com o mdulo seja com
barramento de 8 bits (fixado durante a inicializao). Para o caso desta comunicao ocorrer com apenas 4 bits (nible), os dados
ou instrues sero enviados por nible. sendo enviado o nible mais significativo primeiro. Por exemplo para limpar o display,
escreve-se o nible 0000 e depois 0001.

Display LCD

INSTRUO

R
S
0

R/
W
0

B7

B6

B5

B4

B3

B2

B1

B0

DESCRIO e tempo de execuo (uS)

1.6 mS

Home p/
Cursor

Fixa o modo de
funcionamento

-Limpa todo o display e retorna o cursor


para a primeira posio da primeira linha
-Retorna o cursor para a 1. coluna da 1.
Linha
-Retorna a mensagem previamente
deslocada a sua posio original
-Estabelece o sentido de deslocamento do
cursor (X=0 p/ esquerda, X=1 p/ direita)
-Estabelece se a mensagem deve ou no
ser deslocada com a entrada de um novo
caracter (S=1 SIM, X=1 p/ direita)
-Esta instruo tem efeito somente durante
a leitura e escrita de dados.
-Liga (D=1) ou desliga display (D=0)
-Liga(C=1) ou desliga cursor (C=0)
-Cursor Piscante(B=1) se C=1
-Desloca o cursor (C=0) ou a mensagem
(C=1) para a Direita se (R=1) ou esquerda
se (R=0)
- Desloca sem alterar o contedo da
DDRAM
-Comunicao do mdulo com 8 bits(Y=1)
ou 4 bits(Y=0)
-Nmero de linhas: 1 (N=0) e 2 ou mais
(N=1)
-Matriz do caracter: 5x7(F=0) ou
5x10(F=1)
- Esta instruo deve ser ativada durante a
inicializao
-Fixa o endero na CGRAM para
posteriormente enviar ou ler o dado (byte)

Limpa Display

Controle do
Display

Desloca cursor
ou mensagem

Fixa o modo de
utilizao do
mdulo LCD

Posiciona no
endereo da
CGRAM
Posiciona no
endereo da
DDRAM

Leitura do
Flag Busy

Escreve dado
na CGRAM /
DDRAM
L Dado na
CGRAM /
DDRAM

1
Endereo da CGRAM

1
Endereo da DDRAM

B
F

AC

1
Dado a ser gravado no LCD

1
Dado lido do mdulo

-Fixa o endero na DDRAM para


posteriormente enviar ou ler o dado (byte)

-L o contedo do contador de endereos


(AC) e o BF. O BF (bit 7) indica se a
ltima operao foi concluda (BF=0
concluda) ou est em execuo (BF=1).
- Grava o byte presente nos pinos de dados
no local apontado pelo contador de
endereos (posio do cursor)
- L o byte no local apontado pelo
contador de endereos (posio do cursor)

1.6 mS

40 uS

40 uS

40 uS

40 uS

40 uS

40 uS

40 uS

40 uS

Tabela 5 - Conjunto de instrues do mdulo LCD

Display LCD

3.1 - DESCRIO DETALHADA DAS INSTRUES


3.1.1- Limpa Display
CDIGO

RS
0

R/W
0

B7
0

B6
0

B5
0
MSB

B4
0

B3
0

B2
0

B1
0
LSB

B0
1

Esta instruo escreve o caracter ASCII 32 que corresponde ao branco ou barra de espao em todos os endereos da DDRAM
apagando a mensagem que estiver escrita. O cursor retorna ao endereo zero, ou seja, posio mais a esquerda da primeira
linha.
3.1.2 - Cursor Home

CDIGO

RS
0

R/W
0

B7
0

B6
0

B5
0
MSB

B4
0

B3
0

B2
0

B1
1
LSB

B0
*

Faz retornar o cursor para a posio mais a esquerda da primeira linha e faz voltar posio original mensagens previamente
deslocadas. O contedo da DDRAM permanece inalterado.

3.1.3 - Fixa o modo de operao

CDIGO

RS
0

R/W
0

B7
0

B6
0

B5
0
MSB

B4
0

B3
0

B2
1

B1
X
LSB

B0
S

Esta instruo tem efeito somente durante a leitura ou escrita de dados, portanto, deve ser ativada na inicializao.
Estabelece o sentido de deslocamento do cursor (X=0 p/ esquerda, X=1 p/ direita)
Estabelece se a mensagem deve ou no ser deslocada com a entrada de um novo caracter
S=1 SIM, S=0 NO. Exemplo: X=1 e S=1 => mensagem desloca p/ direita.
3.1.4 - Controle do Display

CDIGO

RS
0

R/W
0

B7
0

B6
0

B5
0
MSB

B4
0

B3
0

B2
D

B1
C
LSB

B0
B

A mensagem fica aparente quando D=1 e desaparece quando D=0, porm o contedo da DDRAM fica inalterado. O cursor fica
aparente quando C=1 e desaparece quando C=0, porm as propriedades de escritas vigentes permanecem inalteradas. O
cursor quando aparente liga a ltima linha que compem o caracter, exceto quando B=1, que apresenta em alternncia com uma
matriz com todos os pontos negros em intervalos de 0,4 segundos. Quando B=1 e C=0, obteremos a ativao intermitente de uma
matriz completa (todos os pontos da matriz).
3.1.5 - Deslocamento do Cursor ou da Mensagem

CDIGO

RS
0

R/W
0

B7
0

B6
0

B5
0
MSB

B4
1

B3
C

B2
R

B1
*
LSB

B0
*

Display LCD

Desloca o cursor ou a mensagem sem que para isso tenha que escrever ou ler dados do display. Utilizado para posicionamento dos
dados no display.
C
0
0
1
1

R
0
1
0
1

FUNO
Desloca o cursor para a esquerda e decrementa o contador de endereo.
Desloca o cursor para a direita e incrementa o contador de endereo.
Desloca a mensagem e o cursor para a esquerda.
Desloca a mensagem e o cursor para a direita

3.1.6 - Estabelece o modo de utilizao do Mdulo LCD

CDIGO

RS
0

R/W
0

B7
0

B6
0

B5
1
MSB

B4
Y

B3
N

B2
F

B1
*
LSB

B0
*

Y estabelece o modo de comunicao. Se Y=1 estabelece 8 bits e quando Y=0 ser 4 bits, enviados em duas operaes, com os 4
bits (Nible) mais significativos sendo enviados primeiro. N fixa o nmero de linhas: N=0 para uma linha e N=1 para duas ou
mais linhas. F fixa o tipo da matriz: F=0 para matriz 7x5 ou 8x5 e F=1 para matriz 10x5 (somente possvel quando apresentando
em uma linha).
3.1.7 - Endereamento da CGRAM
CGRAM uma regio da memria RAM destinada para criao de caracteres especiais, como por exemplo: , , , etc.

CDIGO

RS
0

R/W
0

B7
0

B6
1

B5
A
MSB

B4
A

B3
A

B2
A

B1
A
LSB

B0
A

Estabelece o endereo da CGRAM no contador de endereos (AC) como um nmero binrio AAAAAA e aps isto os dados sero
escritos ou lidos pela CPU neste endereo. Cada caracter especial ocupa 8 endereos na CGRAM.
3.1.8 - Endereamento da DDRAM

CDIGO

RS
0

R/W
0

B7
1

B6
B5
A
A
MSB

B4
A

B3
A

B2
A

B1
A
LSB

B0
A

Estabelece o endereo da DDRAM no contador de endereos (AC) como um nmero binrio AAAAAAA e aps isto os dados
sero escritos ou lidos pela CPU neste endereo. Para os display de uma linha AAAAAAA varia de 80H a CFH. J para todos os
display de duas linhas varia de 80H a A7H para a primeira linha e de C0H a E7H para a segunda linha.
3.1.9 - Busy Flag (BF)

CDIGO

RS
0

R/W
1

B7
BF

B6
B5
A
A
MSB

B4
A

B3
A

B2
A

B1
A
LSB

B0
A

Busy Flag ou o bit 7 indica ao sistema onde est conectado o mdulo LCD, se o controlador do mdulo est ocupado com alguma
operao interna (BF=1), e neste caso, no aceita nenhuma instruo at que BF volte para 0.
Alm disso, permite a leitura do contedo do contador de endereos (AC) expressa por AAAAAAA. O contador de endereos
pode conter tanto endereo da CGRAM como da DDRAM, depende neste caso, da instruo anterior.

Display LCD

3.1.10 - Escrita de dados na DDRAM ou CGRAM

CDIGO

RS
1

R/W
0

B7
A

B6
B5
A
A
MSB

B4
A

B3
A

B2
A

B1
A
LSB

B0
A

Escreve o byte AAAAAAAA tanto na CGRAM como na DDRAM, dependendo da instruo anterior (que define o endereo).
Aps a escrita, o endereo automaticamente incrementado ou decrementado de uma unidade dependendo do modo escolhido
(ver item 3.1.3).
3.1.11 - Leitura de dados na DDRAM ou CGRAM

CDIGO

RS
1

R/W
1

B7
A

B6
B5
A
A
MSB

B4
A

B3
A

B2
A

B1
A
LSB

B0
A

Faz uma leitura na CGRAM ou na DDRAM, dependendo da instruo anterior (que define o endereo). importante que
precedendo a esta leitura seja executado a instruo de estabelecimento do endereo da CGRAM ou DDRAM, pois caso contrrio
o dado lido invlido.

3.2 - TABELAS DE ENDEREOS DOS CARCTERES NA DDRAM


A seguir resumiremos os endereos da DDRAM (em hexadecimal) dos caracteres da maioria dos mdulos LCD disponveis no
mercado.

Mdulo 8x1
Endereo(hexa)

10

1
80

2
81

Caracter
4
5
83
84

3
82

6
85

7
86

8
87

LCD 16x1

1
80

2
81

3
82

4
83

5
84

6
85

7
86

8
87

9
88

10
89

11
8
A

12
8B

13
8C

14
8
D

15
8E

16
8F

LCD 16x1

1
80

2
81

3
82

4
83

5
84

6
85

7
86

8
87

9
C0

10
C1

11
C2

12
C3

13
C4

14
C5

15
C6

16
C7

LCD 16x2
linha 1

1
80

2
81

3
82

4
83

5
84

6
85

7
86

8
87

9
88

10
89

12
8B

13
8C

16
8F

C0

C1

C2

C3

C4

C5

C6

C7

C8

C9

C
B

C
C

14
8
D
C
D

15
8E

linha 2

11
8
A
C
A

C
E

C
F

Display LCD

LCD
20x2
linha 1
linha 2

LCD
20x4
linha 1
linha 2
linha 3
linha 4

10 11 12 13 14 15 16 17 18 19 20

80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3

80
C0
80
C0

81
C1
81
C1

82
C2
82
C2

83
C3
83
C3

84
C4
84
C4

85
C5
85
C5

86
C6
86
C6

87
C7
87
C7

88
C8
88
C8

10 11 12 13 14 15 16 17 18 19 20
89
C9
89
C9

8A
CA
8A
CA

8B
CB
8B
CB

8C
CC
8C
CC

8D
CD
8D
CD

8E
CE
8E
CE

8F
CF
8F
CF

90
D0
90
D0

91
D1
91
D1

92
D2
92
D2

93
D3
93
D3

LCD 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
24x1
LCD
24x2
linha 1 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97
linha 2 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7

LCD
40x1
a LCD
40X4
linha 1
linha 2
linha 3
linha 4
Cont.

10 11 12 13 14 15 16 17 18 19 20

80
C0
80
C0
21

81
C1
81
C1
22

82
C2
82
C2
23

83
C3
83
C3
24

84
C4
84
C4
25

85
C5
85
C5
26

86
C6
86
C6
27

87
C7
87
C7
28

88
C8
88
C8
29

89
C9
89
C9
30

8A
CA
8A
CA
31

8B
CB
8B
CB
32

8C
CC
8C
CC
33

8D
CD
8D
CD
34

8E
CE
8E
CE
35

8F
CF
8F
CF
36

90
D0
90
D0
37

91
D1
91
D1
38

92
D2
92
D2
39

93
D3
93
D3
40

linha 1
linha 2
linha 3
linha 4

94
D4
94
D4

95
D5
95
D5

96
D6
96
D6

97
D7
97
D7

98
D8
98
D8

99
D9
99
D9

9A
DA
9A
DA

9B
DB
9B
DB

9C
DC
9C
DC

9E
DD
9E
DD

9D
DE
9D
DE

9F
DF
9F
DF

A0
E0
A0
E0

A1
E1
A1
E1

A2
E2
A2
E2

A3
E3
A3
E3

A4
E4
A4
E4

A5
E5
A5
E5

A6
E6
A6
E6

A7
E7
A7
E7

OBS:
Para os mdulos de 04 linhas estamos considerando que existe um outro pino de habilitao (como o pino 6) para as duas
ltimas linhas, portando outros endereos de hardware.
Antes de enviar uma instruo para escrita de dados no display, enviar antes uma de endereamento na DDRAM, com o
endereo onde deve ser escrito o caracter, tipo um gotoxy().

11

Display LCD

3.3 - TABELAS DE ENDEREOS DOS CARCTERES NA CGRAM


Os caracteres especiais previamente programado, durante a inicializao, podem ser utilizados a qualquer tempo como se fossem
caracteres normais, lembrando que os endereos bases em hexadecimal para gravao dos caracteres especiais, na maioria dos
mdulos LCD, so respectivamente: 40, 48, 50, 58, 60, 68, 70 e 78. Cada caracter especial ocupa 8 (oito) endereos.

RS

R/W

Endereo 50

Dado em Binrio

50

51

52

10

53

10

54

55

56

57

HEXA

0E
x

x
x

50

x
x

11

15
0E
10
00*

Tabela 7 - Caracter especial {} na CGRAM

Isto significa que para utilizarmos o caracter gravado no endereo base 50, durante a inicializao ou reset do sistema, teremos
que escrevermos 8 bytes entre os endereos 50 e 57, para construirmos o caracter. Para ilustrar este procedimento, supor que
queiramos construir o caracter {} no endereo base 50. Neste caso, devemos construir o mapa deste caracter especial como
mostrado na Tabela 7 (supondo estar trabalhando com matriz 7x5 e com auto incremento de endereo a cada escrita). Observe
que o ltimo endereo sempre ser 00, pois esta posio sempre ocupada pelo cursor.

3.4 - INICIALIZAO DOS MDULOS LCD


Toda vez que alimentamos o mdulo LCD deve ser executado o procedimento de inicializao, que consiste no envio de uma
seqncia de instrues para configurar o modo de operao para execuo de um dado programa de interfaceamento. Em muitos
display este procedimento ocorre automaticamente, dentro de condies especficas que envolve temporizaes mnimas referente
a transio do nvel lgico 0 para 1, ao ligarmos a fonte. Em caso de dvidas, recomendamos o envio destas instrues aps o
reset do sistema.

3.4.1 - Inicializao para sistemas 8 bits de dados (5 instrues)


Entre as duas primeiras instrues recomendamos um delay de 15 mS. As demais instrues podem ser escritas aps checar o
Busy Flag.

12

MDULO LCD
1 linha - Matriz 7x5 e 8x5

1
30

1 linha - Matriz 10x5

34

2 linha - Matriz 7x5 e 8x5

38

15m
S
15m
S
15m
S

Instrues em Hexadecimal (8 bits)


2
3
4
30
06
0E
15m
BF
S
34
06
0E
15m
BF
S
38
06
0E
15m
BF
S

BF

5
01

BF

01

BF

01

Display LCD

3.4.2 - Inicializao para sistemas 4 bits de dados (5 instrues)


Entre as quatro primeiras instrues recomendamos um delay de 15 mS. As demais instrues podem ser escritas aps checar o
Busy Flag. Estes bits (nible) devem estar conectados aos pinos 11, 12.13 e 14.

MDULO LCD
1 linha - Matriz 7x5 e 8x5
1 linha - Matriz 10x5
2 linha - Matriz 7x5 e 8x5

1
3
3
3

2
3
3
3

3
3
3
3

Instrues em Hexadecimal (4 bits)


4
5
6
7
8
9
10
2
2
0
0
8
0
1
2
2
4
0
8
0
1
2
2
8
0
8
0
1

11
0
0
0

12
1
1
1

13

Display LCD

04. ROTEIRO PARA PROGRAMAO


A seguir passaremos a descrever um resumo dos procedimentos para utilizao de um mdulo ou display LCD:
1. Ao energizar o mdulo ajuste o potencimetro de controle do brilho ou contraste at obter a visualizao da matriciao na
primeira linha para mdulo de duas linhas ou at a matriciao de meia linha para mdulos de uma linha.
2. Alguns mdulos de uma linha s funcionam com a instruo 38 ao invs de 30, conforme instrues de inicializao.
3. O sinal de Enable (pino 6) dever ser gerado conforme a temporizao mostrada na Figura 2. Os cdigos de dados ou de
instrues s sero processados pelo processador do mdulo aps a descida do sinal do Enable.
4. Para ajustar a velocidade de comunicao entre a CPU do usurio e o mdulo LCD existem duas possibilidades:
Intercalar uma rotina de atraso de aproximadamente 15 mS entre as instrues.
Fazer a leitura do Busy Flag antes do envio de cada instruo e s enviar quando o mesmo for 0. Neste caso, a nica
exceo ser durante a inicializao.
5. Durante a inicializao enviar a seqncia correta das instrues de inicializao conforme item 3.4
6. Para programar caracteres na CGRAM, faa inicialmente o endereamento da mesma.
7. Aps a escrita de dados na CGRAM envie a instruo 01, para posicionar o cursor.
8. Para escrever os caracteres especiais previamente gravados na CGRAM, utilize os cdigos de 00 at 07 correspondente aos
endereos bases de 40, 48 at 78 em hexa.
9. Comandos teis:

14

FIXAO DAS CONDIES DE UTILIZAO


1 linha 5x7 (8 bits)
2 linha 5x7 (8 bits)
1 linha 5x10 (8 bits)
1 linha 5x7 (4 bits)
2 linha 5x7 (4 bits)
1 linha 5x10 (4 bits)

Instruo
30H
38H
34H
20H
28H
24H

CONTROLE DISPLAY
Display aceso c/ cursor fixo
Display aceso c/ cursor intermitente
Display aceso sem cursor
Display apagado

Instruo
0EH
0FH
0CH
08H

MODO DE OPERAO
Escreve deslocando a mensagem para esquerda (cursor fixo)
Escreve deslocando a mensagem para a direita (cursor fixo)
Escreve deslocando o cursor para a direita
Escreve deslocando o cursor para a esquerda

Instruo
07H
05H
06H
04H

Display LCD

OUTROS COMANDOS TEIS


Limpa display e retorna o cursor para o inicio
Retorna o cursor para o inicio (sem alterar a DDRAM)
Desloca somente o cursor para a direita
Desloca somente o cursor para a esquerda
Desloca o cursor + mensagem para a direita
Desloca o cursor + mensagem para a esquerda
Desloca o cursor para posio inicial da segunda linha
Desloca o cursor para posio inicial da primeira linha

Instruo
01H
02H
14H
10H
1CH
18H
C0H
80H

CGRAM (caracteres especiais)


Endereo inicial para construir caracteres especiais
Para escrever o primeiro caracter (previamente construdos)
Para escrever o ltimo caracter (previamente construdos)

Instruo
40H
00H
07H

Obs: Aps o endereamento da CGRAM, o cursor se desloca para a primeira posio da segunda linha (ou metade), portanto
recomendado enviar a instruo 01 ou limpa display e cursor home.

15

Display LCD

05. CUIDADOS ESPECIAIS COM MDULOS LCD

5.1 - MANUSEIO

Somente retire o mdulo de sua embalagem protetora imediatamente antes de sua instalao
No guarde os mdulos em recintos de alta temperatura e alta umidade. A temperatura de armazenamento dever estar
compreendida entre 5 e 30 oC.
O LCD coberto por uma lmina plstica polarizada a qual no pode ser riscada. Cuidado em seu manuseio. Para a limpeza
da lmina utilize cotonetes embebido em benzina. No utilize outros tipos de solventes.
Observe cuidadosamente os procedimentos de controle anti-esttico quando manusear os mdulos. Eles incorporam circuitos
integrados CMOS LSI os quais so sensveis descarga eletrosttica. No toque nos terminais do conector, trilhas do circuito
impresso e/ou terminais do CI.

5.2 - INSTALAO

Nunca desmonte o mdulo


Use uma estao de solda aterrada para soldagem de conectores ou terminais.
montador dever tambm ser convenientemente aterrado.
Sempre que o projeto o permita, instale o mdulo atrs de uma janela protetora de plstico ou vidro.
Somente retire a fita adesiva que protege a lmina plstica frontal imediatamente antes de seu uso.

5.3 - OPERAO

16

Nunca instale ou desconecte o mdulo com sua alimentao ligada.


Sempre opere os mdulos respeitando sua gama de temperatura de operao.
Observe cuidadosamente os valores das tenses de alimentao e os nveis dos sinais de controle.
Ajuste a tenso no pino 3 (V0) para obter o contraste mais conveniente para uma dada aplicao.

Display LCD

06. EXEMPLO DE PROGRAMAO


Baseado no hardware da Figura 3, eaborar um programa em assembler para o 8031 que escreva no mdulo LCD a seguinte
mensagem: Vila Nova.
;=======================================================================
; Programa: Exemplo para manuseio de display ou modulo LCD
; Autor: Ilton L. Barbacena
; Data: Out/96
; Compilador: ASM51.EXE / versao shareware para 8051 / $mod51
; versao: 1.0
; Descricao:
Este programa grava a mensagem "Vila Nova"
;
no display LCD 2x20 (duas linha de 20 caracteres).
;
Os pinos de dados do mudulo LCD estao conectados
;
diretamente no barramento de dados da CPU, conforme
;
Figura 3 da apostila sobre LCD.
;=======================================================================
$mod51
lcd_wr_inst equ 4000H
lcd_wr_dado equ 4001H
lcd_rd_inst equ 4002H
lcd_rd_dado equ 4003H
;========================================================================
; Programa principal
;========================================================================
ORG 0H
MOV SP,#50H
MOV TMOD,#11H
CLR EA
CALL inicia_lcd
MOV R7,#0FFH
loop:

; TIMER1 / TIMER0 no modo 1


; desabilita todas as interrupcoes

INC R7
MOV A,R7
MOV DPTR,#mensagem
MOVC A,@A+DPTR
CJNE A,#0FFH,cont
JMP fim

; le caracter da mensagem
; testa se fim da mensagem

cont:

CALL wr_dado
CALL espera
JMP loop

; escreve o conteudo de acumulador no LCD


; aguarda busy flag

fim:

JMP fim

; fim do programa

17

Display LCD

;=======================================================================
; Rotinas chamadas pelo Programa Principal
;=======================================================================
ORG 100H
inicia_lcd:
MOV A,#38H
CALL wr_inst
CALL tempo
MOV A,#38H
CALL wr_inst
CALL tempo
MOV A,#06H
CALL wr_inst
CALL espera
MOV A,#0EH
CALL wr_inst
CALL espera
MOV A,#01H
CALL wr_inst
CALL espera
RET
espera:
CALL rd_inst
RLC A
JC espera
RET
wr_inst:

; rotina de inicializacao
; 2 linhas / matriz 7x5
; delay de 15mS
; 2 linhas / matriz 7x5
; delay de 15mS
; cursor com autoincremento para direita
; busy flag
; liga display / cursor
; busy flag
; limpa display / cursor home
; busy flag

; rotina para aguardar busy flag


; ler busy flag e retorna em A
; bit7=BF vai para o carry
; se BF=1 => verifica novamente

; escreve a instrucao em A no LCD


MOV DPTR,#lcd_wr_inst
MOVX @DPTR,A
RET

wr_dado:

; escreve o dado em A no LCD


MOV DPTR,#lcd_wr_dado
MOVX @DPTR,A
RET

rd_inst:

; le o Busy Flag e o contador de endereco


MOV DPTR,#lcd_rd_inst
MOVX A,@DPTR
RET

rd_dado:
MOV DPTR,#lcd_rd_dado
MOVX A,@DPTR
RET

18

; retorna em A

; le dado / de qual endereco?


; depende da ultima operacao no LCD
; retorna em A

Display LCD

;=========================================================
; Rotina de tempo: 15 mS / clock 12 MHz => 50.000 ciclos
;=========================================================
tempo:
MOV DPTR,#15536
MOV TH1,DPH
MOV TL1,DPL
SETB TR1
JNB TF1,$
CLR TR1
CLR TF1
RET
mensagem:

; (65536-50000)

; dispara timer1
; aguarda estouro => 50.0000
; prepara para proxima chamada

; mensagem a ser escrita no LCD


DB 'Vila Nova', 0FFH
END

; obrigatorio

Exerccio para praticar:


Repetir o exerccio anterior, porm com a mensagem Escola Tcnica. Construir o {} na CGRAM. Lembre-se que apenas os
cdigos ascii so caracteres vlidos para o LCD (verificar a tabela no manual do fabricante).

19

PIC: Conversor A/D e LCD

OBJETIVOS

Compreender a operao do conversor A/D do PIC;


Aprender a utilizar as funes do drive de LCD ;
Desenvolver uma IHM usando o LCD e o teclado da placa de experimentos;

CONVERSOR A/D
O mdulo do conversor A/D possui 8 entradas analgicas, que possuem um capacitor de sampleand-hold. A sada do sample-and-hold conectada a entrada do conversor A/D a partir de um
multiplex 8 x 1. O conversor A/D gera uma palavra binria de 10 bits para representar o valor de
tenso na entrada analgica selecionada.
O mdulo A/D tem duas entradas de tenso de referncia (alta e baixa), que so selecionadas por
software, entre algumas opes de combinao pr-estabelecidas. Uma caracterstica apenas
presente no mdulo conversor A/D que o mesmo pode operar mesmo o PIC estando no modo
SLEEP. Para operar neste modo o sinal de clock do conversor A/D (CAD) deve ser derivado do
oscilador RC interno do PIC.
O conversor A/D possui quatro registradores:
Registrador do byte mais significado do resultado da converso (ADRESH);
Registrador do byte menos significado do resultado da converso (ADRESL);
Registrador de controle 0 (ADCON0) e
Registrador de controle 1.
Os registradores ADRESH:ADRESL contm os 10 bits do resultado da converso. Quando a
mesma concluda, o resultado carregado nesses registradores, o bit GO/DONE (bit 2 do Reg.
ADCON0) resetado e o flag de interrupo, bit ADIF, setado.
Aps a configurao do mdulo como desejado, o canal cujo sinal analgico deve ser convertido,
deve ser selecionado antes da converso ser iniciada. Os canais de entrada analgicos devem ter
seus correspondentes bits TRIS ajustado para que os pinos das portas A e E se comportem como
entradas. Aps o perodo de aquisio do sinal ter finalizado (aproximadamente 20s) a
converso A/D pode ser iniciada conforme os seguintes passos:
1. Configure o mdulo A/D
Configure os pinos de entrada analgica, as tenses de referncia e os pinos de I/O
digital (ADCON1);
Selecione o canal de entrada analgica (ADCON0);
Selecione a freqncia do sinal de clock do conversor A/D (ADCON0);
Ative o mdulo A/D;
2. Configure a interrupo do mdulo A/D (se desejado);
Resete o bit ADIF;
Sete o bit ADIE;
Sete o bit GIE;
3. Aguarde o tempo de aquisio requerido;
4. Inicie a converso

Sete o bit GO/DONE (ADCON0)


5. Aguarde o tempo de converso ter transcorrido;
Realize um POLLING no bit GO/DONE, verificando se o seu valor zero
(indicativo de fim de converso A/D);
ou aguarde pela interrupo gerada pelo mdulo A/D ao fim da converso;
6. Leia o par de registradores (ADRESH:ADRESL), resete o bit ADIF se a interrupo do
conversor A/D est sendo utilizada;
7. Para realizar uma nova converso retorne ao passo 1 ou 2 (antes de uma nova converso
ser iniciada, deve ser aguardado um tempo de 2TAD, que o tempo de converso por bit,
cujo valor definido na tabela 1).
O conversor A/D necessita de no mnimo 12 TAD para realizar uma converso de 10 bits. A fonte
do clock do conversor A/D selecionada por software entre as possibilidades abaixo:
2Tosc
8Tosc
32Tosc
Oscilador RC interno
Para uma converso correta, o clock do conversor A/D deve ser selecionado para garantir um TAD
mnimo de 1.6s. A tabela 1 mostra os valores de TAD em funo da seleo da fonte do clock.
Tabela1 TAD x Mxima freqncia de converso

Se o bit GO/DONE for resetado durante uma converso, esta ser abortada. Os registradores de
resultado do mdulo A/D no sero atualizados com a parcialmente concluda converso. Assim,
os registradores ADRESH:ADRESL continuaram armazenando o valor da ltima converso
concluda (ou o ltimo valor escrito para os registradores ADRESH:ADRESL). Aps uma
converso ser abortada, um tempo de 2TAD necessrio antes de uma nova converso ser
iniciada. Aps este tempo, a aquisio do canal selecionado automaticamente iniciada.
O par de registradores ADRESH:ADRESL comporta 16 bits, assim, o valor convertido de 10 bits
pode ser justificado a direita ou esquerda, de acordo com o bit seleo de formato do conversor
A/D (ADFM), que controla a justificao. Os bits extras no utilizados so carregados com 0
(zeros). Quando o mdulo A/D no estiver sendo utilizado, os registradores ADRESH:ADRESL
podem ser usados como dois registradores de propsito geral de 8 bits.

Justificao do resultado da converso A/D

Diagrama de blocos do conversor A/D

Registrador ADCON0 - Controla a operao do mdulo A/D.

Registrador ADCON1 Configura a funo dos pinos das portas (A e E)

Os registradores ADCON1 e TRIS controlam a operao dos pinos das portas A/D. Os pinos das
portas que sero entradas analgicas devem ter seus correspondentes bits TRIS setados. Se o bit
est resetado, o nvel de tenso da sada digital ser convertido. A operao do conversor A/D
independe do estado dos bits CHS2:CHS0 e dos bits TRIS
Observaes:
1 Quando o registrador da porta lido, qualquer pino configurado como um canal de entrada
analgica ser lido como zero (nvel baixo). Pinos configurados como entradas digitais iro se
converter em entradas analgicas. Nveis analgicos em uma entrada configurada como digital,
no afetaro a preciso da converso.
2 Nveis analgicos em qualquer pino que definido como uma entrada digital (incluindo os
pinos AN7:AN0) podem fazer com que o buffer de entrada consuma corrente que est fora das
especificaes do dispositivo.

Registradores associados com o mdulo do conversor A/D

As rotinas abaixo implementam as funes utilizadas para escrever


caracteres e/ou mensagens em um LCD (Display de Cristal Lquido) de 16
colunas por 2 linhas.

/*=====================================================================
=======================================================================
ARQUIVO - DRIVER:
LCD_16x2_LIB.C
DATA DE CRIAO:
03/11/2003
REVISO:
1.0
DATA DA ULTIMA REV: 03/12/2004
ULTIMA REV:
1.1
MICROCONTROLADOR:
FAMILIA PIC
FUNO:
DESCRIO:
BIBLIOTECA DE MANIPULAO DO DISPLAY DE CRISTAL
LQUIDO (LCD 16X2).
AUTOR:

TC. LCIO HLIO

=======================================================================
=====================================================================*/

#ifndef

CS_LCD

#define

CS_LCD

PIN_E0

#define

RS_LCD

PIN_E1

#define

D4_LCD

PIN_D4

#define

D5_LCD

PIN_D5

#define

D6_LCD

PIN_D6

#define

D7_LCD

PIN_D7

// Pino de Controle "CS - CHIP


//SELECT" do LCD --------- (pino 6).
// Pino de Controle "RS - REGISTER
//SELECT" do LCD ----- (pino 4).
// Pino do Barramento de Dados "D4 //4" do LCD --- (pino 11).
// Pino do Barramento de Dados "D5 //5" do LCD --- (pino 12).
// Pino do Barramento de Dados "D6 //6" do LCD --- (pino 13).
// Pino do Barramento de Dados "D7 //7" do LCD --- (pino 14).

Dado
Dado
Dado
Dado

Você também pode gostar