Перейти к содержанию
    

Преобразование двоичного в двоично-десятичный код

Имеетя 24-х разрядное двоичное число представленное в виде трех однобайтных (unsigned char) переменных

BYTE2,BYTE1,BYTE0 (старший -> младший байт числа)

 

Нужно это число пребразовать в 8 разрядов десятичного числа представленных unsigned char переменными DIGIT7...DIGIT0 (старший -> младший байт числа)

 

Возможно использовать только переменные unsigned char т.к. это для восьмиразрядного микроконтроллера.

 

Помогите написать на языке С функцию для такого преобразования.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно использовать только переменные unsigned char т.к. это для восьмиразрядного микроконтроллера.
Глупость вы тут написали. Как только вы это поймете, задача сведется к трем строчками кода.

 

1)пока исходое число не равно нулю

2)записать в выходной буфер остаток от деления исходного числа на 10

3)поделить исходное число на 10.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На PIC16 я делал так

uint32_t value;
uint8_t digit[8];
void lcdPrint(void)
{
digit[7] = 0;
while(value >= 10000000)
{
	value -= 10000000;
	++digit[7];
}
digit[6] = 0;
while(value >= 1000000 )
{
	value -= 1000000;
	++digit[6];
}
digit[5] = 0;
while(value >= 100000 )
{
	value -= 100000;
	++digit[5];
}
digit[4] = 0;
while(value >= 10000 )
{
	value -= 10000;
	++digit[4];
}
digit[3] = 0;
while(value >= 1000 )
{
	value -= 1000;
	++digit[3];
}
digit[2] = 0;
while(value >= 100 )
{
	value -= 100;
	++digit[2];
}
digit[1] = 0;
while(value >= 10 )
{
	value -= 10;
	++digit[1];
}
digit[0] = 0;
while(value >= 1 )
{
	value -= 1;
	++digit[0];
}
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Придется искать 24-разрядный микроконтроллер, иначе никак!)

 

Есть реализация этой задачи на assembler, но не знаю как это на С перевести

 

CBLOCK   
    DIGIT0   
    DIGIT1   
    DIGIT2   
    DIGIT3   
    DIGIT4  
    DIGIT5   
    DIGIT6   
    DIGIT7   
    BIN0     
    BIN1    
    BIN2    
        cycles  
    deccnt   
    octcnt   
    bitcnt   
ENDC

bin2dec
    CLRF   FSR
    CLRF   INDF

    clrf DIGIT0
    clrf DIGIT1
    clrf DIGIT2
    clrf DIGIT3
    clrf DIGIT4
    clrf DIGIT5
    clrf DIGIT6
    clrf DIGIT7
    clrf cycles     
    movlw 08     
    movwf octcnt 
octloop:          
    incf cycles  
    movlw 03        
    movwf bitcnt
bitloop:
    rlf BIN0
    rlf BIN1
    rlf BIN2
    movlw DIGIT0
    movwf FSR
    movfw cycles 
    movwf deccnt
decloop:
    rlf INDF
    movlw 0xF6
    addwf INDF,0
    btfsc STATUS,0
    movwf INDF
    incf FSR
    decfsz deccnt
    goto decloop
    decfsz bitcnt
    goto bitloop
    decfsz octcnt 
    goto octloop 
    return

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужно это число пребразовать в 8 разрядов десятичного числа представленных unsigned char переменными DIGIT7...DIGIT0 (старший -> младший байт числа)

Если программной памяти много, применяют sprintf()

Если же памяти мало, ищите реализации нестандартной функции ltoa()

Также есть оптимальный не очевидный алгоритм через упакованный BCD формат, поищите по слову bin2bcd

 

Возможно использовать только переменные unsigned char т.к. это для восьмиразрядного микроконтроллера.

Вам выдали специальный вариант компилятора Си, поддерживающего только unsigned char ? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо! Работает. Вопрос решен.

 

чой-та коробит от такого. Может лучше так ?!

 

char *dest = digit;
u32 div = 1000000000UL,  tmp;

while( div )
{
    tmp = (u8)( value / div);
    in_num -= tmp * div;
    div /= 10;
    *dest++ = '0' + tmp;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если я правильно понял задачу. Из двоичного получить BCD.

Ф-ии реализовывывал сам, "наразвес". Давно. Метод не помню как называется, кажется в термине присутствует "даббл дубл" или похоже.

Исходные ссылки брал в Wiki. - линк внизу поста.

Работает быстро, за счет чисто двоичной математики.

 

ps int == 16-разрядный

 

SUPPORT.C

#include  "support.h"

// unsigned int bin2BCD( unsigned int in_word ) { return bin2BCD( (unsigned char ) in_word ); }

// unsigned int bin2BCD( int in_word ) { return bin2BCD( (unsigned char ) in_word ); }
char bin2BCD( int in_word )
{
     static unsigned char arr[2]; // результат
     unsigned char *c_ptr = (unsigned char *) &in_word;

     memset( arr, 0x00, sizeof(arr));
     bin8_to_bcd( arr, c_ptr[0] );
     return arr[0];
}

// преобразование из 8-битного двоичного arg_bin8 в упакованный BCD - в массиве bcd3[2]
void bin8_to_bcd( unsigned char *bcd3, unsigned char arg_bin8 )
{
    unsigned long i_src;    // рабочий регистр
    unsigned char *arr;
    arr = (unsigned char *) &i_src;
    i_src = 0;

    arr[0] = arg_bin8;    // младший байт раб.регистра - исходное bin число

    unsigned char test1;
    for(int i=0; i<8; i++)
    {    i_src = i_src << 1;
        if( i >= 7 ) break;
        test1 =  arr[1] & 0x0F;            if( test1 >= 5 ) add_3( &arr[1], B_LOW );
        test1 = (arr[1] >> 4 ) & 0x0F;    if( test1 >= 5 ) add_3( &arr[1], B_HI );
        test1 =  arr[2] & 0x0F;            if( test1 >= 5 ) add_3( &arr[2], B_LOW );
        test1 = (arr[2] >> 4 ) & 0x0F;    if( test1 >= 5 ) add_3( &arr[2], B_HI );
        test1 =  arr[3] & 0x0F;            if( test1 >= 5 ) add_3( &arr[3], B_LOW );
        test1 = (arr[3] >> 4 ) & 0x0F;    if( test1 >= 5 ) add_3( &arr[3], B_HI );
    }

    bcd3[1] = arr[2];    // старший разряд BCD
    bcd3[0] = arr[1];    // 2 младших разряда BCD

}


// вспомогательная ф-я прибавки 3 к тетраде (без переноса)
// обрабатывается байт по c_ptr, sw1 - указывает какя тетрада обрабатывается B_LOW / B_HI
void add_3( unsigned char *c_ptr, int sw1 )
{
    unsigned char ch1, ch2;
    ch2 = *c_ptr;
    if( sw1 == B_LOW )    // младшая тетрада в ch1
    {    ch1 = *c_ptr & 0x0F;            
        ch1 += 3;
        *c_ptr = ( ch2 & 0xF0 ) | ( ch1 & 0x0F );
    }
    else            // старшая тетрада в ch1
    {    ch1 = *c_ptr & 0xF0;            
        ch1 += 0x30;
        *c_ptr = ( ch1 & 0xF0 ) | ( ch2 & 0x0F );
    }

}

 

SUPPORT_H

#ifndef SUPPORT_H
#define SUPPORT_H
#include  <string.h>
. . . .
// Вспомогательные ф-ии

// переключатель террад
#define B_HI    1
#define B_LOW    2

// вспомогательная ф-я прибавки 3 к тетраде (без переноса)
// второй параметр - переключатель тертрады B_HI / B_LOW
void add_3( unsigned char *, int );     

// ф-я конвертации из bin в упакованный BCD
// ( вызывает add_3() )
void bin8_to_bcd( unsigned char *, unsigned char); 

// ф-я конвертации из bin в упакованный BCD
// ( вызывает bin8_to_bcd() )
//  unsigned int si1 = bin2BCD( 123 );
//  (si1) == 0x0123
//unsigned int bin2BCD( unsigned char );
//unsigned int bin2BCD( unsigned int ); 
char bin2BCD( int ); 
#endif

 

Wiki Double_dabble

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На PIC16 я делал так

    digit[0] = 0;
    while(value >= 1 )
    {
        value -= 1;
        ++digit[0];
    }
}

А последнюю цифру(разряд единиц) зачем крутить?

digit[0] = value

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1)пока исходое число не равно нулю

2)записать в выходной буфер остаток от деления исходного числа на 10

3)поделить исходное число на 10.

 

Нельзя так над человеком издеваться :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...