collapse

* Links de Robótica

* Posts Recentes

Medir Agua que está no Poço por jm_araujo
[Hoje às 00:36]


URGENTE - display de 7 segmentos com backpack por helderjsd
[Ontem às 12:30]


Preços e fabricantes de pcb por Sérgio_Sena
[19 de Setembro de 2017, 10:20]


Palavras Cruzadas por Njay
[19 de Setembro de 2017, 02:24]


Isaac Asimov - I, Robot por senso
[18 de Setembro de 2017, 03:41]


Apresentação por TigPT
[17 de Setembro de 2017, 07:31]


ic SL440 da Plessey? por senso
[16 de Setembro de 2017, 13:11]


Compra Colectiva RS-Amidata por brunus
[15 de Setembro de 2017, 22:31]


Ideias para construir um quadrúpede simples por zordlyon
[15 de Setembro de 2017, 10:18]


Preparar bancada de testes por jm_araujo
[14 de Setembro de 2017, 10:24]

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

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

Offline metRo_

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 3.726
[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.726
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.086
    • 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.726
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.086
    • 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.726
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.086
    • 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 »