Implementando Printf

Software e Hardware para ATMEL

Moderadores: 51, guest2003, brasilma

Mensagempor msamsoniuk » 25 Ago 2008 15:01

brasilma escreveu:Caros colegas, dando continuidade a rotina Printf, preciso de uma ajuda com ponteiros.

Coloquei alguns dados na EEPROM e já estou conseguindo ler, porem gosteria de uma idéia de como limitar a quantidade de dados passadas a rotina Printf via ponteiro.

Explico, normalmente passo o texto a ser impresso no seguinte formato: GLCD_Print("Texto", 5, 1, 0, 0); agora preciso passar apenas um byte, que é que foi lido da EEPROM, estou fazendo assim GLCD_Print(&EE_data2, 5, 1, 0, 0); (EE_data2 é uma variável local que recebe o valor da EEPROM), porem a rotina Printf imprime mais de 1 caractere, ou seja, parece que neste caso o limitador '\0' não funciona.

Como posso fazer para que seja pego apenas o byte???


ueh, se vc quer imprimir exatamente 1 caracter, vc pode usar:

printf("%c", *p);

onde p aponta para uma string, *p aponta para o primeiro byte da string e o formatador %c indica para imprimir apenas 1 unico caractere.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor brasilma » 25 Ago 2008 15:39

Olá Robl e Marcelo obrigado pela ajuda, vamos lá:

Robl - a rotina está imprimindo corretamente um caractere, porem após imprimir este caractere ela imprime outros que não tem nada a ver, gostaria justamente de uma sugestão de como fazer para que ela imprima apenas um caractere, tentei agora a pouco fazer assim: GLCD_Print(&EE_data2+'\0', 5, 1, 0, 0); porem não funcionou.

Marcelo - beleza, porem não é uma rotina Printf padrão, é a Printf que estou fazendo, dentro dela há uma determinação do comprimento da string feito desta forma: char_tot = 0; while(texto[char_tot] != '\0') ++char_tot; // atribui à char_tot, o tamanho da string texto . Quando passo um texto no formato: GLCD_Print("Texto", 5, 1, 0, 0); ela funciona bem, porem agora estou tentando passar um byte que está em uma variável e ela está imprimindo mais do que apenas 1 byte, sai o byte e mais um pouco de "sujeira".
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor msamsoniuk » 25 Ago 2008 18:21

brasilma escreveu:Olá Robl e Marcelo obrigado pela ajuda, vamos lá:

Robl - a rotina está imprimindo corretamente um caractere, porem após imprimir este caractere ela imprime outros que não tem nada a ver, gostaria justamente de uma sugestão de como fazer para que ela imprima apenas um caractere, tentei agora a pouco fazer assim: GLCD_Print(&EE_data2+'\0', 5, 1, 0, 0); porem não funcionou.

Marcelo - beleza, porem não é uma rotina Printf padrão, é a Printf que estou fazendo, dentro dela há uma determinação do comprimento da string feito desta forma: char_tot = 0; while(texto[char_tot] != '\0') ++char_tot; // atribui à char_tot, o tamanho da string texto . Quando passo um texto no formato: GLCD_Print("Texto", 5, 1, 0, 0); ela funciona bem, porem agora estou tentando passar um byte que está em uma variável e ela está imprimindo mais do que apenas 1 byte, sai o byte e mais um pouco de "sujeira".


ok, pelo que entendi a sua funcao print requer uma string como parametro! e veja bem, vc *nao pode* converter uma variavel de um unico byte eh uma string de um caractere, pq uma string com um caractere requer pelo menos 2 bytes!

mas a solucao eh muito simples:

Código: Selecionar todos
char p[2]="x"; // reserva 2 bytes para uma string de 1 caractere

...

while(EE_data2=le_eeprom())
{
  p[0]=EE_data2;
  GLCD_Print(p, 5, 1, 0, 0);
}


dae funciona! uma segunda solucao, se vc pode alterar a variavel EE_data2, seria:

Código: Selecionar todos
char EE_data2[2]="x"; // reserva 2 bytes para uma string de 1 caractere

...
while(EE_data2[0]=le_eeprom()) // le eeprom no byte 0 de ee_data direto
{
  GLCD_Print(EE_data2, 5, 1, 0, 0); // note que nao uso &, pq EE_data jah eh string!
}
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor brasilma » 25 Ago 2008 18:42

Gostei muito das soluções Marcelo.

Vou testar as duas e retorno aqui.

Muito obrigado!!!
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor barboza » 25 Ago 2008 22:25

Só um complemento Brasilma.


GLCD_Print(&EE_data2+'\0', 5, 1, 0, 0);



Neste caso vc esta fazendo uma soma na passagem do parâmetro do ponteiro para a string a ser impressa.

&EE_data2+'\0'

Neste caso o compilador irá efetuar esta soma antes de passar o parâmetro. Mas neste caso, como '\0' vale zero, o compilador pode nem fazer nada, ou se fizer não irá mudar o seu parâmetro. Mas cuidado com isso.

Outro detalhe, evite criar funções com muitos parâmetros, pois a passagem de parâmetros é feito com registradores até um certo limite, depois começa a usar a stack e a chamada as funções pode ficar grande e lenta.

Para os compiladores/arquitetura ARM este limite é 4 registradores, para o AVR não sei te dizer.
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor brasilma » 25 Ago 2008 23:28

Belê Barbosa, percebi bem rapidinho que a idéia não funcionou, depois disso "gritei por socorro", rs, rs
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor brasilma » 01 Set 2008 21:58

Marcelo,

Testei hoje a primeira solução e funcionou perfeitamente.

Demorou um pouco pois resolvi fazer algumas mudanças, não vou mais salvar a tabela de caracteres na EEPROM, pois ela é muito acessada e portanto não é interessante fazer isso.

Ao invez usei 768 bytes dela para armazenar uma imagem da tela de abertura, isso já está funcionando legal.

Gostaria de colocar a imagem dos caracteres na Flash, já tentei definir como constante assim: const uint8_t fonte3x5 [] = {} , mas o compilador continua armazenando na RAM, como faço isso???

Abraços.
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor msamsoniuk » 01 Set 2008 23:44

ola brasilma,

as vezes eh dificil fazer o compilador escolher o melhor lugar para armazenar algo. eu particularmente mudaria para:

const char *fonte3x5="\x00\x01\x02 ... ";

pois normalmente quando declaramos ponteiros para strings, estas strings nao sao interpretadas como "reutilizaveis". a notacao usada para colocar dados na string diretamente eh uma notacao hexadecimal usando \x e ela obviamente tem um \x00 implicito no final.

se essa alteracao nao der resultado, suponho que vc vai ter que mexer em parametros de linkagem.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor brasilma » 02 Set 2008 08:26

Obrigado Marcelo,

Vou tentar e retorno com os resultados.

Abraços.
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor brasilma » 02 Set 2008 09:57

Marcelo,

Aceitou legal mas não resolveu, ou seja, continua alocando na RAM, mas fica tranquilo, deixa eu pesquisar um pouco.

Abraços e Obrigado,
Marcos.
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor Sergio38br » 02 Set 2008 10:29

bom dia Brasilma, qual compilador vc esta utilizando???

[ ]'s
Sergio
Avatar do usuário
Sergio38br
Word
 
Mensagens: 759
Registrado em: 22 Nov 2007 13:39
Localização: São Paulo - SP

Mensagempor brasilma » 02 Set 2008 11:46

Boa Tarde Sergio,

Uso o AVR Studio.

Abraços.
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor Sergio38br » 02 Set 2008 15:13

Se por acaso estiver usando o AVRgcc me lembro que quando estava estudando um projeto com o avr , tinha um comando para colocar variaveis de uma tabela na flash. acho que tinha algo sobre o atributo "progmem" na declaração das variaveis Agora teria de rever tudo e achar a documentação que li, espero que esta pequena luz te ajude.

[ ]'s

Sergio
Avatar do usuário
Sergio38br
Word
 
Mensagens: 759
Registrado em: 22 Nov 2007 13:39
Localização: São Paulo - SP

Mensagempor brasilma » 02 Set 2008 15:59

Olá Sergio,

É exatamente isto, a biblioteca se chama pgmspace.h

"The functions in this module provide interfaces for a program to access data stored in program space (flash memory) of the device."

Com ela até os tipos das variáveis ficam similar, ao invez de uint8_t usa-se prog_uint8_t e assim por diante.

Valeuz.
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor RobL » 03 Set 2008 07:54

É isso mesmo que já descobriu, só que se coloca PROGMEM em maiúsculo para informar que é para armazenar na EProm.

const char conc_pattern_2s[] PROGMEM={0x0a,0x80,0xbe,0x41,0x0a,0x80,0x78,0x84,0x0a,0x00,0x7d,0x03,0x0a,0x00,0xfa,0xfa};
const char conc_pattern_2s50[] PROGMEM={0x0a,0x80,0x88,0x58,0x0a,0x00,0x33,0xcb,0x0a,0x00,0x11,0x31,0x0a,0x00,0x22,0xa2};
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Anterior

Voltar para AVR

Quem está online

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

x