Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Преобразование двоичного в двоично-десятичный код
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
_alex__
Имеетя 24-х разрядное двоичное число представленное в виде трех однобайтных (unsigned char) переменных
BYTE2,BYTE1,BYTE0 (старший -> младший байт числа)

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

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

Помогите написать на языке С функцию для такого преобразования.
Сергей Борщ
QUOTE (_alex__ @ Mar 22 2018, 22:14) *
Возможно использовать только переменные unsigned char т.к. это для восьмиразрядного микроконтроллера.
Глупость вы тут написали. Как только вы это поймете, задача сведется к трем строчками кода.

1)пока исходое число не равно нулю
2)записать в выходной буфер остаток от деления исходного числа на 10
3)поделить исходное число на 10.
Mareng
Придется искать 24-разрядный микроконтроллер, иначе никак!)
mcheb
На PIC16 я делал так
CODE
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];
}
}
_alex__
Цитата(Mareng @ Mar 23 2018, 01:28) *
Придется искать 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
Baser
Цитата(_alex__ @ Mar 22 2018, 22:14) *
Нужно это число пребразовать в 8 разрядов десятичного числа представленных unsigned char переменными DIGIT7...DIGIT0 (старший -> младший байт числа)

Если программной памяти много, применяют sprintf()
Если же памяти мало, ищите реализации нестандартной функции ltoa()
Также есть оптимальный не очевидный алгоритм через упакованный BCD формат, поищите по слову bin2bcd

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

Вам выдали специальный вариант компилятора Си, поддерживающего только unsigned char ? sm.gif
_alex__
Цитата(mcheb @ Mar 23 2018, 04:58) *
На PIC16 я делал так


Спасибо! Работает. Вопрос решен.
megajohn
Цитата(_alex__ @ Mar 23 2018, 16:12) *
Спасибо! Работает. Вопрос решен.


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

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

while( div )
{
    tmp = (u8)( value / div);
    in_num -= tmp * div;
    div /= 10;
    *dest++ = '0' + tmp;
}
k155la3
Если я правильно понял задачу. Из двоичного получить 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
ae_
Цитата(mcheb @ Mar 23 2018, 13:58) *
На PIC16 я делал так
Код
    digit[0] = 0;
    while(value >= 1 )
    {
        value -= 1;
        ++digit[0];
    }
}

А последнюю цифру(разряд единиц) зачем крутить?
Код
digit[0] = value
Lagman
Цитата(Сергей Борщ @ Mar 23 2018, 02:31) *
1)пока исходое число не равно нулю
2)записать в выходной буфер остаток от деления исходного числа на 10
3)поделить исходное число на 10.


Нельзя так над человеком издеваться :-)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.