Página 1 de 1

Mostragem em display LCD

MensagemEnviado: 11 Set 2008 19:46
por buiz
Ola amigos,

Estou com uma duvida em C que parece simples mas tem me tirado o sono para resolver.

Estou fazendo os menus de um novo projeto, e nos campos ainda sem valores ao inves de mostrar 00 tera que mostrar -- (dois tracinhos)

Mas como minha variavel e um numero inteiro, e nao tem como trabalhar com dois tipos de mostragem em um mesmo campo do display, ou seja para inteiro uso %u e para caracteres %s, como faco para mostra -- quando o valor for 0?

Desculpe os erros de acentuacao mas meu note ta meio louco esta semana e nao aceita nada.

Um exemplo do que tera que acontecer:

Hora: 00:00 (assim e o normal)
Hora: --:-- (Preciso que apareca assim e ao digitar o valor substitua o -- pelo valor digitado)

Se alguem tiver alguma solucao, ficarei eternamente grato, pois faz tempo que este problema me atormenta.

So lembrando programo em C no CCS.

Um abraco a todos!

MensagemEnviado: 11 Set 2008 23:20
por microcontrolador.pic
Olá amigo,

Na linguagem BASIC (a que eu entendo) eu faria o seguinte:

print at 1,1, "Hora: 00:00" ;(mostrar na tela normal)

para programar a hora eu faria

print at 1,1, "Hora: --:--"

e na media que pressionar alguma tecla, incrementa uma variável que deslocará o número na posição contida a string "-" da tela acima;
por exemplo:


print at 1,7 "2" ; isto mostraria no display "Hora: 2-:--"
print at 1,8 "1" ; isto mostraria no display "Hora: 21:--"
print at 1,10 "1" ; isto mostraria no display "Hora: 21:1-"
print at 1,11 "6" ; isto mostraria no display "Hora: 21:16"


agora para o problema da conversão para número inteiro:
"1" = "01"
"2" = "02"
você deveria comparar se a string a ser mostrada houver 2 digitos, senão deveria adicionar o "0" antes para obter dois dígitos.


Obs.: desculpe o código ou a explicação bastante resumida, espero ter lhe ajudado.

Abraços!
:D

MensagemEnviado: 12 Set 2008 07:51
por buiz
Realmente o que eu necessito e isso mesmo, trocar os tracinhos pelo valor digitado

Mas nao estou achando como fazer isso em C, obrigado pela dica, vou dar uma analisada e ver o que posso aproveitar dela.

Valeu, se alguem tiver mais alguma dica fico grato,

Um bom dia a todos!

MensagemEnviado: 12 Set 2008 08:17
por phophollety
buiz escreveu:Realmente o que eu necessito e isso mesmo, trocar os tracinhos pelo valor digitado

Mas nao estou achando como fazer isso em C, obrigado pela dica, vou dar uma analisada e ver o que posso aproveitar dela.

Valeu, se alguem tiver mais alguma dica fico grato,

Um bom dia a todos!


Como está escrevendo no lcd? printf direto!?

Procure fazer um vetor com o nome de bufferLcd[][]. com o número de linhas correspondende ao seu display e o número de colunas correspondente também.

Faça um driver que por timer pegue esse vetor todo e reescreve no LCD.

Faça um buffer constante com as mensagens , supomos que seu display é um 2 * 16

Código: Selecionar todos
const unsigned char Mensagens [QUANTIDADE_DE_MENSAGENS][NUMERO_DE_COLUNAS] { "mensagem 1  ", // 0
                                        "mensagem 2  ", // 1
                                        "mensagem n..." // 2
                                         "Hora: --:--     "}; // 3 Mantenha os 16 caracteres!!!

Quando for chamar a mensagem, você carrega do constante para o buffer do driver, faça um for

for ( i = 0; i < NUMERO_DE_COLUNAS, i ++ )
{
      bufferLcd[ LINHA_1 ][ i ] = Mensagens[ 3 ] [ i ]
}

O buffer estará escrito;

crie uma variável cont, que vc usará por todo o programa

unsigned char cont = 0;

tem sua variavel hora, um int.

unsigned int hora = 0;

switch( cont )
{
    case 0:
         bufferLcd[ LINHA _ 1][ 11 ] = ( ( hora & 0x000f ) + 0x40 );
         break;

    case 1:
         bufferLcd[ LINHA _ 1][ 12 ] = unsigned int( ( ( hora & 0x00f0 ) + 0x40 ) >> 4 );
         break;

    case 2 :
         bufferLcd[ LINHA _ 1][ 13 ] = unsigned int (( ( hora & 0x0f00 ) + 0x40 ) >> 8 );
         break;

    case 3:
         bufferLcd[ LINHA _ 1][ 14 ] = unsigned int (( ( hora & 0xf000 ) + 0x40 ) >> 12 );
         break;
         break;

}

Toda vez que o seu usuário colocar uma hora, você chama essa rotina..

Faça uma rotina com todas as telas do display, fica melhor estruturado.
Basicamente assim, quando ele colcar uma hora, você vai no switch.

Claro, coloque as variáveis na área de variaveis ou no começo da função, não se esqueça dos idents, faça uma boa estrutura, é vitál quando o programa começa a crescer ou numa futura manutenção.





MensagemEnviado: 12 Set 2008 08:38
por buiz
Muito boa a sua a idéia phophollety,

Ainda não tinha pensado em fazer desta forma, ficou pratico, estou dando uma olhada para ver como poderei implementar no meu programa, pois ele ja estava quase pronto, na realidade esta pronto, só estou tentando acertar esta parte agora, pois meu chefe acha melhor que apareça tracinhos ao inves de 00000000000......

Outra duvida, andei dando uma olhada nos ATOIs ATOLs mas com eles posso passar uma string para inteiro, e para passar de inteiro para string, tem alguma solução?

Andei dando uma olhada no Help do CCS mas não encontrei nada de inteiro para String.

Tambem seria uma solução para mim se eu conseguisse fazer desta forma.

Obrigado pelas dicas.

MensagemEnviado: 12 Set 2008 09:22
por buiz
Ola,

Bom, achei como fazer usando o ITOA(), mas ocupa muita memoria do uC, mas funcionou, vou ver se consigo otimizar um pouco o meu codigo.

Continuo na luta!

MensagemEnviado: 12 Set 2008 10:00
por joao
Ola,

Não sei se funcionaria para microcontrolador, mas acho que sim. Se não rolar, avisa:

o que você tem hoje em dia é algo deste tipo?

Código: Selecionar todos
int hora[4]; //quatro posicoes, sendo duas para hora e 2 para minuto

printf(lcd,"hora: %d%d:%d%d", hora[0],hora[1],hora[2],hora[3]);


O que eu sugeriria era fazer o seguinte:
Código: Selecionar todos
int hora[4]; //quatro posicoes, sendo duas para hora e 2 para minuto

for (int i=0; i<4; i++) //Zerando as variaveis com -1
    hora[i] = -1;

/*Aqui neste espaço vc faz a captura dos valores, e joga na variavel hora*/

printf(lcd,"hora: %c%c:%c%c",
               hora[0] == -1 ? '-':'0'+hora[0],
               hora[1] == -1 ? '-':'0'+hora[1],
               hora[2] == -1 ? '-':'0'+hora[2],
               hora[3] == -1 ? '-':'0'+hora[3]);


Explicando essa linha aqui: hora[0] == -1 ? '-':'0'+hora[0]
é um if ternario que é isso:
condicao ? retorno_se_verdadeiro: retorno_se_falso

A condição é: hora[0] == -1 verifica se a variavel tem o valor original.
retorno_se_verdadeiro é: '-' se for -1, retorna o traço
retorno_se_falso é: '0'+hora[0] que retorna o valor ASCII de '0' MAIS o valor de hora. Entao imagine que vc tem 1 na variavel hora[0], ele vai retornar o valor ASCII de '0' +1 que é na verdade '1'.

Bem, seilá se pirei muito. :)

Mas quem sabe lhe de uma idéia melhor do que fazer.

[]'s

MensagemEnviado: 12 Set 2008 10:39
por ze
ocupar muita memória é o resultado de usar rotinas préprontas.
mas de int (na verdade char) pra string não é só somar 0x30?
um ex. que funciona nos meus projs pra 4 (ou -) dígitos:
Código: Selecionar todos
void lcd_dec(unsigned char li,unsigned char co,unsigned char nd,unsigned int dado)
{
unsigned int mil,cen,dez,un;
mil=dado/1000;
cen=(dado-mil*1000)/100;
dez=(dado-mil*1000-cen*100)/10;
un=dado-mil*1000-cen*100-dez*10;
LCD_RS=0;
lcd_write(li+co);//posiciona cursor
LCD_RS=1;
switch(nd) { //num de dígitos
   case 4: lcd_write(mil+0x30);//sem break
   case 3: lcd_write(cen+0x30);
   case 2: lcd_write(dez+0x30);
   case 1: lcd_write(un+0x30);
   }
}
substitui o itoa() e come menos mem. ah, o lcdwrite() é uma rotininha que escreve 1 caracter no disp.
abs

MensagemEnviado: 12 Set 2008 10:43
por joao
Lellis,

A unica diferença que eu vejo é em relação a valores maiores que 9...
com o itoa, vc consegue tranformar 1234567 para "1234567"
Enquanto que somando apenas 0x30 não rola.

0x30 = 48 decimal = '0' em ASCII.

Por isso que somando 0x30 dá certo, mas usando apenas 1 casa decimal apenas. Mais do que isso é erro na certa!

MensagemEnviado: 12 Set 2008 13:18
por ze
corretíssimo joão padre marcelo!!! é claro que percebeste que a rotininha acima desmonta o int e coloca cada asc com uma pinça no display. e pode ser menor que 9 sim. se não quiser o zero a esquerda (= eu), é só "argumentar" 1 no nd. aquele ex. é de pobre pra pobre (de memória). tente ver que aqui em baixo temos que trabalhar as vezes com 16 bytes de ram e 256 de rom total e em 100% C e é possível! o itoa() é pra ricos e inteligentes. mas tem sua utilidade. na verdade prefiro sprintf().
ah, tá...aquelas continhas não deixam o valor > 9 se dado<=9999
abs.....

MensagemEnviado: 12 Set 2008 13:50
por joao
Tá reclamando do que?

Olha a gambiarra que eu fiz ali no código...
Só que eu uso direto em ASCII ao invés de hexa como tu...
Pq saber valores hexa é para poucos e ricos!
Eu, pobre mortal, uso o ASCII mesmo...
hehehe

[]'s

MensagemEnviado: 12 Set 2008 14:56
por buiz
Ai pessoal, por questão de tempo estourado para entregar o projeto, e sem falar que ja esta praticamente 98% pronto, apelei para o ITOA().

Ficou +/- assim, esse foi um teste apenas.

Código: Selecionar todos
int val=123;//Variavel que muda conforme a programação
char string[4];
char zero[]={"--"};//Substitui o zero no display
char mostra[];// Variavel de mostragem


if (val>0) {itoa(val,10,string);// Se val maior que zero usa o itoa
                mostra=string;}// Atribui o valor de String a Variavel mostra
                                       

if (val==0) mostra=zero;// Se val igual a zero escreve --

printf (LCD,"teste: %s",mostra);// Escreve no Lcd




Mas para os proximos projetos vou estudar cada uma das sugestões dadas.

Obrigado microcontrolador.pic.
Obrigado phophollety
Obrigado Joao
Obrigado Lellis

Um abraço a todos! Um otimo final de semana!

MensagemEnviado: 12 Set 2008 18:34
por Maurício
buiz,

Já que vc está trabalhando com tempo de relógio, que varia no máximo até 59D (3BH), substitua os traços por 0xFFH e testa!

Se for 0xFF, sua rotina de impressão substitui o byte 0xFF por traços.
O que está no LCD, só vale pro LCD. Na memória continua tudo como está.

Eu faço isso!

[]'s

MensagemEnviado: 14 Set 2008 09:17
por phophollety
Maurício escreveu:buiz,

Já que vc está trabalhando com tempo de relógio, que varia no máximo até 59D (3BH), substitua os traços por 0xFFH e testa!

Se for 0xFF, sua rotina de impressão substitui o byte 0xFF por traços.
O que está no LCD, só vale pro LCD. Na memória continua tudo como está.

Eu faço isso!

[]'s


Simples e funcional...

A vantagem de se usar como eu mostrei é que é prático poder alterar um só caracter, sem ter que rescrever o display todo...

Essa técnica de fazer um "device driver" genérico que só faz pegar do vetor e escrever no display pelo timer e específico para cada uC aliado a rotina de estrutura de display é ótima, pois a rotina de estrutura é completamente portável para qualquer compilador, basta reescrever o device driver...