collapse

* Posts Recentes

Arame de Estendal por almamater
[Hoje às 16:16]


O que é isto ? por SerraCabo
[12 de Abril de 2024, 14:20]


Amplificador - Rockboard HA 1 In-Ear por almamater
[11 de Abril de 2024, 20:46]


Emulador NES em ESP32 por dropes
[10 de Abril de 2024, 15:30]


Meu novo robô por josecarlos
[29 de Março de 2024, 18:30]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]

Autor Tópico: [AVR-GCC] Divisão Atmega8  (Lida 4171 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 »