collapse

* Posts Recentes

+ LASERs por dropes
[03 de Julho de 2025, 19:35]


Cerca eléctrica por SerraCabo
[14 de Junho de 2025, 23:26]


Alguém arranja motores? por almamater
[10 de Junho de 2025, 22:34]


Condensador 4.7uF 0603 por brunus
[09 de Junho de 2025, 15:52]


Lenovo IdeaPad 3 Não liga por jm_araujo
[07 de Maio de 2025, 19:10]


Identificar Diodo Zenner por filjoa
[01 de Maio de 2025, 23:07]


Meu novo robô por dropes
[18 de Março de 2025, 14:51]


JBL partybox On-The-Go por almamater
[21 de Fevereiro de 2025, 23:32]


Talking Reverse Engineering with an Absolute Legend! por SerraCabo
[13 de Fevereiro de 2025, 09:56]


Motoserra Stihl 120C por brunus
[11 de Fevereiro de 2025, 16:29]

Autor Tópico: [AVR-GCC] Divisão Atmega8  (Lida 6930 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline metRo_

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 3.753
[AVR-GCC] Divisão Atmega8
« em: 21 de Novembro de 2009, 19:48 »
Olá,
Eu preciso de imprimir pela porta série um uint8_t em hexadecimal.
Imprimir o valor hexadecimal não é o problema mas sim a conversão de decimal para hexadecimal.
A rotima que quero implementar faz o seguinte:
Para o numero 53 em decimal:

   1 - 53/16 = 3,3125
O resultado da divisão é 3 e este é o valor da esquerda do hexadecimal.
   2 - 0.3125*16 = 5

O resultado em hexadecimal para 53 é 35.
a minha duvida é onde vou buscar a parte fraccionaria, os 0,3125.

Eu sei que a função div() tem mas como accesso aos valores? http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#g7486ea9a8a90ac6b93bed37d08ebbd9e


Offline metRo_

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 3.753
Re: [AVR-GCC] Divisão Atmega8
« Responder #1 em: 21 de Novembro de 2009, 20:24 »
Eu estava a complicar um bocadinho em cima, bastava-me ter acesso ao resto.
Parece que é só isto:

Código: [Seleccione]
int x=53;
int quot;   // The quotient
    int rem;    // The remainder
int y=16;
div_t temp;
temp = div( x, y );
int a = temp.quot;
int b = temp.rem;
« Última modificação: 21 de Novembro de 2009, 20:28 por metRo_ »

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: [AVR-GCC] Divisão Atmega8
« Responder #2 em: 21 de Novembro de 2009, 23:35 »
É muito fácil converter de decimal para hexa... dividir por 16 é o mesmo que shiftar 4 bits para a direita (no sentido do bit menos significativo) e o resto da divisão são os 4 bits que "deitamos fora" com o shift. Pode usar-se uma tabela ou uns ifs para converter para ASCII.
Com uma tabela seria assim:

Código: [Seleccione]
int  x = 53;
char  TabelaConv[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
uart_send(TabelaConv[(x >> 4) & 0x0F]);
uart_send(TabelaConv[x & 0x0F]);

Com ifs seria assim:

Código: [Seleccione]
#define DecDigitToHex(digit)  ( (digit) < 10? '0' + (digit) : 'a' + (digit) - 10 )
int  x = 53;
unsigned char  tmp = (x >> 4) & 0x0F;
uart_send(DecDigitToHex(tmp));
tmp = x & 0x0F;
uart_send(DecDigitToHex(tmp));

Assumi que existe uma função 'uart_send' que serve para enviar um character pela uart.
« Última modificação: 22 de Novembro de 2009, 02:05 por Njay »

Offline metRo_

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 3.753
Re: [AVR-GCC] Divisão Atmega8
« Responder #3 em: 22 de Novembro de 2009, 01:58 »
Realmente o teu código está muito mais simples e mais prático, muito obrigado.
Só acho tens ali um erro, na 5ª linha do segundo exemplo:
Código: [Seleccione]
tmp = TabelaConv[x & 0x0F];Aqui seria:
Código: [Seleccione]
tmp = DecDigitToHex[x & 0x0F];
certo?

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: [AVR-GCC] Divisão Atmega8
« Responder #4 em: 22 de Novembro de 2009, 02:02 »
Quase! Era "tmp = x & 0x0F;". Erro de copy&paste, obrigado :). Vou alterar na mensagem anterior.

Mas entendeste o código? Os 2 blocos são independentes, ou se usa 1 ou o outro.
« Última modificação: 22 de Novembro de 2009, 02:05 por Njay »

Offline metRo_

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 3.753
Re: [AVR-GCC] Divisão Atmega8
« Responder #5 em: 22 de Novembro de 2009, 02:08 »
sim percebi,
eu tinha colocado
Código: [Seleccione]
tmp = DecDigitToHex[x & 0x0F]; pois pensei que era o tmp que era enviado na porta serie ;)

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: [AVR-GCC] Divisão Atmega8
« Responder #6 em: 22 de Novembro de 2009, 03:26 »
Não poderia ser "DecDigitToHex[x & 0x0F]" porque DecDigitToHex é uma macro e não um array, e os [] só se usam com arrays.

A conversão para hexadecimal (hex) é muito simples porque é fácil converter de binário para hex, e é por isso que se usa tanto em programação e electrónica digital. Repara no teu número 53:

   53      (decimal)
0011 0101  (binário)
   3 5     (hexadecimal)

Se partires do número na representação binária, basta dividir o número em grupos de 4 bits e converter cada grupo de 4 para hexadecimal. Cada grupo corresponde a um digito em hexadecimal: 0011b = 3h e 0101b = 5h ("b" indica que o número é binário e "h" que é hexadecimal). Desta forma é muito mais simples converter entre binário e hex do que entre binário e decimal.
« Última modificação: 22 de Novembro de 2009, 03:28 por Njay »