Escrevendo no LCD.

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Escrevendo no LCD.

Mensagempor Pask » 08 Jul 2008 15:08

Amigos do fórum, estou manipulando um display LCD de 2 linhas e 16 colunas e gostaria de saber como implementar um simples programinha para escrever a frase "TESTANDO DISPLAY" em seu visor. A parte de comandos de inicialização do display eu já fiz. Eu apenas gostaria de saber como enviar a frase acima para o display via barramento paralelo de 8 vias. A comunicação não é via USART!
Por exemplo, com comunicação paralela via portB como eu estou fazendo, o caracter "T" em ASCII seria representado pelo código binário 01000101 o que, em hexadecimal, seria 0x45. Então, eu pensei: para enviar cada letra ao display será que eu terei que enviar cada seqüência de 8 bits para o barramento do portB separadamente? Mas, será que não teria um modo mais direto de escrever as letras no display? Alguém poderia passar-me uma sugestão? Não seria possível implementar uma escrita com variáveis do tipo "char" ?
Detalhe: eu estou trabalhando com a linguagem C.
Obrigado e aguardo vocês.
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor ze » 08 Jul 2008 15:38

Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: Escrevendo no LCD.

Mensagempor Maurício » 08 Jul 2008 23:46

Salve, Pask.

Pask escreveu:Então, eu pensei: para enviar cada letra ao display será que eu terei que enviar cada seqüência de 8 bits para o barramento do portB separadamente?


Sim. Caractere por caractere. Mas, qualé o problema? A parte chata (ficar enviando) quem faz é o MCU! eheheheheh

Mas, será que não teria um modo mais direto de escrever as letras no display?


Que eu saiba, não! Displays LCDs nada mais são do que memórias RAM visuais. Vc precisa endereçar o display e escrever o caractere. Exibem ASCII.

Alguém poderia passar-me uma sugestão?


Sugestão de que? De rotina? Se for rotina, experimenta as minhas naquele fórum que o lellis citou.

Não seria possível implementar uma escrita com variáveis do tipo "char"?


Tem que ser, do tipo char. O que eu faço é criar uma string e enviar letra por letra.

[]'s
"Não leve a vida tão à sério, afinal, nenhum de nós sairá vivo, dela!"
Avatar do usuário
Maurício
Word
 
Mensagens: 678
Registrado em: 14 Out 2006 17:23
Localização: São Paulo - SP

Mensagempor geraldomelo » 09 Jul 2008 04:20

não entendi direito ... vc esta construindo sua própria lib ?? se não , dá uma olhaa aqui:


http://www.asm51.eng.br/phpbb/viewtopic ... ght=#26961
geraldomelo
Byte
 
Mensagens: 267
Registrado em: 14 Out 2006 16:53
Localização: Ribeirão preto - SP

Mensagempor Pask » 10 Jul 2008 12:25

Caros amigos, algumas mensagens deste post desapareceram e eu não consigo mais visualizá-las. A última pergunta que eu fiz foi a seguinte: como escrever o código de escrita para o lcd sem utilizar ponteiros para as variáveis do tipo char? Obrigado.
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor Maurício » 11 Jul 2008 04:24

Kraca!!

As postagens sumiram todas!

Pask. Ao invés de passar um ponteiro pra função, vc pode passar um vetor, dessa forma:

Código: Selecionar todos
void LCD_escreve ( char string [ ] )
{
   unsigned char indice = 0;

   while ( string [ indice ] )
   {
      output ( string [ indice ] );  // não me lembro qual era o comando de saída
      PULSE_ENA;
      indice++;
   }
}

void main ( void )
{
   char texto [ ] = "TEXTO";

   init_LCD ( );
   LCD_escreve ( texto );
   while ( 1 );
}


Experimenta aí, mas, fazer isso, não é muito prático, não! E pode acontecer de vc introduzir bugs no seu programa! O mais prático é passar ponteiros pra essa função, mesmo. Estude ponteiros, cara. Eles são o basicão em C.

[]'s
"Não leve a vida tão à sério, afinal, nenhum de nós sairá vivo, dela!"
Avatar do usuário
Maurício
Word
 
Mensagens: 678
Registrado em: 14 Out 2006 17:23
Localização: São Paulo - SP

Mensagempor Pask » 11 Jul 2008 08:57

Amigo Maurício, o que acontece com relação aos ponteiros é que eu ainda não consegui entender a sua utilidade prática na programação em C. Qual é a vantagem de se fazer referência à posição da variável dentro da memória RAM do PIC e não atribuir um valor a ela? Qual é a vantagem deste procedimento? É isto que eu não entendo! Se vc pudesse me explicar melhor a vantagem dos ponteiros eu agradeceria mais ainda!
Até...
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor xultz » 11 Jul 2008 13:04

A vantagem é a seguinte:
Imagine que você tem espaço contínuo de memória 10 bytes de informação. Você sabe que na primeira posição tem determinada informação, na segunda tem outra, e assim por diante. E estas informações estão na RAM.
Agora imagine que você quer passar para uma rotina estes dados para a rotina manipulá-los. Como você faria sem ponteiros? Teria que carregar cada byte num registrador, chamar a rotina, esta descarregaria os registradores e manipularia-os. O PIC tem um único e mísero registrador. Logo, dessa maneira é impossível.
Assim, se você passar somente o ponteiro do primeiro byte para a função, é suficiente. A rotina pega o byte do ponteiro, e usa-o. Se pegar o ponteiro + 1 pode acessar o segundo byte, e assim por diante. Se você pensar isso no código assembly que o compilador provavelmente vai gerar, vai entender como é prático (o que quer dizer que roda rápido e gasta pouca memória).

Imagine que você faz duas rotinas: uma para escrever um caracter no display, que podemos prototipar como
void escrever_letra(unsigned char letra);
você passa uma byte e a rotina faz o protocolo de escrita da letra no display.
Daí você faz outra rotina, do tipo
void escreve_frase(unsigned char * frase, int quantidade);
Esta rotina podemos escrever como:
Código: Selecionar todos
{
    for( ; quantidade !=0; quantidade--)
        {
              escreve_letra(* frase);
              frase++;
         }
}


E daí você chama a rotina com:
escreve_frase("TESTE 1234", 10);

O que que o compilador vai fazer:
Primeiro, a frase TESTE 1234 ele vai guardar na flash, com os caracteres na ordem.
Segundo, quando você chama o comando acima, ele vai verificar somente qual é o ponteiro para o primeiro caracter, e vai passar para a rotina de escrever a frase, e a rotina vai poder ler o valor do byte, usá-lo, ler o próximo, e assim por diante.

Se você não usar ponteiros, é difícil imaginar uma forma de fazê-lo.

Eu compreendo você, ponteiro é um saco, eu entendo menos de ponteiros do que deveria, eu também xinguei esse negócio no começo, mas não tem como fugir, ponteiros em C é essencial.
Código: Selecionar todos
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor Pask » 11 Jul 2008 15:47

Bem amigos, ainda não consegui fazer o display funcionar. Energizo o circuito, o backlight acende e todos os pixels da linha 1 acendem (retângulos). A minha biblioteca de controle para o lcd é:

void lcd_data(){

output_high(rs); //lcd recebe com dados
}


void lcd_command(){

output_low(rs); //lcd recebe com comandos

}


void send_lcd(){ //envia dados ou comandos ao lcd pelo barramento do port B

output_high(en);
delay_ms(1);
output_low(en);
delay_ms(1);
}

void lcd_escreve(char *k){ //escreve algo no lcd
while(*k){
output_b(*k);
k++;
send_lcd();
}
}

void init_lcd (){ //inicialização do lcd.

lcd_command();
output_b(0x30);
send_lcd();
delay_ms(4);
output_b(0x30);
send_lcd();
delay_us(100);
output_b(0x30);
send_lcd();
delay_us(40); //comandos de inicialização do lcd
output_b(0x01); //comando para limpar o display e posicionar o cursor na linha 1 e coluna 1
send_lcd();
delay_ms(2);
output_b(0x38); //comando para 8 via de dados e matriz 7x5
send_lcd();
delay_us(40);
output_b(0x0e); //comando para ligar display e cursor
send_lcd();
delay_us(40);
output_b(0x0c); //comando para display sem cursor
send_lcd();
delay_us(40);
output_b(0x06); //comando para deslocamento automático do texto para a direita
send_lcd();
delay_us(40);
lcd_data();
}

Por que ainda não funcionou ???
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor Maurício » 11 Jul 2008 16:14

Pask.

O pino RW do display está aterrado?

Cara! Baixe essa apostila do Renie aqui:

http://www.reniemarquet.cjb.net/arquivo ... 050119.pdf

Eu sei que eu tinha a inicialização pra 8 bits aqui, mas, não tá no computador e eu nem me lembro mais como é que se inicializa o display, eheheheheh

AVR é problema!! eheheheheheh
Deixa a gente preguiçoso, eheheheheh

Vc tb deu um delay (uns 100ms) depois de ligar o circuito pro LCD poder se estabilizar?

[]'s
"Não leve a vida tão à sério, afinal, nenhum de nós sairá vivo, dela!"
Avatar do usuário
Maurício
Word
 
Mensagens: 678
Registrado em: 14 Out 2006 17:23
Localização: São Paulo - SP

Mensagempor Pask » 11 Jul 2008 17:12

As informações que eu posso passar para você são as seguintes:

O pino RW está sim aterrado;
Eu dei um tempo inicial de 50ms para a estabilização do circuito;
Tentei enviar a string para o lcd assim:

char k;
k=("T");
output_b(k);
send_lcd();

k=("E");
output_b(k);
send_lcd();

...e assim por diante até formar a palavra "TESTE" por inteiro.
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor Maurício » 12 Jul 2008 06:07

Pask escreveu:As informações que eu posso passar para você são as seguintes:

O pino RW está sim aterrado;
Eu dei um tempo inicial de 50ms para a estabilização do circuito;
Tentei enviar a string para o lcd assim:

char k;
k=("T");
output_b(k);
send_lcd();

k=("E");
output_b(k);
send_lcd();

...e assim por diante até formar a palavra "TESTE" por inteiro.


Seus procedimentos estão incorretos.

Em C, o que estiver entre ASPAS, é string. O compilador finaliza automaticamente a string com o terminador de string NULL ('\0' ou 0x00H).
Mas, no seu programa vc não define uma string, vc define simplesmente, uma variável do tipo CHAR (byte) de oito bits.

Código: Selecionar todos
char k;


Uma string é um vetor de caracteres, e são definidas com o uso de colchetes, p. ex. ( char k [ ]; ). Isso É uma string sem comprimento, ou, de comprimento indeterminado.

Se vc quer passar somente UM caractere ASCII para uma função qualquer, vc passa o caractere entre APÓSTROFO, como abaixo:

Código: Selecionar todos
char k;
k = 'T';
output_b(k);    // <-- ISSO DAQUI VAI DAR PROBLEMAS!!
send_lcd();


Mas, se vc cria uma função para enviar uma string, e passa um caractere único pra função, o que vc acha que vai acontecer?

Estude CARACTERES, STRINGS, VETORES, MATRIZES e principalmente, PONTEIROS em C. Vc não vai perder seu tempo!

Boa sorte.

[]'s
"Não leve a vida tão à sério, afinal, nenhum de nós sairá vivo, dela!"
Avatar do usuário
Maurício
Word
 
Mensagens: 678
Registrado em: 14 Out 2006 17:23
Localização: São Paulo - SP

Mensagempor Pask » 12 Jul 2008 16:36

Amigos, deixando um pouco de lado as minhas dificuldades com a linguagem C, resolvi escrever o código em assembly, usando um exemplo do livro "Conectando o PIC - Recursos Avançados" do Nicolás César Lavínia. Fiz uma adaptação para o meu caso, reduzindo o código e tornando-o mais simples. Uma parte do código é:

INIT_DISPLAY

MOVLW .50
CALL DELAY_MS ;AGUARDA UM TEMPO INICIAL

BCF RS ; SELECIONA O DISPLAY P/ COMANDOS

MOVLW 0X30 ; ESCREVE COMANDO 0X30 PARA
CALL ESCREVE ; INICIALIZAÇÃO

MOVLW .5
CALL DELAY_MS ; DELAY DE 3MS (EXIGIDO PELO DISPLAY)

MOVLW 0X30 ; ESCREVE COMANDO 0X30 PARA
CALL ESCREVE ; INICIALIZAÇÃO

MOVLW 0X30 ; ESCREVE COMANDO 0X30 PARA
CALL ESCREVE ; INICIALIZAÇÃO

MOVLW B'00111000' ; ESCREVE COMANDO PARA
CALL ESCREVE ; INTERFACE DE 8 VIAS DE DADOS

MOVLW B'00000001' ; ESCREVE COMANDO PARA
CALL ESCREVE ; LIMPAR TODO O DISPLAY
MOVLW .1
CALL DELAY_MS ; DELAY DE 1MS

MOVLW B'00001100' ; ESCREVE COMANDO PARA
CALL ESCREVE ; LIGAR O DISPLAY SEM CURSOR

MOVLW B'00000110' ; ESCREVE COMANDO PARA INCREMENTO
CALL ESCREVE ; AUTOMÁTICO À DIREITA

MOVLW 0X80 ; COMANDO PARA POSICIONAR O CURSOR NA
CALL ESCREVE ; LINHA 0 / COLUNA 0

BSF RS ; SELECIONA O DISPLAY P/ DADOS

RETURN
-------------------------------------------------------------------------------------
Para escrever no display, eu fiz - de acordo com o livro:

MOVLW 'T'
CALL ESCREVE
MOVLW 'E'
CALL ESCREVE
MOVLW 'S'
CALL ESCREVE
MOVLW 'T'
CALL ESCREVE
MOVLW 'E'
CALL ESCREVE

GOTO $

Porém, infelizmente, ainda não funcionou. Aparece apenas a letra "E" no canto superior esquerdo do display e não a palavra "TESTE" inteira como deveria ser. E agora?
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor Pask » 13 Jul 2008 20:09

Amigos, a questão do lcd foi descoberta. O meu PIC estava com defeito no pino RB0 que se mantinha continuamente em nivel lógico zero! Como o portB é usado como barramento paralelo do lcd (RB0-RB7), estando o pino RB0 constantemente em low, o coitado do lcd estava recebendo instruções totalmente equivocadas e erradas o tempo todo! Um exemplo:
a letra "T" em ASCII é representada pelo número 0x54; já a letra "U" é representada pelo número 0x55. A diferença existente entre T e U na tabela ASCII é somente o primeiro bit do byte. Quando a letra é T, o primeiro bit é zero e quando a letra é U, o primeiro bit é 1. Como esse primeiro bit é gerado pelo pino RB0 do PIC e ele mantinha-se continuamente em zero, vocês já podem imaginar o que estava acontecendo....rsrsrsrsr!
Agora, vou comprar um PIC novo e testá-lo que certamente obterei sucesso. Obrigado.
Pask
Word
 
Mensagens: 600
Registrado em: 22 Dez 2006 19:19

Mensagempor Maurício » 13 Jul 2008 23:24

Já que o problema era o PIC, volta pro C rapidinho! ehehehehehehe

[]'s
"Não leve a vida tão à sério, afinal, nenhum de nós sairá vivo, dela!"
Avatar do usuário
Maurício
Word
 
Mensagens: 678
Registrado em: 14 Out 2006 17:23
Localização: São Paulo - SP

Próximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

cron

x