HOME PROJETOS PROGRAMAÇÃO |
Vamos aprender como conectar ao PIC um LCD gráfico padrão KS0108 de 64 linhas por 128 colunas.
O LCD Gráfico padrão KS0108 possui 2 controladoras ou dois lados, conforme mostra a figura 1.
Durante o trabalho, esses lados podem ser usados separadamente ou ao mesmo tempo através dos pinos
CS1 para o lado 1 e CS2 para o lado 2 do LCD.
Um nível alto (+5V) num desses pinos ativa o lado correspondente.
Quando o nível estiver baixo (0V), o lado correspondente estará inativo e não responderá aos comandos enviados
ao LCD.
Cada lado do LCD é composto de 8 páginas (de 0 a 7) de 64 bytes cada, onde cada byte representa uma coluna de 8 bits na posição vertical. Essas colunas são numeradas de 0 a 63.
O bit de menor significância (bit 0) fica do lado de cima, sendo que cada bit dessa coluna representa um ponto na tela do LCD. Assim, se quisermos acender o terceiro ponto da primeira coluna da página 0 (zero), devemos enviar ao LCD o byte 0x04 ou em binário b'00000100', onde os bits 0 e 1 estão desligados, o bit 2 está ligado e os bits de 3 a 7 estão desligados
Podemos dizer então, que escrever num LCD gráfico será, em primeiro lugar, uma questão de posicionar no ponto desejado da tela e, em segundo lugar, ligar ou desligar o bit desejado. Além disso, não poderemos escrever caracteres diretamente num LCD gráfico do mesmo modo como fazemos num LCD alfanumérico, porque só poderemos enviar uma coluna vertical por vez. Para escrever caracteres de "A" a "Z" e de "0" a "9" devemos montar mapas ou desenhos contendo vários bytes verticais para cada caracter. Do mesmo modo, podemos fazer desenhos como quadrados, retângulos, triângulos e enviá-los ao LCD. Veja o programa exemplo no fim desta página.
Figura 1 |
Mapeando um Caracter | ||
A figura ao lado mostra um mapa ou desenho do caracter "A" que tem 8 pontos de largura por 8 pontos de altura. Os "#" representam os pontos acesos no LCD e os "." representam os pontos apagados. A coluna 0 é formada verticalmente por 7 pontos acesos ("#") e um ponto apagado ("."). Note que essa mesma configuração se repete na coluna 6. Começando pelo bit 7 da coluna 0, teremos a configuração ".#######", que representado em binário é b'01111111' ou 0x7F em hexadecimal. Prosseguindo com o bit 7 da coluna 1, teremos a configuração "....#..#", que representado em binário é b'00001001' ou 0x09 em hexadecimal. Essa mesma configuração se repete nas colunas 2, 3, 4 e 5. Na coluna 7 a configuração é "........" cuja representação binária é b'00000000' ou 0x00 em hexadecimal. Segue que, para escrever o caracter "A" no LCD usando esse mapeamento, devemos enviar a sequência 0x7F, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7F, 0x00 para a posição desejada. |
|
Antes de começar a lixar os bits e bytes no LCD, é necessário conectá-lo a um microcontrolador. Usaremos microcontroladores da família 18F porque eles possuem memória Flash e memória RAM suficiente para suportar a carga de dados requirida pelos LCDs gráficos. Além disso, serão necessárias 14 portas para conectar o LCD gráfico ao microcontrolador: 8 portas de I/O para fazer a conexão do bus de dados e mais 6 portas para o bus de comandos, por isso, o ideal será usar um PIC18F4520 ou um PIC18F4620.
A figura 2, abaixo, mostra um esquema de conexão entre um microcontrolador PIC18F4520 e o LCD gráfico.
Somente os nomes dos pinos do LCD foram usados e seus números não foram mostrados porque podem variar de posição de fabricante para fabricante. Ao adquirir um LCD gráfico consulte o data sheet para saber a posição correta dos pinos.
Figura 2 |
Antes de continuar, monte o circuito acima num protoboard usando um cristal com frequência de 20MHZ para que o programa fique bem ágil.
Devemos observar que em alguns LCDs podemos encontrar um pino de nome DI e, em outros, um pino de nome RS. Os nomes mudam mas a função é a mesma.
Passaremos, agora, a estudar como se faz a comunicação com o LCD gráfico.
A figura 3, mostra a tabela de comandos utilizados para operação do LCD gráfico.
Notar que todo comando é composto pelos bits de controle RS, R/W e pelos bits de dados DB0 a DB7
O bit RS informa ao LCD que tipo de informação vai pelo bus de dados (DB0 a DB7).
Quando desejarmos enviar comandos ao LCD, devemos fazer RS=0 (Low).
Quando desejarmos enviar dados ao LCD, devemos fazer RS=1 (High).
Assim, de acordo com a tabela da figura 3, para dar o comando que coloca o LCD ON/OFF, devemos fazer RS=0 (Low).
Para ler (READ) ou gravar (WRITE) no LCD fazemos RS=1 (High).
Figura 3 |
O bit R/W informa ao LCD o tipo de operação requisitada pelo microcontrolador, isto é, informa o LCD se o microcontrolador deseja enviar (Write) ou receber (Read) uma informação.
Para enviar (Write) um comando ou dado ao LCD, devemos fazer R/W=0 (Low).
Para receber (Read) um dado ou o Status do LCD, devemos fazer R/W=1 (High).
Notar, na figura 3, que o único comando (RS=0 e R/W=1 ) que implica no microcontrolador receber uma informação é o comando Status Read.
Para enviar um comando ao LCD, devemos seguir a seguinte sequência de operações:
Para enviar um dado ao LCD, devemos seguir a seguinte sequência de operações:
Para ler um dado do LCD, devemos seguir a seguinte sequência de operações:
O comando ON/OFF habilita e desabilita o LCD dependendo do valor do bit DB0.
O comando para desativar o LCD pode ser codificado como:
LCD OFF | RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 |
O comando para ativar o LCD pode ser codificado como:
LCD ON | RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
Antes de enviarmos um dado ao LCD devemos dizer a ele em que posição queremos colocar esse dado.
O comando Set Address permite posicionar o LCD numa coluna (0 a 63) dentro da página.
Para posicionar o LCD na coluna 36 podemos codificar o comando:
SET ADDRESS | RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 |
Estabelece o número da página (0 a 7) do LCD onde o dado será colocado.
Para posicionar o LCD na página 5 podemos codificar o comando:
SET PAGE | RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 |
Estabelece o número da linha (0 a 7) do LCD que será mostrada no topo da tela.
Para informar que a linha 6 será mostrada no topo da tela podemos codificar o comando:
Display Start Line | RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 |
O comando STATUS READ permite ler o estado em que se encontra o LCD.
Para ler o estado do LCD devemos enviar o comando com o seguinte formato, onde o valor de "x" é indiferente:
STATUS READ | RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | x | 0 | x | x | 0 | 0 | 0 | 0 |
Ao recebermos a resposta, os bits D7, D5 e D4, conterão o estado do LCD conforme mostra a tabela da figura 3.
O comando Write Display Data envia um byte ao LCD.
Para enviarmos o valor 0xFF ao LCD podemos codificar o comando:
Write Display Data | RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Notar que o valor 0xFF acenderá uma coluna de 8 bits na página e na coluna onde o LCD estiver posicionado no momento.
O comando Read Display Data fará com que o LCD devolva nos bits D7 a D0, o valor contido na posição atual (página e coluna) de sua tela.
Para lermos o conteúdo da posição atual do LCD podemos enviar o comando onde o valor de "x" é indiferente:
Write Display Data | RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|
1 | 1 | x | x | x | x | x | x | x | x |
Como resposta ao comando, os bits D7 a D0 conterão o valor da posição atual do LCD.
Vamos exemplificar o uso das funções de controle para LCD gráfico com um pequeno programa que desenhará um retângulo na coluna 40 da página 3 do LCD como mostra a foto abaixo.
Faça o download do projeto que se encontra no arquivo retangulo.zip, descomprima-o e abra-o no MPLAB para dar uma olhada.
Dentro da pasta do projeto encontra-se o arquivo "ks0108.inc" que contem todas as funções de controle do LCD definidas anteriormente e é inserido no fonte do programa pela diretiva #include "ks0108.inc".
O programa está escrito para o microcontrolador PIC18F4620 mas pode ser modificado facilmente para outro modelo da mesma família.
Monte o circuito de acordo com as definições de hardware do programa, isto é, use o PORTB para conectar as portas de dados do LCD (D0 a D7) e use o PORTC para conectar os pinos de controle do LCD (DI, RW, EN, CS1, CS2 e RST), conforme definido no fonte do programa abaixo. A seguir, usando seu programador PIC preferido, grave o programa "retangulo.hex" no microcontrolador, recoloque-o no circuito e ligue a energia. Um pequeno retângulo deverá aparecer na coluna 40 da página 3 do LCD. Se isso não acontecer, revise as conexões e tente novamente. Este programa foi compilado no MPLAB e testado no protoboard onde funcionou perfeitamente.
list p=18f4620 ; modifique isto para usar outro microcontrolador #include <p18f4620.inc> ; modifique isto para usar outro microcontrolador errorlevel -302 CONFIG WDT = OFF ; configuration bits CONFIG MCLRE = ON ; configuration bits CONFIG DEBUG = OFF ; configuration bits CONFIG LVP = OFF ; configuration bits CONFIG OSC = HS ; configuration bits UDATA 0x80 ; ; DEFINICAO DA PORTA DE DADOS ; #define GLCD_DATATRIS TRISB ; controle de I/O da porta de dados/comandos #define GLCD_DATAIN PORTB ; porta de dados/comandos #define GLCD_DATAOUT LATB ; alias da porta de dados/comandos ; ; DEFINICAO DA PORTA DE CONTROLE ; #define GLCD_CNT PORTC ; porta de controle para o LCD #define GLCD_CNTRIS TRISC ; controle de I/O da porta de controle #define GLCD_CNTDI 0 ; ao pino DI do LCD........ dado/ou instrucao #define GLCD_CNTRW 1 ; ao pino RW do LCD........ read/write #define GLCD_CNTE 2 ; ao pino EN do LCD........ chip enable #define GLCD_CNTCS1 3 ; ao pino CS1 do LCD........ lado 1 #define GLCD_CNTCS2 4 ; ao pino CS2 do LCD........ lado 2 #define GLCD_CNTRST 5 ; ao pino RST do LCD........ restart GLCD_W1 RES 1 ; registrador de trabalho GLCD_W2 RES 1 ; registrador de trabalho GLCD_Delay1 RES 1 ; registrador de trabalho GLCD_RC1 RES 1 ; registrador de controle GLCD_PAGE RES 1 ; numero da pagina GLCD_COL RES 1 ; numero da coluna ; ---------------------------------------------------------------------------------------------------------- rst_code CODE 0x000 goto inicio hi_prty_int CODE 0x008 retfie ; ---------------------------------------------------------------------------------------------------------- MAIN CODE #include "ks0108.inc" ; Funcoes para o LCD grafico ; ---------------------------------------------------------------------------------------------------------- inicio movlw 0x0F ; mascara para digital ports movwf ADCON1 ; configura todos os pinos como digital clrf LATD ; limpa PORTD clrf LATC ; limpa PORTC clrf TRISD ; PORTD tudo saida clrf TRISC ; PORTC tudo saida call GLCD_Init ; inicializa o LCD call GLCD_Enable1 ; habilita lado 1 call GLCD_Enable2 ; habilita lado 2 call GLCD_Clear ; apaga a tela do LCD call GLCD_Enable1 ; habilita o lado 1 movlw START_LINE ; comando para posicionar linha zero call GLCD_Command ; envia o comando ao LCD movlw .3 ; numero da pagina iorlw X_ADDRESS ; insere pagina no comando call GLCD_Command ; envia o comando movlw .40 ; numero da coluna iorlw Y_ADDRESS ; insere coluna no comando call GLCD_Command ; envia o comando call retangulo ; desenha o retangulo parada goto parada ; fica parado aqui ; ; Desenha um retangulo ; retangulo movlw 0xFF call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0x81 call GLCD_Write movlw 0xFF call GLCD_Write return END
Índice dos circuitos |
H P S P I N Desde 04 de Março de 2010 Atualização: 08 de Oct de 2024 |