Programção com LCD

Enviado:
08 Dez 2006 16:38
por psycoman
Seguinte galera eu fiz um código lendo e copiando da internet, so que eu executo ele no meu controlador e no simulador mais nao acontece nada.
obs a linha RW ta aterrada pra ficar sempre em modo de escrita.
alguem pode me ajudar? o codigo usa RW eu nao consegui fazerm funcionar.
Se puderm me da uma força, recebi meu kit hoje e to futucando já
- Código: Selecionar todos
$mod51
DB0 EQU P1.0
DB1 EQU P1.1
DB2 EQU P1.2
DB3 EQU P1.3
DB4 EQU P1.4
DB5 EQU P1.5
DB6 EQU P1.6
DB7 EQU P1.7
EN EQU P3.7
RS EQU P3.6
;RW EQU P3.5
DADO EQU P1
LCALL INIT_LCD
LCALL CLEAR_LCD
MOV A,#'H'
LCALL WRITE_TEXT
MOV A,#'E'
LCALL WRITE_TEXT
MOV A,#'L'
LCALL WRITE_TEXT
MOV A,#'L'
LCALL WRITE_TEXT
MOV A,#'O'
LCALL WRITE_TEXT
MOV A,#'W'
LCALL WRITE_TEXT
MOV A,#'O'
LCALL WRITE_TEXT
MOV A,#'R'
LCALL WRITE_TEXT
MOV A,#'L'
LCALL WRITE_TEXT
MOV A,#'D'
LCALL WRITE_TEXT
Init_LCD:
SETB EN
CLR RS
MOV DADO,#38h
CLR EN
LCALL WAIT_LCD
SETB EN
CLR RS
MOV DADO,#0Eh
CLR EN
LCALL WAIT_LCD
SETB EN
CLR RS
MOV DADO,#06h
CLR EN
LCALL WAIT_LCD
RET
CLEAR_LCD:
SETB EN
CLR RS
MOV DADO,#01h
CLR EN
LCALL WAIT_LCD
RET
WAIT_LCD:
SETB EN ; inicia os comandos no LCD
CLR RS ;
;SETB RW ; comando de leitura
MOV DADO,#0FFh ; seta todos os pinos para FF
WRITE_TEXT:
SETB EN
SETB RS
MOV DADO, A
CLR EN
LCALL WAIT_LCD
RET
end

Enviado:
08 Dez 2006 17:54
por rubenprom
Me parece que tem um erro na programaçao, quando voce seta os 38h,
ou sej ame refiro na hora que voce inicalize o LCD, na rotina de INIT_LCD, DADO 38H ............tem de fazé-lo 3 vezes, pelo que percebi no seu programa está apenas um avez.
Se quiseres um tutorial sobre LCD, muito pratico, entra neste endereço:
www.aterroso.com, entra em Dicas de HW & SW e procura por Display LCD
Espero ter ajudado

Enviado:
08 Dez 2006 20:43
por gabriel_paz
Oi Psycoman, realmente muitos livros e apostilas informam para enviar o dado 38H 3 vezes, porém não há necessidade, não é esse o motivo de seu programa não estar funcionando.
Provavelmente duas coisas estão ocorrendo, primeiro tome cuidados com essas inúmeras subidas e descidas dos sinais E e RS, preste bastante atenção para não estar mudando o sinal no momento errado, outra coisa como você não está usando a função de leitura do LCD precisa de um delay para que o controlador do LCD interprete o dado/instrução, a seguir posto dois exemplos de programa que funcionam, inclusive é compatível com seu hardware, os pinos de controle também são os mesmos e fiz para os kits aqui da empresa que também têm o RW aterrado.
Primeiro exemplo de programa:
;Dados/Instruções -> 8 Bit Port P1
;R/W -> Terra
;E -> P3.7
;RS -> P3.6
;Definições:
TEMPO EQU (65535-10000) ;Para atraso de 10ms
E EQU P3.7 ;E = pino P3.7
RS EQU P3.6 ;RS = pino P3.6
;Rotina principal
ORG 0000H ;End. de início de escrita na ROM
;Rotina inicial:
CLR A ;Limpo Acc
MOV SP,#30H ;Aponto a pilha p/ o endereço 30H
MOV P1,#00H ;Zero P1
MOV TMOD,#00000001B ;Programo T1 p/ Modo 1 16Bits
;Rotina de inicialização do LCD
CLR RS ;RS em 0 - para envio de instrução
MOV A,#38H ;Configuro display 2 linhas Matriz 5x7
LCALL ESCREVE ;Chama rotina de escrita
MOV A,#06H ;Escreve deslocando o cursor para direita
LCALL ESCREVE ;Chama rotina de escrita
MOV A,#0CH ;Display aceso sem cursor
LCALL ESCREVE ;Chama rotina de escrita
MOV A,#01H ;Limpa o display
LCALL ESCREVE ;Chama rotina de escrita
;Rotina para a escrita de cada caracter de um nome
SETB RS ;RS em 1 - para envio de dados
MOV A,#'S' ;
LCALL ESCREVE ;
MOV A,#'e' ;
LCALL ESCREVE ;
MOV A,#'u' ;
LCALL ESCREVE ;
;Espaço ;
CLR RS ;Envio de instrução
MOV A,#14H ;Desloca somente o cursor para a direita
LCALL ESCREVE ;chama rotina de escrita
;Continua escrevendo os caracteres
SETB RS ;RS em 1 - para envio de dados
MOV A,#'N' ;
LCALL ESCREVE ;
MOV A,#'o' ;
LCALL ESCREVE ;
MOV A,#'m' ;
LCALL ESCREVE ;
MOV A,#'e' ;
LCALL ESCREVE ;
SJMP $ ;
;Rotina para a escrita ;
ESCREVE: MOV P1,A ;Coloca o caracter no PORT 1
SETB E ;E=1
LCALL ATRASO ;Chama atraso de 10ms
CLR E ;E=0 (dados/instruções são lidos na
;transição de 1 para 0
RET ;Retorna da subrotina
;Rotina para tempo de atraso, aproximadamente 10ms
ATRASO: CLR TR0 ;Desliga T0
CLR TF0 ;Zera a flag de estouro
MOV TH0,#HIGH(TEMPO) ;Carregando Timers
MOV TL0,#LOW(TEMPO) ;
SETB TR0 ;Liga o Timer
JNB TF0,$ ;Espera estouro de contagem
RET ;Retorna da subotina
END ;Fim de compilação
Segundo Exemplo de programa:
;Dados/Instruções -> 8 Bit Port P1
;R/W -> Terra
;E -> P3.7
;RS -> P3.6
;Definições:
TEMPO EQU (65535-10000) ;Para atraso de 10ms
E EQU P3.7 ;E = pino P3.7
RS EQU P3.6 ;RS = pino P3.6
;Rotina principal
ORG 0000H ;End. de início de escrita na ROM
;Rotina inicial:
CLR A ;Limpo Acc
MOV SP,#30H ;Aponto a pilha p/ o endereço 30H
MOV P1,#00H ;Zero P1
MOV DPTR,#200H ;Carrega pontiro para escrever a mensagem
MOV TMOD,#00000001B ;Programo T1 p/ Modo 1 16Bits
;Rotina de inicialização do LCD
CLR RS ;RS em 0 - para envio de instrução
MOV A,#38H ;Configuro display 2 linhas Matriz 5x7
LCALL ESCREVE ;Chama rotina de escrita
MOV A,#06H ;Escreve deslocando o cursor para direita
LCALL ESCREVE ;Chama rotina de escrita
MOV A,#0CH ;Display aceso sem cursor
LCALL ESCREVE ;Chama rotina de escrita
MOV A,#01H ;Limpa o display
LCALL ESCREVE ;Chama rotina de escrita
;Rotina para a escrita da mensagem
SETB RS ;RS em 1 - para envio de dados
VOLTA: CLR A
MOVC A,@A+DPTR ;Carrega os caracteres
CJNE A,#'%',CONTINUA ;Verifica fin da mensagem
SJMP $ ;Mantém nesta linha
CONTINUA: LCALL ESCREVE ;Chama rotina de escrita
INC DPTR ;Incrementa o DPTR
SJMP VOLTA ;Próximo caracter
;Rotina para a escrita ;
ESCREVE: MOV P1,A ;Coloca o caracter no PORT 1
SETB E ;E=1
LCALL ATRASO ;Chama atraso de 10ms
CLR E ;E=0 (dados/instruções são lidos na
;transição de 1 para 0
RET ;Retorna da subrotina
;Rotina para tempo de atraso, aproximadamente 10ms
ATRASO: CLR TR0 ;Desliga T0
CLR TF0 ;Zera a flag de estouro
MOV TH0,#HIGH(TEMPO) ;Carregando Timers
MOV TL0,#LOW(TEMPO) ;
SETB TR0 ;Liga o Timer
JNB TF0,$ ;Espera estouro de contagem
RET ;Retorna da subotina
ORG 0200H ;End. da frase
DB 'MINHA FRASE' ;Frase
END ;Fim de compilação
Espero ter ajudado um pouco.
Gabriel

Enviado:
08 Dez 2006 20:45
por R.B.Sanchez
Não está determinada a posição inicial do cursor antes de iniciar a escrita e eu não vejo a necessidade da rotina WAIT_LCD.
É possível melhorar estas rotinas de forma a ficarem menores e simples. O que or comum a mais de um ponto no programa, pode ser centrado em uma única rotina.
Atenciosamente,
Renato.