HOME PROJETOS PROGRAMAÇÃO |
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.
CARACTERÍSTICAS DOS CIRCUITOS
Os circuitos devem ser alimentados por uma tensão de 5V.
R1 pode variar de 1k a 20k dependendo do LCD. Para LCD HD44780 usar R1=1k. Para LCD JHD162A usar 2K2.
R2 é o resistor do backlight e pode ser ajustado a um valor adequado ao ambiente com por exemplo 460R.
R3 é o resistor do contraste pode ser um resistor ou potenciômetro de 1k.
ASPECTO DA MONTAGEM |
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 |
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) |
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo da Página |
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 |
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo da Página |
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:
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo da Página |
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ções | Topo 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 |