HOME      PROJETOS      PROGRAMAÇÃO     

LCD GRÁFICO PADRÃO KS0108 64x128


Vamos aprender como conectar ao PIC um LCD gráfico padrão KS0108 de 64 linhas por 128 colunas.



INTRODUÇÃO

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.

+---------> coluna 0  |+--------> coluna 1  ||+-------> coluna 2  |||+------> coluna 3  ||||+-----> coluna 4  |||||+----> coluna 5  ||||||+---> coluna 6  |||||||+--> coluna 7  ||||||||             0 #######.             1 #.....#.             2 #.....#.             3 #######.             4 #.....#.             5 #.....#.             6 #.....#.             7 ........                  





CONEXÕES

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.





COMANDOS DO LCD

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.




Sequência de Operações para Comunicação com o LCD

Para enviar um comando ao LCD, devemos seguir a seguinte sequência de operações:

  1. Fazer RS=0 para informar que é um comando.
  2. Fazer RW=0 para informar que desejamos gravar no LCD.
  3. Colocar o comando desejado (vide figura 3) na porta de dados (D0 a D7).
  4. Fazer EN=1 para o LCD capturar o comando que pusemos na porta.
  5. Manter o bit EN levantado durante pelo menos 15us (microssegundos).
  6. Fazer EN=0 para encerrar a operação.
  7. Aguardar o LCD completar a tarefa.

Para enviar um dado ao LCD, devemos seguir a seguinte sequência de operações:

  1. Fazer RS=1 para informar que é um dado.
  2. Fazer RW=0 para informar que desejamos gravar no LCD.
  3. Colocar o dado na porta de dados (D0 a D7).
  4. Fazer EN=1 para o LCD capturar o dado que pusemos na porta.
  5. Manter o bit EN levantado durante pelo menos 15us (microssegundos).
  6. Fazer EN=0 para encerrar a operação.
  7. Aguardar o LCD completar a tarefa.

Para ler um dado do LCD, devemos seguir a seguinte sequência de operações:

  1. Fazer RS=1 para informar que é um dado.
  2. Fazer RW=1 para informar que desejamos ler o LCD.
  3. Fazer EN=1 para o LCD colocar o dado na porta de dados.
  4. Manter o bit EN levantado durante pelo menos 15us (microssegundos).
  5. capturamos o dado que o LCD colocou em sua porta (D0 a D7).
  6. Fazer EN=0 para encerrar a operação.
  7. Aguardar o LCD completar a tarefa.



Uma Breve Descrição dos Comandos



Comando ON/OFF

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 





Comando Set Address

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 





Comando Set Page

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 





Comando Display Start Line

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 





Comando Status Read

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.






Comando Write Display Data

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.






Comando Read Display Data

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.






Desenvolvendo Algumas Funções de Controle para LCDs KS0108

A fim de facilitar a programação com LCDs gráficos, vamos desenvolver algumas funções que possam ser chamadas de dentro de um programa assembler, assumindo que o LCD gráfico esteja conectado ao microcontrolador no modo paralelo, isto é, que cada pino do LCD esteja conectado a um pino do microcontrolador.

As funções aqui apresentadas devem ser usadas somente com microcontroladores da família 18F porque usam instruções assembler específicas para essa família e, tendo em mente que é necessário temporizar o sinal EN (GLCD_CNTE), uma rotina de retardo, chamada GLCD_Delay foi construida levando-se em consideração um ciclo de instrução de 200ns (nanossegundos), o que significa que, para usar essas funções, o clock do projeto deve ser fornecido por um cristal de 20MHZ.

Por uma questão de economia no desenvolvimento do código, vamos usar o PORTB como porta de dados pois o PORTB possui resistores pull-up internos que podem ser habilitados e desbilitados por software conforme a necessidade. Quando o PORTB for usado como saída não necessitamos usar resistores pull-up porém, quando usado como entrada, é importante que haja polarização correta dos pinos para não haver leitura incorreta. Definimos o PORTB como porta de dados e criamos símbolos específicos para nos referirmos a essa porta.

#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



Definimos o PORTC como porta de controle, isto é, no PORTC serão conectados os pinos RS, RW, EN, CS1, CS2 e RST do LCD gráfico. Aqui, cada pino (bits de 0 a 5) será nomeado apropriadamente para não haver confusão na hora de usá-los durante a programação.

#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



Os seguintes registradores serão usados pelas funções de controle do LCD gráfico e não devem ser utilizados pelo programador para quaisquer outros fins:

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



Definimos símbolos que facilitam recordar os nomes dos comandos do LCD durante a programação.

#define X_ADDRESS 0xB8 ; Comando Set X Address #define Y_ADDRESS 0x40 ; Comando Set Y Address #define START_LINE 0xC0 ; Comando Start Line #define DISPLAY_ON 0x3F ; Comando Display on #define DISPLAY_OFF 0x3E ; Comando Display off #define BUSY 0x80 ; mascara para o bit de status do LCD



FUNÇÕES DE CONTROLE PARA LCD GRÁFICO KS0108




GLCD_Init

Em primeiro lugar, vamos codificar uma função para inicializar o LCD. Essa função deve enviar uma sequência de comandos ao LCD para poder ativá-lo. Essa função não recebe parâmetros e deve ser a primeira função a ser chamada antes do LCD poder ser usado. Para saber detalhes, leia os comentários ao lado de cada instrução.

; ------------------------------------------------------------------------------ ; Inicializa o LCD ; ; ENTRADA: Nao ha ; ------------------------------------------------------------------------------ GLCD_Init movlw 0x00 ; W=0 movwf GLCD_DATATRIS ; porta de dados ---> saida movwf GLCD_CNTRIS ; porta de controle ---> saida movwf GLCD_DATAOUT ; limpa porta de dados clrf GLCD_RC1 ; limpa registrador de controle movf GLCD_RC1,w ; carrega registrador de controle movwf GLCD_CNT ; envia controles para porta nop ; delay esperando estabilizar nop ; delay esperando estabilizar nop ; delay esperando estabilizar bcf GLCD_RC1,GLCD_CNTRST ; RST=0 movf GLCD_RC1,w ; carrega registrador de controle movwf GLCD_CNT ; envia controles para porta movlw .5 ; 5ms call delay_ms ; wait bsf GLCD_RC1,GLCD_CNTRST ; RST=1 movf GLCD_RC1,w ; carrega registrador de controle movwf GLCD_CNT ; envia controles para porta movlw .5 ; 5ms call delay_ms ; wait bsf GLCD_RC1,GLCD_CNTCS1 ; habilita lado 1 bsf GLCD_RC1,GLCD_CNTCS2 ; habilita lado 2 movf GLCD_RC1,w ; carrega registrador de controle movwf GLCD_CNT ; envia controles para porta nop ; delay esperando estabilizar nop ; delay esperando estabilizar nop ; delay esperando estabilizar movlw DISPLAY_ON ; DISPLAY_ON call GLCD_Command ; envia comando ao LCD movlw START_LINE ; START_LINE call GLCD_Command ; envia comando ao LCD movlw X_ADDRESS ; X_ADDRESS - posiciona na pagina 0 call GLCD_Command ; envia comando ao LCD movlw Y_ADDRESS ; Y_ADDRESS - posiciona na coluna 0 call GLCD_Command ; envia comando ao LCD bcf GLCD_RC1,GLCD_CNTCS1 ; desabilita lado 1 bcf GLCD_RC1,GLCD_CNTCS2 ; desabilita lado 2 movf GLCD_RC1,w ; carrega registrador de controle movwf GLCD_CNT ; envia controles para porta return ; fim




GLCD_Command

A função GLCD_init, definida anteriomente, faz uma chamada a função GLCD_Command cujo objetivo é enviar um comando para o LCD executar. Vamos agora definir a função GLCD_Command. Essa função usa como parâmetro o valor contido no registrador W que na verdade é o comando que desejamos enviar ao LCD.

; ------------------------------------------------------------------------------ ; Envia um comando ao LCD ; ; ENTRADA: W contem o codigo do comando ; ------------------------------------------------------------------------------ GLCD_Command movwf GLCD_W1 ; salva o comando call GLCD_Wait ; aguarda o LCD ficar pronto bsf GLCD_RC1,GLCD_CNTRST ; assegura que RST=1 bcf GLCD_RC1,GLCD_CNTDI ; indica comando bcf GLCD_RC1,GLCD_CNTRW ; indica gravacao bsf GLCD_RC1,GLCD_CNTE ; strobe up clrf GLCD_CNTRIS ; porta de controle como saida movf GLCD_RC1,w ; carrega registrador de controle movwf GLCD_CNT ; output na porta de controle movlw 10 ; tempo call GLCD_Delay ; duty cycle movf GLCD_W1,w ; restaura o comando movwf GLCD_DATAOUT ; envia o comando nop ; delay esperando estabilizar nop ; delay esperando estabilizar nop ; delay esperando estabilizar bcf GLCD_RC1,GLCD_CNTE ; strobe down movf GLCD_RC1,w ; carrega registrador de controle movwf GLCD_CNT ; output na porta de controle return ; fim




GLCD_Wait

Ao pedir um serviço ao LCD, pode ser que ele esteja ocupado executando alguma tarefa requisitada anteriormente mas que ainda não foi concluida. Uma das maneiras de esperar que o LCD fique pronto é fazer um delay de tempo fixo, digamos 2ms porém, esse delay pode gastar muito tempo e fazer com que a resposta do LCD fique lenta. Outra maneira de saber se o LCD está pronto para operar é testar o bit BUSY fornecido pelo comando STATUS READ (ver figura 3).

A função GLCD_Wait espera o LCD ficar pronto para receber dados e comandos testando o bit BUSY fornecido pelo comando STATUS READ. Essa é uma função interna e não deve ser usada pelo programador.

; ---------------------------------------------------------------------------------------------------------- ; Aguarda o LCD ficar pronto para operar ; ; ENTRADA: nao ha ; ; ---------------------------------------------------------------------------------------------------------- GLCD_Wait movlw 0xFF ; mascara de I/O movwf GLCD_DATATRIS ; porta de dados como entrada bcf INTCON2,RBPU ; habilita resistores pullup bcf GLCD_RC1,GLCD_CNTDI ; aviso o LCD que vou enviar um comando bsf GLCD_RC1,GLCD_CNTRW ; aviso que o LCD deve me devolver um dado movf GLCD_RC1,w ; carrego o buffer de controle em W movwf GLCD_CNT ; coloco o controle na porta de controle nop ; espera estabilizar nop ; espera estabilizar nop ; espera estabilizar GLCD_Wait1 bsf GLCD_RC1,GLCD_CNTE ; levanto o sinal de envio no buffer de controle movf GLCD_RC1,w ; carrego o buffer de controle em W movwf GLCD_CNT ; coloco o controle na porta de controle movlw 10 ; 10us call GLCD_Delay ; espera 10us (microssegundos) bcf GLCD_RC1,GLCD_CNTE ; abaixo o sinal de envio no buffer de controle movf GLCD_RC1,w ; carrego o buffer de controle em W movwf GLCD_CNT ; coloco o controle na porta de controle nop ; espera estabilizar nop ; espera estabilizar movf GLCD_DATAIN,w ; leio do dado que veio naporta de dados andlw BUSY ; teste do bit BUSY xorlw BUSY ; teste do bit BUSY btfss STATUS,Z ; LCD estava ocupado??? goto GLCD_Wait1 ; SIM --> espera desocupar bsf INTCON2,RBPU ; NAO --> desabilita resistores pullup movlw 0x00 ; mascara de I/O movwf GLCD_DATATRIS ; porta de dados como saida movwf GLCD_DATAOUT ; limpa a porta de dados return ; fim




GLCD_Delay

A função GLCD_Delay permite provocar um delay da ordem de microssegundos. O registrador W deve ser carregado com o número de microssegundos antes da chamada. Esta é uma função interna e não deve ser usada pelo programador.

; ---------------------------------------------------------------------------------------------------------- ; Delay em microssegundos ; ENTRADA: W = tempo em microssegundos ; ---------------------------------------------------------------------------------------------------------- GLCD_Delay movwf GLCD_Delay1 ; numero de microssegundos _delayloop nop ; 200ns nop ; 200ns decfsz GLCD_Delay1, f ; 200ns goto _delayloop ; 400ns ; 1000ns = 1us --> total return ; fim




GLCD_Clear

A função GLCD_Clear limpa o lado do LCD que está habilitado. Não há parâmetro de entrada para esta função. Após a limpeza, ambos os lados estarão desabilitados.

; ---------------------------------------------------------------------------------------------------------- ; Limpa o(s) lado(s) habilitado(s) do LCD ; ; ENTRADA: nao ha ; ; SAIDA : 1 - LCD LIMPO ; 2 - LCD Posicionado em 0,0 ; 3 - Ambos os lados desabilitados ; ---------------------------------------------------------------------------------------------------------- GLCD_Clear movlw 0x00 ; caracter de preenchimento call GLCD_Fill ; vai preencher o LCD movlw Y_ADDRESS ; posiciona coluna 0 call GLCD_Command ; envia movlw X_ADDRESS ; posiciona pagina 0 call GLCD_Command ; envia movlw START_LINE ; posiciona linha 0 call GLCD_Command ; envia return ; fim




GLCD_Swap

A função GLCD_Swap alterna os lados do LCD, isto é, inverte a seleção dos lados do LCD. Não há parâmetros de entrada para esta função.

; ---------------------------------------------------------------------------------------------------------- ; Inverte os lados do LCD: ; Se o lado 1 estiver habilitado e o lado 2 desabilitado, entao o lado 1 sera desabilitado ; e o lado 2 sera habilitado ou vice-versa. ; ; ENTRADA: Um dos lados deve estar selecionado e o outro desabilitado antes de chamar esta funcao. ; ; SAIDA : habilitacao dos lados invertidas ; ; ---------------------------------------------------------------------------------------------------------- GLCD_Swap btg GLCD_RC1,GLCD_CNTCS1 ; inverte o lado 1 btg GLCD_RC1,GLCD_CNTCS2 ; inverte o lado 2 movf GLCD_RC1,w ; carrega o buffer de controle movwf GLCD_CNT ; envia o controle return ; fim




GLCD_Read

É comum pensar ..."por que ler o conteúdo do LCD???", até que se perceba a importância da função de leitura.

A modificação da configuração dos bytes que já se encontram na tela permite, por exemplo, fazer animações no LCD sem que seja necessário mapear a tela na memória RAM do microcontrolador, economizando essa memória para ser utilizada em outras finalidades.

A função GLCD_Read le um byte da posição atual (X_ADDRESS, Y_ADDRESS) na porta de dados do LCD (pinos D0 a D7) e devolve o byte lido no registrador W. A condição para ler o LCD é que pelo menos um dos lados deve estar ativo.

; ---------------------------------------------------------------------------------------------------------- ; Le um byte na posicao atual do LCD. ; ; ENTRADA: 1 - Um dos lados deve estar habilitado ; 2 - X_ADDRESS deve estar posicionado ; 3 - Y_ADDRESS deve estar posicionado ; ; SAIDA : W contem o byte lido ; ; ---------------------------------------------------------------------------------------------------------- GLCD_Read call GLCD_Wait ; espera liberar o LCD movlw 0xFF ; mascara de entrada movwf GLCD_DATATRIS ; porta de dados para entrada bcf INTCON2,RBPU ; habilita resistores pullup bsf GLCD_RC1,GLCD_CNTDI ; DI --> data movf GLCD_RC1,w ; carrega registrador de controle movwf GLCD_CNT ; envia para a porta de controle bsf GLCD_RC1,GLCD_CNTRW ; RW --> read movf GLCD_RC1,w ; carrega registrador de controle movwf GLCD_CNT ; envia para a porta de controle bsf GLCD_RC1,GLCD_CNTE ; E = 1 movf GLCD_RC1,w ; carrega registrador de controle movwf GLCD_CNT ; envia para a porta de controle nop ; espera estabilizar nop ; espera estabilizar nop ; espera estabilizar nop ; espera estabilizar nop ; espera estabilizar movf GLCD_DATAIN,w ; le a porta de dados movwf GLCD_W1 ; salva byte lido bcf GLCD_RC1,GLCD_CNTE ; E = 0 movf GLCD_RC1,w ; carrega registrador de controle movwf GLCD_CNT ; envia para a porta de controle call GLCD_Wait ; aguarda liberar o LCD bsf INTCON2,RBPU ; desabilita resistores pullup clrf GLCD_DATATRIS ; porta de dados para saida bcf GLCD_RC1,GLCD_CNTRW ; RW --> write movf GLCD_RC1,w ; carrega registrador de controle movwf GLCD_CNT ; envia para a porta de controle movf GLCD_W1,w ; W = dado lido return ; fim




GLCD_Write

Esta é a função mais esperada pois ela é responsável por fazer as coisas aparecerem na tela do LCD.

A função GLCD_Write envia o byte contido no registrador W para aposição atual (X_ADDRESS, Y_ADDRESS) do LCD.

Cada byte enviado por essa função aparecerá na tela em posição vertical conforme mostra a figura 1 (bits D0 a D7)

Lembre que para acender um ponto no LCD é necessário que o bit daquela posição tenha o valor 1 e, para apagar um ponto da tela, o bit daquela posição deve ter o valor 0 (zero).

; ---------------------------------------------------------------------------------------------------------- ; Envia um byte ao LCD ; ; ENTRADA: W contem o byte a ser enviado ; ; SAIDA : cartacter exibido no LCD ; ---------------------------------------------------------------------------------------------------------- GLCD_Write bcf INTCON2,RBPU ; conecta os resistores pull-up do PORTB movwf GLCD_W1 ; salva o valor a enviar call GLCD_Wait ; espera o LCD ficar pronto bsf GLCD_RC1,GLCD_CNTDI ; especifica modo de dados bcf GLCD_RC1,GLCD_CNTRW ; especifica gravacao movf GLCD_RC1,w ; carrega buffer de controle movwf GLCD_CNT ; envia o buffer de controle nop ; espera estabilizar nop ; espera estabilizar nop ; espera estabilizar bsf GLCD_RC1,GLCD_CNTE ; levanta o sinal de envio movf GLCD_RC1,w ; carrega bufer de controle movwf GLCD_CNT ; envia controle movlw 10 ; 16us call GLCD_Delay ; mantem o sinal levantado movf GLCD_W1,w ; recupera o valor a ser enviado movwf GLCD_DATAOUT ; coloca o valor na porta de dados movlw 10 ; 16us call GLCD_Delay ; segura o sinal levandado bcf GLCD_RC1,GLCD_CNTE ; abaixa o sinal de envio movf GLCD_RC1,w ; carrega o buffer de controle movwf GLCD_CNT ; envia buffer de controle bsf INTCON2,RBPU ; desconecta resistores pull-up de PORTB return ; fim




GLCD_Fill

A função GLCD_Fill preenche o lado habilitado do LCD com um valor de preenchimento contido no registrador W. Após o preenchimento os dois lados estarão desabilitados.

; ---------------------------------------------------------------------------------------------------------------- ; Preenche um dos lados ou os dois lados do LCD simultaneamente, dependendo de que lado ; esteja habilitado no momento. ; ; ENTRADA: 1 - W deve conter o caracter de preenchimento ; 2 - O lado desejado deve estar selecionado. ; 3 - Ambos os lados podem estar selecionados ao mensmo tempo ; ; SAIDA : 1 - LCD preenchido com o caracter especificado em W ; 2 - Os dois lados serao desabilitados ; ; OBS: Esta funcao e usada para para limpar o LCD com W=0x00. ; ; ---------------------------------------------------------------------------------------------------------------- GLCD_FILL GLCD_Fill movwf GLCD_W2 ; salva caracter de preenchimento clrf GLCD_PAGE ; GLCD_W3=0 --> numero da pagina GLCD_Clear0 movlw Y_ADDRESS ; col=0 call GLCD_Command ; SET Y ADDRESS movlw X_ADDRESS ; comando SET X ADDRESS iorwf GLCD_PAGE,w ; insere o numero da pagina call GLCD_Command ; SET X ADDRESS movlw START_LINE ; comando START LINE call GLCD_Command ; START LINE movlw .64 ; numero total de colunas movwf GLCD_COL ; carrega contador de colunas GLCD_Clear1 movf GLCD_W2,w ; recupera caracter de preenchimento call GLCD_Write ; envia o byte para linpar decfsz GLCD_COL,f ; conta colunas goto GLCD_Clear1 ; continua limpando a pagina incf GLCD_PAGE,f ; proxima paginas btfss GLCD_PAGE,3 ; verifica se estourou goto GLCD_Clear0 ; continua se nao estourou bcf GLCD_RC1,GLCD_CNTCS1 ; desabilita o lado 1 bcf GLCD_RC1,GLCD_CNTCS2 ; desabilita o lado 2 movf GLCD_RC1,w ; carrega o registrador de controle movwf GLCD_CNT ; envia os controles return ;




GLCD_Enable1

A função GLCD_Enable1 habilita o lado 1 do LCD.

; ---------------------------------------------------------------------------------------------------------------- ; Habilita Lado 1 ; ENTRADA: nao ha ; ---------------------------------------------------------------------------------------------------------------- GLCD_Enable1 bsf GLCD_RC1,GLCD_CNTCS1 ; habilita o lado 1 movf GLCD_RC1,w ; carrega o registrador de controle movwf GLCD_CNT ; envia os controles return




GLCD_Enable2

A função GLCD_Enable2 habilita o lado 2 do LCD.

; ---------------------------------------------------------------------------------------------------------------- ; Habilita Lado 2 ; ENTRADA: nao ha ; ---------------------------------------------------------------------------------------------------------------- GLCD_Enable2 bsf GLCD_RC1,GLCD_CNTCS2 ; habilita o lado 2 movf GLCD_RC1,w ; carrega o registrador de controle movwf GLCD_CNT ; envia os controles return




GLCD_Disable1

A função GLCD_Disable1 desabilita o lado 1 do LCD.

; ---------------------------------------------------------------------------------------------------------------- ; Desabilita Lado 1 ; ENTRADA: nao ha ; ---------------------------------------------------------------------------------------------------------------- GLCD_Disable1 bcf GLCD_RC1,GLCD_CNTCS1 ; desabilita o lado 1 movf GLCD_RC1,w ; carrega o registrador de controle movwf GLCD_CNT ; envia os controles return




GLCD_Disable2

A função GLCD_Disable2 desabilita o lado 2 do LCD.

; ---------------------------------------------------------------------------------------------------------------- ; Desabilita Lado 2 ; ENTRADA: nao ha ; ---------------------------------------------------------------------------------------------------------------- GLCD_Disable2 bcf GLCD_RC1,GLCD_CNTCS2 ; desabilita o lado 2 movf GLCD_RC1,w ; carrega o registrador de controle movwf GLCD_CNT ; envia os controles return




USANDO AS FUNÇÕES PARA LCD GRÁFICO

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: 28 de Mar de 2024