SAIBA COMO CONTROLAR LCD COM APENAS 3 PINOS DO MICROCONTROLADOR (SEM NENHUM CIRCUITO INTEGRADO ADICIONAL)

2

Quando se trabalha com pequenos microcontroladores como PIC12F629 ou mesmo 675, muitos exitam em usa-los nas aplicação que necessite de um LCD. Talvez, até, deixe ele de lado, optando por um com muito pinos, mais caro, e sobrando io’s. Tome o caso do PIC12F675. Pequeno, mas até tem um conversor analógico/digital embutido. Para construir um simples voltimetro fica bem fácil. Mas, aí… como ligar o LCD?
Muitos tem empregado um circuito integrado adicional, que, apesar de funcional, aumenta muito o espaço na placa, aumenta o custo e as vezes sai mais barato pegar um microcontrolador com mais pinos. Pensando nestas dificuldades, resolvi estudar meios de enviar sinais ao Lcd usando poucos pinos. Obtive sucesso com o emprego de rede RC junto aos pinos do LCD, de maneira que um unico fio atendia a 2 pinos do LCD. Nascia o ‘LARIOSPLEX'(L_PLEX). O seu primeiro uso foi no projeto do FREQ_METER_TINY (usando apenas 3 fios). No projeto HCS_PROG_TINY usei apenas parte do principio, nos pinos “E” e “RS”. Mais recentemente, fiz uso do L_PLEX no projeto LC_METER_TINY.

Qual é a idéia básica de operação do sistema?
Observe a figura 1 abaixo.

Nela aparece apenas uma parte do sistema para facilitar o entendimento. Vemos a porta de saida GP1 para controlar os pinos DB5, de forma direta e também DB7, via resistor + capacitor, pinos estes do LCD. Temos GP0 como saida para produzir o pulso de enable (“E”) no LCD (empurrar o dado/comando para dentro do LCD).

Veja a situação “A” da tabela verdade abaixo do circuito.
Colocando GP1 em “0”, dando um tempo ou delay de 750 microsegundos (podendo variar conforme a rede RC usada) em seguida mantendo GP1 em “0”, dá-se um pulso por GP0 e o LCD receberá o valor DB7=”0″(capacitor descarregado = gnd) e DB5=”0″, pois a linha direta está aterrada.

Agora, observe a situação “B” da tabela verdade.
Colocando GP1 em “1”, dando um tempo ou delay e em seguida mantendo GP1 em “1”, dá-se um pulso por GP0 e o LCD receberá o valor DB7=”1″ (capacitor carregado com Vcc) e DB5=”1″, pois a linha direta está ao Vcc.

Altere mais uma vez e observe a situação em “C” da tabela verdade.
Colocando GP1 em “1”, dando um tempo ou delay e em seguida trocando GP1 de “1” para “0”, dá-se um pulso por GP0 e o LCD receberá o valor DB7=”1″ (capacitor carregado com Vcc) e DB5=”0″ , pois a linha direta está aterrada.

Por último, observe a situação em “D” da tabela verdade.
Colocando GP1 em “0”, dando um tempo ou delay e em seguida trocando GP1 de “0” para “1”, dá-se um pulso por GP0 e o LCD receberá o valor DB7=”0″ (capacitor descarregado com vcc) e DB5=”1″ , pois a linha direta está ao Vcc.

Mudando o valor de GP1 antes e/ou depois do “delay” produzirá valores diferentes a serem capturados no LCD. Isto é observado nas colunas horizontais A,B,C e D da tabela verdade, conforme explicado.

Veja agora a figura 2 abaixo:

Nela vemos o esquema mais completo de ligação ao microcontrolador, onde cada pino deverá ter a sua rede temporizadora RC e como usamos 3 pinos, serão 3 redes. Os valores podem ser mudados, mas deverá ser feito um estudo minuciosos e testes para calibrar os tempos necessários para a carga e descarga dos capacitores (no caso, o tempo do ‘delay’). Quanto menores forem estes tempos, mais rápido será enviado os dados/comandos para o LCD. O resistor em série com o diodo serve para agilizar os tempos de descarga dos capacitore, lembrando que nivel 0= 0,6v a 0,8v e nivel 1= 1,2v a 1,4 volts e o capacitor chega a 5 volts Vcc. Portanto, o circuito funciona melhor se a descarga dos capacitores forem mais rápida. Nada impede, também, de eliminar este resistor e diodo, desde que seje refeito a rotina de delay apropriada.

Como funciona agora que temos 3 linhas para controlar?
Irá funcionar da seguinte maneira, usando basicamente 6 fases para o envio de cada nibble (4 bits) para Lcd em modo 4 bits:

1) Colocar na linha ‘DB7’ o valor de ‘DB5’ e colocar na linha ‘DB6’ o valor de ‘DB4’. Se for um dado ,setar (1) a linha ‘E’ e se for comando resetar (0) a linha ‘E’.
2) Dar um Delay (em torno de 800 a 1000 uSeg) para carregar/descarregar os capacitores ligados nos pinos ‘DB4′,’DB5′,’E’. Se a linha era ‘0’, não haverá carga, logicamente.
3) Colocar na linha ‘DB7’ o valor de ‘DB7’ e colocar na linha ‘DB6’ o valor de ‘DB6’ .
4) Imediatamente, pulsar a linha ‘E’ para enviar para o Lcd estes 4 bits (sendo 2 atuais e 2 carregados nos capacitores).
5) resetar(0) ou zerar ‘DB7’, ‘DB6’ e ‘E’.
6) Dar um tempo de Delay de aproximadamente 1 mSeg para descarregar os capacitores carregados.

Agora é só repetir o mesmo para o proximo nibble , colocando na linha ‘DB7’ o valor de ‘DB1’ e na linha ‘DB6’ o valor de ‘DB0’ (Passo 1). Depois Delay, depois no Passo 3 colocar na linha ‘DB7’ o valor de ‘DB4’, na linha ‘DB6’ o valor de ‘DB3’. O resto é igual.

Quais as vantagens deste sistema?
Como atualmente existem capacitores e resistores do tipo ‘smd’, podem ser facilmente montados juntos ao LCD, gerando economia no microcontrolador (mais barato), no espaço (por serem bem pequenos), bem como na complicação para a disposição das varias linhas de atuação do LCD no sistema de tradicional (facilitando para quem faz a placa de circuito impresso).

Quais as desvantagens?
O envio de informação fica mais lento. Até certo ponto, pode-se melhorar o problema, por escolher redes RC para tempo menor e delay’s menores.
Também, para usar o modo ‘leitura’ do Lcd fica comprometido (RW terá que ser sempre aterrado).Esta situação pode ser vencida com uma segunda rede RC no pinos “E” e “RS”, para operar também o “RW”, mas exigiria mais estudo e alterações significativas das rotinas atuais.
Certas situações como interferências (raras), poderá aparecer caracteres ‘estranhos’e necessitar de um ‘reset’ no microcontrolador e LCD. Os resistores em série com cada linha do microcontrolador (R4,R7,R10) foram previsto para proteger
portas do micro e do LCD, no caso de conflito de dados em situação de interferências/falhas.
Com respeito a sofware necessário, temos que alterar inclusive rotinas de inicialização para este método.

Veja abaixo como fica a nova Rotina ASM:

;======================================================================================
L_PLEX ;(LARIOPLEX)

; Rotinas para envio de dados/comandos em Lcd
; by Claudio Lários 14-11-12
;
;Reserve na Ram , os seguintes registradores:
; FLAGS ;flag para determinar se dado ou comando a enviar
; TEMP ;temporário
; DL0 ;contador de tempo
; DL1 ;idem
; TMP ;guarda dado/comando temporariamente para envio

;escolha as portas a serem usadas para o Lcd (3 portas)

#DEFINE LCD_DB7 0h ;NÚMERO DA PORTA DE SAIDA PARA ‘DB5’
#DEFINE LCD_DB6 1h ;NÚMERO DA PORTA DE SAIDA PARA ‘DB6’
#DEFINE LCD_E 2h ;NÚMERO DA PORTA DE SAIDA PARA ‘E’

#DEFINE FLCD_RS FLAGS,0 ;FLAG DE COMANDO/DADO

#DEFINE PORTX EQU GPIO ;PODE SER PORTA, PORTB,PORTC OU GPIO
#DEFINE TRISX EQU TRISIO ;PODE SER TRISA, TRISB,TRISC OU TRISIO

;Nota: Se escolher PortA, então deverá usar o registrador Tris correspondente,
; ou seja : TrisA. Observe que o programa se encarrega de acertar as portas para
; daqui em diante, de forma automática.
; Cuidado com as ‘funções adicionais’ dos pinos que podem atrapalhar
; o funcionamento correto (ex. Comparadores,BConversores Anal/Dig,etc), bem como a
;’Palavra de Configuração'(ex. LVP acionado, Osc Xtal ao invés de RC nterno,etc).
; Esta rotina poderá ser acrescentado a seu programa ou fazer um ‘include'(salvando
; no mesmo Diretório em forma de arquivo de texto).
;===================================================================================

;===================================================================================
;rotina de inicializaçãodo Lcd
LcdInit
;acerta portas para ‘saidas’ nos pinos do Lcd ‘automaticamente’
bsf STATUS,RP0 ;bank1
bcf TRISX,LCD_E
bcf TRISX,LCD_DB7
bcf TRISX,LCD_DB6
bcf STATUS,RP0 ;bank0

bcf PORTX,LCD_E ;Disabled LCD
bcf PORTX,LCD_DB6 ;0011->48
bcf PORTX,LCD_DB7
movlw .30 ;Wait 30 ms
call Delay_Ms

;envia 0x03 por 3 vezes e depois o 0x02 por 1 vez, para modo 4 bits

bsf PORTX,LCD_DB6 ;0011 (carrega capacitores de db5 e db4)
bsf PORTX,LCD_DB7
movlw .250 ;min=.150 (achado por tentativa e erro)
call WAIT_uS

bcf PORTX,LCD_DB6 ;0011 (aterra linha direta)
bcf PORTX,LCD_DB7

bsf PORTX,LCD_E ;Enables LCD
NOP
bcf PORTX,LCD_E ;Disabled LCD
nop
bsf PORTX,LCD_E ;Enables LCD
NOP
bcf PORTX,LCD_E ;Disabled LCD
nop
bsf PORTX,LCD_E ;Enables LCD
NOP
bcf PORTX,LCD_E ;Disabled LCD

; Nota: Foi enviado por 3 vezes o valor 0011 para o LCD

movlw .1 ;Wait 1ms
call Delay_Ms
bcf PORTX,LCD_DB6 ;0010
bsf PORTX,LCD_DB7 ;TORNA DB5 =1 POR TEMPO
movlw .250 ;Wait 2 ms
call WAIT_uS
bcf PORTX,LCD_DB7
call Pulse_E

;Nota: foi enviado o valor 0010 para o LCD

bcf PORTX,LCD_E ;Disabled LCD
bcf PORTX,LCD_DB6 ;0011->48
bcf PORTX,LCD_DB7
movlw .1
call Delay_Ms
movlw 28H ;Set 4 bit data bus length
call EC
movlw 06H ;Entry mode set, increment, no shift
call EC

;abaixo são as opções do usuário para o LCD (descomente uma e comente todas as outras)

;movlw 0DH ;Display ON, Cursor ON, Blink ON
;movlw 0FH ;Display ON, Cursor ALTERADO ON, Blink ON
;movlw 0EH ;Display ON, Cursor ON, Blink OFF
movlw 0CH ;Display ON, Cursor OFF, Blink OFF
call EC

;rotina para limpar a tela do Lcd

LcdClear movlw 01H ;clear display
call EC
movlw .2 ;Wait 2 ms
call Delay_Ms
clrwdt
return

;===========================================================================
;ROTINAS DE ENVIOS DE DADOS E COMANDOS
;envia dados
ED
bsf FLCD_RS ;seta flag para indicar ‘dado’
goto XENV
;===========================================================================
;troca de linha do Lcd
LINE2 movlw 0XC0 ;opção para linha2
;===========================================================================
;envia comandos
EC
bcf FLCD_RS ;reseta flag para indicar ‘comando’
XENV call E_Byte
return
;===========================================================================
;envia byte
E_Byte
clrwdt
movwf TMP ;salva dado/comando a enviar
;acerta portas para ‘saida’ do Lcd

bsf STATUS,RP0 ;bank1
bcf TRISX,LCD_E ;acerta pinos para saidas
bcf TRISX,LCD_DB7
bcf TRISX,LCD_DB6
bcf STATUS,RP0 ;bank0

bcf PORTX,LCD_E
bcf PORTX,LCD_DB7
bcf PORTX,LCD_DB6 ;DESCARREGA CAPACITORES
movlw .1 ;AGUARDA 1 MS P/ DESCARGA COMPLETA QUANDO EM ‘IN’
call Delay_Ms
btfsc TMP,4
bsf PORTX,LCD_DB6
btfsc TMP,5
bsf PORTX,LCD_DB7
btfsc FLCD_RS ;flag rs
bsf PORTX,LCD_E ;Enables LCD
movlw .250 ;tempo para carga dos capacitores -> min=.150 (achado por tentativa e erro)
call WAIT_uS
bcf PORTX,LCD_DB6
btfsc TMP,6
bsf PORTX,LCD_DB6
bcf PORTX,LCD_DB7
btfsc TMP,7
bsf PORTX,LCD_DB7
call Pulse_E ;envia um 1° nible
;———————————————————————
btfsc TMP,0
bsf PORTX,LCD_DB6
btfsc TMP,1
bsf PORTX,LCD_DB7
btfsc FLCD_RS ;flag rs
bsf PORTX,LCD_E ;Enables LCD
movlw .250 ;tempo para carga dos capacitores -> min=.150 (achado por tentativa e erro)
call WAIT_uS
bcf PORTX,LCD_DB6
btfsc TMP,2
bsf PORTX,LCD_DB6
bcf PORTX,LCD_DB7
btfsc TMP,3
bsf PORTX,LCD_DB7
call Pulse_E ;envia um 2° nible
return

;=================================================================================
;pulso no pino ‘E’ do Lcd
Pulse_E

bsf PORTX,LCD_E ;Enables LCD
clrwdt
nop
bcf PORTX,LCD_E ;Disabled LCD
bcf PORTX,LCD_DB7
bcf PORTX,LCD_DB6 ;DESCARREGA CAPACITORES
movlw .1 ;Wait 1ms
call Delay_Ms
return

;=====================================================
;rotina de ‘n’ milisegundos passado por ‘w’
Delay_Ms
movwf DL1
call WAIT_500US
call WAIT_500US
decfsz DL1,f
goto $-3
return
;=====================================================
;rotina de 500 microsegundos
WAIT_500US
movlw .164
WAIT_uS
movwf DL0
decfsz DL0, F
goto $-1
return

;=====================================================
;***************************************************************************************************

Mais detalhes do uso prático, veja os artigos ‘FREQ_METER_TINY‘, ‘LC_METER_TINY‘ E ‘HCS_PROG_TINY‘, com esquemas
, arquivos asm e hex fornecidos.

Segue abaixo o arquivo L_PLEX (arquivo de texto para ‘INCLUDE’):

L_PLEX_ASM

Até o próximo artigo!!!

Curiosidades:

Ouvidos invejáveis
Ervas daninhas melhores que pesticidas

Outros assuntos:

Como resolver ‘diferenças’ no casamento
Como ‘sobreviver’ ao primeiro ano de casamento
Como lidar com dívidas

2

2 comments

  1. 0

    😛 Ola Claudio Larios
    Gostaria de agradecer a sua gentileza de dividir conosco o seu conhecimento.
    Fiquei maravilhado quando conheci a sua pagina para mim foi de grande avalia, pois encontrei artigos que procurava a muito.
    Muito obrigado
    Carlos Roberto

    1. 0

      Olá Carlos! Obrigado por seu comentário. Fico feliz que, de alguma forma, esteja sendo de ajuda, por compartilhar o pouco conhecimento que tenho com os demais colegas hobistas.
      Claudio

Comments are closed.