HOME      PROJETOS      PROGRAMAÇÃO     

Interface de 2 fios para LCDs compatíveis com o HD44780


Este projeto cria uma interface de comunicação entre um microcontrolador PIC e um LCD alfanumérico do tipo HD44780 usando shift-registers comuns do tipo CMOS 4015 ou TTL 74LS164.

Somente dois pinos de I/O do PIC serão necessários para controlar LCDs de 1, 2 ou 4 linhas, onde um dos pinos enviará o sinal de clock e o outro os bits de dados. Isso significa que a nossa interface será do tipo serial, onde os bits de dados serão enviados um após o outro controlados pelo sinal de clock.

Aparentemente seria impossível uma interface serial se comunicar com um LCD porque eles aceitam somente dados enviados através de um bus paralelo de 4 ou 8 vias, dependendo do modo de operação selecionado e, além disso, existem os sinais de comandos que devem ser enviados numa determinada sequência para que o chip processador do LCD possa operar adequadamente.

Para conseguir enviar dados e comandos através de uma interface serial, usa-se um shift-register CMOS 4015 ou TTL 74LS164 para receber os dados e comandos de forma serial, provenientes do PIC, e enviar esses mesmo dados de forma paralela ao LCD.

Abaixo temos dois esquemas elétricos que podem ser usados para montar a interface, um com o shift-register CMOS 4015 e outro com o 74LS164. Sem dúvida, o circuito com o 74LS164 é mais simples, em termos de desenho, pois o 4015 possui dois blocos de 4 bits que precisam ser encadeados enquanto o 74LS164 tem somente um bloco de 8 bits.

Nos esquemas abaixo estão representados LCDs diferentes mas isso não importa pois, todos os LCDs desse tipo têm 16 pinos com as mesmas funções, porém, eles podem estar em posições diferentes nos diversos chips de LCD. Por isso, antes de começar a montagem, é recomendado fazer uma consulta no respectivo data sheet.



INTERFACE USANDO O SHIFT-REGISTER CMOS 4015






INTERFACE USANDO O SHIFT-REGISTER TTL 74LS164




CARACTERÍSTICAS DOS CIRCUITOS




ASPECTO DA MONTAGEM







FUNÇÕES DE CONTROLE DO LCD

Para controlar o envio de dados e comandos ao LCD foram desenvolvidas funções cujo arquivo lcd_services deve ser baixado e salvo na sua pasta de projetos.

Este serviço fornece funções de comunicação com LCDs seriais tipo HD44780 Hitachi e similares.

Este serviço suporta as famílias de microcontroladores 16F e 18F.

Para usar este serviço, o arquivo lcd_services.inc deve ser incluido no programa bem como os seguintes símbolos e registradores:

UDATA 0x080 SR_1 RES 1 ; registrador auxiliar 1 SR_2 RES 1 ; registrador auxiliar 2 SR_3 RES 1 ; registrador auxiliar 3 SR_4 RES 1 ; registrador auxiliar 4 SR_5 RES 1 ; registrador auxiliar 5 LCD_COMMAND RES 1 ; buffer de comando e dados SR_TIPO RES 1 ; tipo de LCD SR_CLK equ 7 ; em TRISx este bit deve ser saida SR_DAT equ 6 ; em TRISx este bit deve ser saida SR_CHARS equ 0 ; 0 - caracteres 5x7 1 - caracteres 5x10 #define SR_TRIS TRISA ; I/O #define SR_DATA LATA,SR_DAT ; DATA #define SR_CLOCK LATA,SR_CLK ; CLOCK


Dependências Externas

O serviço de LCD pode ser usado em microcontroladores das famílias 16F e 18F e, sendo assim, é necessário identificar, durante a compilação, qual microcontrolador está sendo usado a fim de que o código adequado seja gerado pois existem instruções de máquina diferentes entre os microcontroladores dessas duas famílias. Para que o código do microcontrolador correto seja gerado, devemos incluir o arquivo familias.inc no programa.

O serviço de LCD usa os serviços de Delay para temporizar o LCD, portanto, o arquivo delay_services.inc deve ser incluido no programa bem como os seguintes símbolos e registradores:

; Registradores para serviços de Delay delay_temp RES 1 CLOCK RES (frequência de clock em Hertz)


Visão Geral do Serviço

A placa de LCD controlada por shift-register requer somente dois pinos de I/O do microcontrolador e esses pinos devem pertencer a mesma porta. Um desses pinos fornecerá o sinal de clock (SR_CLOCK) e o outro transmitirá os dados de forma serial (SR_DATA). A cada transição do sinal de clock, do nível baixo para o nível alto, um bit de dado será enviado ao shift-register que, após receber os 8 bits de dados, os enviará automaticamente ao LCD.

O símbolo SR_TRIS representa o registrador de controle da porta de I/O do microcontrolador.

A porta estará referenciada nos símbolos SR_DATA e SR_CLOCK que, por sua vez, vão operar usando os pinos SR_CLK e SR_DAT. Ambos os pinos serão definidos como saída.

O pino referenciado por SR_CLK é o sinal de clock e o pino referenciado por SR_DAT é o pino de dados.

O símbolo SR_CHARS bem como os registradores SR_1, SR_2, SR_3, SR_4, SR_5 e SR_TIPO são de uso exclusivo das funções internas do serviço de LCD e não deve ser alterado pelo programador.

O registrador LCD_COMMAND é o buffer de dados e comandos. Esse registrador pode ser usado pelo programador para enviar um comando ou caracter ao LCD através das funções "SR_SENDCMD" ou "SR_SENDCHR" respectivamente.


Menu de FunçõesTopo da Página

Operação do Serviço

Para usar o serviço, primeiramente devemos incluir no programa os arquivos lcd_services.inc e delay_services.inc.

A seguir, definimos os registradores de trabalho para esses dois serviços, conforme visto acima, não esquecendo de alterar os símbolos necessários para refletir as necessidades do projeto.

Uma vez incluidos os arquivos necessários, definimos as dimensões do LCD usando a macro LCD_LINES.

Agora estamos prontos para operar o LCD mas, antes, o LCD deve ser inicializado com uma chamada à rotina "SR_4BITS" (call SR_4BITS) que vai configurá-lo no modo de 4 bits. Veja o programa exemplo no fim desta página para saber mais.

A partir daqui podemos enviar comandos e caracteres ao LCD usando as funções adequadas, conforme descrito abaixo.


Menu de FunçõesTopo da Página

Enviando Caracteres ao LCD

Caracteres são letras, números e outros símbolos imprimíveis da tabela ASCII que serão apenas mostrados no display do LCD.

Para enviar um caracter ao LCD, pode-se carregar o registrador W com o caracter desejado e usar a função SR_SENDW para enviá-lo ao LCD. Pode-se, também, inserir o caracter no registrador LCD_COMMAND e usar a função "SR_SENDCHR" como no exemplo abaixo. Após o envio do caracter, recomenda-se esperar alguns milisegundos para dar tempo do LCD completar a tarefa.

call SR_4BITS ; inicializa LCD call SR_LCDCLEAR ; limpa o LCD movlw "x" ; carrega "x" em W movwf LCD_COMMAND ; armazema o caracter call SR_SENDCHR ; envia o caracter ao LCD movlw .15 ; 10ms call delay_ms ; espera completar . . .


Menu de FunçõesTopo da Página

Enviando Comandos ao LCD

Comandos são valores especiais que fazem o LCD executar uma tarefa interna como, por exemplo, posicionar o cursor numa linha e coluna.

Para enviar um comando ao LCD carrega-se o registrador LCD_COMMAND com o comando desejado e usa-se a função SR_SENDCMD para enviá-lo ao LCD. Após o envio do comando, recomenda-se esperar alguns milisegundos para dar tempo do comando completar. Veja o exemplo abaixo:

call SR_4BITS ; inicializa LCD call SR_LCDCLEAR ; limpa o LCD movlw 01 ; carrega comando em W movwf LCD_COMMAND ; armazema o caracter call SR_SENDCMD ; envia o caracter ao LCD movlw .15 ; 10ms call delay_ms ; espera completar . . .


Menu de FunçõesTopo da Página

Enviando Strings ao LCD

Para enviar strings ao LCD usa-se a macro LCD_WRITE que permite enviar uma cadeia de caracteres definidos inline nessa macro. Exemplo:

. . . call SR_4BITS ; inicializa LCD call SR_LCDCLEAR ; limpa o LCD LCD_WRITE "Teste de LCD" ; envia string . . .


Menu de FunçõesTopo da Página

FUNÇÕES (Subrotinas chamadas com CALL)

As seguintes funções são fornecidas pelo serviço:

SR_4BITS Inicializa o LCD
SR_LCDRESET Limpa e reposiciona o LCD
SR_LCDCLEAR Limpa o LCD
SR_SENDW Envia o valor de W ao LCD
SR_SENDCHR Envia ao LCD o caracter do registrador LCD_COMMAND
SR_SENDCMD Envia ao LCD o comando do registrador LCD_COMMAND
SR_CURSORHOME Posiciona o cursor do LCD na linha 1 coluna 1
SR_SETCURSOR Posiciona o cursor na linha e coluna especificada
SR_LINESET Posiciona o cursor no início de uma linha


FUNÇÕES (Macros)

As seguintes macro instruções são fornecidas pelo serviço:

LCD_LINES Especifica número de linhas e colunas do LCD
LCD_WRITE Envia uma string ao LCD
SET_CURSOR Posiciona o cursor na linha e coluna especificada
SR4_MVC Posiciona o cursor na linha e coluna especificada

Menu de FunçõesTopo da Página

SR_4BITS

A função SR_4BITS inicializa o LCD no modo 4 bits. Essa função deve ser chamada no início do programa antes que se possa enviar dados ao LCD.

Exemplo:

inicio movlw 7 movwf CMCON . . call SR_4BITS ; inicializa LCD . .


Menu de FunçõesTopo da Página

SR_LCDRESET

A função SR_LCDRESET limpa o LCD e posiciona o cursor na linha 1 e coluna 1.

Exemplo:

inicio movlw 7 movwf CMCON . . call SR_4BITS ; inicializa LCD call SR_LCDRESET ; reposiciona o LCD .


Menu de FunçõesTopo da Página

SR_LCDCLEAR

A função SR_LCDRESET limpa o LCD e posiciona o cursor na linha 1 e coluna 1.

Exemplo:

inicio movlw 7 movwf CMCON . . call SR_4BITS ; inicializa LCD call SR_LCDCLEAR ; garante que o LCD esta limpo . .


Menu de FunçõesTopo da Página

SR_SENDW

A função SR_SENDW envia o caracter contido no registrador W para ser exibido na posição atual da tela do LCD.

Exemplo:

inicio movlw 7 movwf CMCON . . call SR_4BITS ; inicializa LCD call SR_LCDCLEAR ; garante que o LCD esta limpo movlw "A" ; W = "A" call SR_SENDW ; envia "A" ao LCD .


Menu de FunçõesTopo da Página

SR_SENDCHR

A função SR_SENDCHR coloca o LCD em modo de recepção de dados e envia o caracter contido no registrador LCD_COMMAND para ser exibido na posição atual da tela.

Exemplo:

inicio movlw 7 movwf CMCON . . call SR_4BITS ; inicializa LCD call SR_LCDCLEAR ; garante que o LCD esta limpo movlw "A" ; caracter "A" movwf LCD_COMMAND ; move "A" para o buffer call SR_SENDCHR ; envia "A" ao LCD .


Menu de FunçõesTopo da Página

SR_SENDCMD

A função SR_SENDCMD coloca o LCD em "modo de comando" e envia o comando contido no registrador LCD_COMMAND para o LCD executar. Os comandos aceitos fazem parte do firmware do LCD e devem ser consultados nos data sheets dos respectivos dispositivos.

Exemplo:

inicio movlw 7 movwf CMCON . . call SR_4BITS ; inicializa LCD call SR_LCDCLEAR ; garante que o LCD esta limpo movlw b'00101111' ; configura interface de 4 bits andwf LCD_COMMAND,f ; move o commmando para o buffer call SR_SENDCMD ; envia o comando .


Menu de FunçõesTopo da Página

SR_CURSORHOME

A função SR_CURSORHOME posiciona o cursor na primeira linha e primeira coluna do LCD mas não apaga o seu conteúdo.

Exemplo:

. inicio movlw 7 movwf CMCON . . call SR_4BITS ; inicializa LCD call SR_CURSORHOME ; posiciona na linha 1, coluna 1 .


Menu de FunçõesTopo da Página

SR_SETCURSOR

A função SR_SETCURSOR Posiciona o cursor numa determinada linha e coluna do LCD.

O registrador SR_1 deve conter o número da linha e o registrador SR_2 o número da coluna que devem ser compatíveis com o LCD, cujos endereços serão fornecidos pela macro LCD_LINES que deve ser emitida uma única vez para gerar a respectiva tabela de endereços de linhas e colunas.

A função SR_SETCURSOR pode ser chamada pela macro SET_CURSOR que facilita a programação permitindo que os valores de linha e coluna sejam escritos diretamente na macro.

Exemplo:

. LCD_LINES 0216 ; macro p/ gerar enderecos linha/coluna p/ LCD 2x16 . . inicio movlw 7 movwf CMCON . . call SR_4BITS ; inicializa LCD call SR_LCDRESET ; reposiciona o LCD movlw .1 ; liha 1 movwf SR_1 ; carrega registrador de linha movlw .5 ; coluna 5 movwf SR_2 ; carrega registrador de coluna call SR_SETCURSOR ; posiciona o cursor . .


Menu de FunçõesTopo da Página

SR_LINESET

A função SR_LINESET posiciona o cursor do LCD no início de uma linha, isto é, na primeira coluna da linha especificada no registrador W.

Esta rotina exige que a macro LCD_LINES seja emitida no início do programa para gerar a tabela de enderecos das linhas para o LCD.

Exemplo:

. LCD_LINES 0216 ; macro p/ gerar enderecos ; linha/coluna p/ LCD 2x16 . . inicio movlw 7 movwf CMCON . . call SR_4BITS ; inicializa LCD call SR_LCDRESET ; reposiciona o LCD movlw .2 ; linha 2 call SR_LINESET ; posiciona no inicio da linha 2 . . .


Menu de FunçõesTopo da Página

LCD_WRITE   "string"

A função LCD_WRITE envia a string "string" ao LCD.

Exemplo:

. . . LCD_LINES 0216 . . inicio movlw 7 movwf CMCON . . call SR_4BITS ; inicializa LCD call SR_LCDRESET ; reposiciona o LCD SET_CURSOR .1,.1,"i" ; posiciona LCD_WRITE "Ola!!!" ; envia a mensagem . . .

A macro LCD_WRITE gera strings na memória RAM do microprocessador toda vez que a usamos para enviar uma mensagem ao LCD. As vezes desejamos enviar ao LCD uma mensagem que vai se repetir muitas vezes durante o programa e, para economizar memória, podemos definir uma mensagem fixa e chamá-la como uma subrotina como mostrado no exemplo abaixo:

SET_CURSOR   <linha>, <coluna>, "opt"

A função SET_CURSOR posiciona o cursor na <linha> e <coluna> especificadas.

Quando os valores dos parâmetros <linha> e <coluna> estão inline na macro, o parâmetro "opt" deve ser codificado como "i".
Quando os valores dos parâmetros <linha> e <coluna> residem em registradores, o parâmetro "opt" deve ser codificado como "r".

Exemplo:

. . . LCD_LINES 0216 . . inicio movlw 7 movwf CMCON . . call SR_4BITS ; inicializa LCD call SR_LCDRESET ; reposiciona o LCD . . ; posicionando com linha e coluna direto na macro SET_CURSOR .1,.1 "i" ; posiciona na linha 1 coluna 1 LCD_WRITE "Teste da Macro" ; envia a mensagem SET_CURSOR .2,.1 "i" ; posiciona na linha 2 coluna 1 LCD_WRITE "SET_CURSOR" ; envia a mensagem . . ; posicionando com linha e coluna em registradores call SR_LCDCLEAR ; limpa o LCD movlw .1 ; linha 1 movwf R1 ; salva numero da linha movlw .5 ; coluna 5 movwf R2 ; salva numero da coluna SET_CURSOR R1, R2, "r" ; posiciona linha 1, coluna 5 LCD_WRITE "Ola!!!" . . .


Menu de FunçõesTopo da Página

LCD_LINES   <lincol>

A macro LCD_LINES especifica o número de linhas e colunas do LCD a serem usadas pelo serviço onde o parâmetro <lincol> deve ser conforme a tabela abaixo:

  Dimensões do LCD     Parâmetro <lincol>  
  Linhas     Colunas  
  2   16 0216
  2     20     0220  
  4     16     0416  
  4     20     0420  

A macro LCD_LINES é de uso obrigatório e deve ser emitida logo após a inclusão do arquivo lcd_services.inc para que o serviço possa identificar as dimensões do LCD com o qual esta operando.

Exemplo:

. . . MAIN CODE #include "lcd_services.inc" . . LCD_LINES 0420 . . inicio movlw 7 movwf CMCON . . call SR_4BITS ; inicializa LCD call SR_LCDRESET ; reposiciona o LCD . . .


Menu de FunçõesTopo da Página

SR_4MVC   <string>

A macro SR_4MVC move para o LCD a string definida na localização <string> da memória.

Esta macro pode ser usada nas famílias 16F e 18F porém, na família 18F é preferível usa a macro LCD_WRITE.

Notar que na família 18F a mensagem reside na memória de programa enquanto na família 16F reside numa Table Read.

Em ambos os casos, o fim da string deve ser marcado com um byte nulo (0x00).

Exemplo para a família 18F:

. . . msg001 SR_4MVC ms001 ms001 DB "mensagem",0 . . call msg001 . .



Exemplo para a família 18F:

. . . msg001 SR_4MVC ms001 ms001 ADDWF PCL,f DT "mensagem",0 . . call msg001 . .


Menu de FunçõesTopo da Página

PROGRAMA EXEMPLO

Para demostrar tudo que foi dito até agora, o programa exemplo lcd.asm, cuja listagem é mostrada abaixo, pode ser baixado e executado em um microcontrolador PIC18F4620.

; ------------------------------------------------------ ; PROGRAMA EXEMPLO ; ; Este programa funciona em qualquer microcontrolador ; da familia 18F. ; ; Para usar outro microprocessador,modifique o codigo ; nas duas diretivas abaixo. ; ; ------------------------------------------------------ LIST P=18F4620 #include <P18F4620.INC> #include "familias.inc" ; ; ------------------------------------------------------ ; CONFIGURATION BITS ; ------------------------------------------------------ CONFIG WDT = OFF CONFIG MCLRE = ON CONFIG debug = OFF CONFIG LVP = OFF CONFIG OSC = HS CONFIG CP0 = OFF CONFIG CP1 = OFF CONFIG CP2 = OFF CONFIG CP3 = OFF CONFIG CPB = OFF CONFIG CPD = OFF CONFIG WRT0 = OFF CONFIG WRT1 = OFF CONFIG WRT2 = OFF CONFIG WRT3 = OFF CONFIG WRTC = OFF CONFIG WRTB = OFF CONFIG WRTD = OFF ; ------------------------------------------------------ ; REGISTRADORES E SIMBOLOS NA MEMORIA DE DADOS ; ------------------------------------------------------ UDATA 0x80 delay_temp res 1 ; para serviço de delay CLOCK equ 20000000 ; Fosc=20MHZ ; SR_1 RES 1 ; registrador auxiliar 1 SR_2 RES 1 ; registrador auxiliar 2 SR_3 RES 1 ; registrador auxiliar 3 SR_4 RES 1 ; registrador auxiliar 4 SR_5 RES 1 ; registrador auxiliar 5 LCD_COMMAND RES 1 ; buffer de comando e dados SR_TIPO RES 1 ; tipo de LCD SR_CLK equ 2 ; em TRISx este bit deve ser saida SR_DAT equ 1 ; em TRISx este bit deve ser saida SR_CHARS equ 0 ; 0 - caracteres 5x7 1 - caracteres 5x10 #define SR_TRIS TRISD #define SR_DATA LATD,SR_DAT ; DATA #define SR_CLOCK LATD,SR_CLK ; CLOCK ; ; ------------------------------------------------------ ; Vetores de interrupções ; ------------------------------------------------------ rstvec CODE 0x0000 goto inicio inth CODE 0x0008 retfie ; ------------------------------------------------------ ; Inicio da area de codigo ; ------------------------------------------------------ MAIN CODE #include "delay_services.inc" #include "lcd_services.inc" LCD_LINES 0216 ; dimensoes do LCD ; ------------------------------------------------------ ; Entrada principal ; ------------------------------------------------------ inicio movlw 0x0F ; movwf ADCON1 ; todas as portas digitais clrf PORTD ; PORTD = 0x00 clrf TRISD ; PORTD -> Saida call SR_4BITS ; configura o LCD loop call SR_LCDCLEAR ; limpa o LCD call tempo ; aguarda 1 segundo SET_CURSOR .1,.1,"i" ; posiciona linha 1, coluna 1 call msg001 ; envia mensagem ao LCD call tempo ; tempo para visualizacao SET_CURSOR .2,.1,"i" ; posiciona linha 2, coluna 1 call msg002 ; envia mensagem ao LCD call tempo ; tempo para visualizacao goto loop ; ------------------------------------------------------ ; Mensagens fixas ; ------------------------------------------------------ msg001 LCD_WRITE "PROGRAMA EXEMPLO" return ; msg002 LCD_WRITE "LCD@18F4620.LAB" return ; ------------------------------------------------------ ; Retardo de 1 segundo ; ------------------------------------------------------ tempo movlw .250 call delay_ms movlw .250 call delay_ms movlw .250 call delay_ms movlw .250 call delay_ms return END


Menu de FunçõesTopo da Página



Índice dos circuitos




H P S P I N

Desde 04 de Março de 2010

Atualização: 08 de Oct de 2024