WhyCan Forum

本站无需注册,无需积分,无需回复可下载所有资料,如果真的喜欢小站,请您注册之后请至少回复一个帖子激活Id,谢谢支持! 站长QQ: 516333132 (挖坑网/填坑网) admin@whycan.cn

您尚未登录。

#1 2019-05-26 15:03:09

BugActive
会员
注册时间: 2017-10-17
累计积分: 2

超长字节bin与bcd转换

#include "stdint.h"
#include <stdio.h>

#define BIN_LEN 16 //统一长度 ,方便计算 ,但要注意BCD码溢出的问题 
#define BCD_LEN 16 // bcd码最大位数位 BCD_LEN*2,这里为32位

uint8_t bin_arry[BIN_LEN] = { 0 };
uint8_t bcd_arry[BCD_LEN] = { 0 };

void long_bin2bcd(uint8_t* p_bin, uint8_t* p_bcd)
{
    int16_t i;
    uint8_t carry_flag = 0;
    for(i = BIN_LEN * 8; i > 0; i--) {
        carry_flag = p_bin[BIN_LEN - 1] & 0X80 ? 1 : 0;
        for(int8_t j = BIN_LEN - 1; j >= 0; j--) {
            p_bcd[j] <<= 1;
            p_bin[j] <<= 1;
            if(j > 0) {
                if(p_bcd[j - 1] & 0x80) {
                    p_bcd[j] |= 0x01;
                }
                if(p_bin[j - 1] & 0x80) {
                    p_bin[j] |= 0x01;
                }
            }
        }
        p_bcd[0] |= carry_flag;

        if(i > 1) {
            for(int8_t j = 0; j < BIN_LEN; j++) {
                if((p_bcd[j] + 0x03) & 0x08) {
                    p_bcd[j] += 0x03;
                }
                if((p_bcd[j] + 0x30) & 0x80) {
                    p_bcd[j] += 0x30;
                }
            }
        }
    }
    printf("BCD = 0d:");
    for(i = BCD_LEN - 1; i >= 0; i--) {
        printf("%02x", p_bcd[i]);
    }
    printf("\r\n");
}

void long_bcd2bin(uint8_t* p_bin, uint8_t* p_bcd)
{
    int16_t i;
    for(i = BCD_LEN * 8 - 1; i > 0; i--) {
        if(i < BCD_LEN * 8 - 1) {
            for(int8_t j = 0; j < BCD_LEN; j++) {
                if(p_bcd[j] & 0x08) {
                    p_bcd[j] -= 0x03;
                }
                if(p_bcd[j] & 0x80) {
                    p_bcd[j] -= 0x30;
                }
            }
        }

        if(p_bcd[0] & 0x01) {
            p_bin[BCD_LEN - 1] |= 0x80;
        }
        for(int8_t j = 0; j < BCD_LEN; j++) {
            p_bin[j] >>= 1;
            p_bcd[j] >>= 1;
            if(j < BCD_LEN - 1) {
                if(p_bin[j + 1] & 0x01) {
                    p_bin[j] |= 0x80;
                }
                if(p_bcd[j + 1] & 0x01) {
                    p_bcd[j] |= 0x80;
                }
            }
        }
    }
    printf("BIN = 0x:");
    for(i = BIN_LEN - 1; i >= 0; i--) {
        printf("%02x", p_bin[i]);
    }
    printf("\r\n");
}

int main(int argc, char** argv)
{
    bcd_arry[0] = 0x11;
    bcd_arry[1] = 0x22;
    bcd_arry[2] = 0x33;
    bcd_arry[3] = 0x44;
    bcd_arry[4] = 0x55;
    bcd_arry[5] = 0x66;
    bcd_arry[6] = 0x77;
    bcd_arry[7] = 0x88;
    bcd_arry[8] = 0x99;
    bcd_arry[9] = 0x08; // BCD: 8998877665544332211
    long_bcd2bin(bin_arry, bcd_arry);
    for(uint8_t i = 0; i < BIN_LEN; i++) {
        bcd_arry[i] = 0;
    }
    long_bin2bcd(bin_arry, bcd_arry);
    for(uint8_t i = 0; i < BIN_LEN; i++) {
        bcd_arry[i] = bin_arry[i] = 0;
    }
    bin_arry[0] = 0xFF;
    bin_arry[1] = 0xEE;
    bin_arry[2] = 0x33;
    bin_arry[3] = 0x44;
    bin_arry[4] = 0x55;
    bin_arry[5] = 0x66;
    bin_arry[6] = 0x77;
    bin_arry[7] = 0x88;
    bin_arry[8] = 0x99;
    bin_arry[9] = 0x08; // BIN: 0X89988766554433EEFF
    long_bin2bcd(bin_arry, bcd_arry);
    for(uint8_t i = 0; i < BIN_LEN; i++) {
        bin_arry[i] = 0;
    }
    long_bcd2bin(bin_arry, bcd_arry);

    for(uint8_t i = 0; i < BIN_LEN; i++) {
        bcd_arry[i] = bin_arry[i] = 0;
    }
    bin_arry[0] = 0x11;
    bin_arry[1] = 0x22;
    bin_arry[2] = 0x33;
    bin_arry[3] = 0x44;
    bin_arry[4] = 0x55;
    bin_arry[5] = 0x66;
    bin_arry[6] = 0x77;
    bin_arry[7] = 0xAA;
    bin_arry[8] = 0xBB;
    bin_arry[9] = 0xCC;
    bin_arry[10] = 0xDD;
    bin_arry[11] = 0xEE;
    bin_arry[12] = 0xFF; // BIN: 0xFFEEDDCCBBAA77665544332211
    long_bin2bcd(bin_arry, bcd_arry);
    for(uint8_t i = 0; i < BIN_LEN; i++) {
        bin_arry[i] = 0;
    }
    long_bcd2bin(bin_arry, bcd_arry);
    
    return 0;
}

离线

#2 2019-05-26 15:53:33

BugActive
会员
注册时间: 2017-10-17
累计积分: 2

Re: 超长字节bin与bcd转换

#include "stdint.h"
#include <stdio.h>

#define NUMBER_TYPE uint32_t //最大32it BCD码,即最大BCD码为 99999999


//Q格式数据拆分后分为整数部分和小数部分,整数部分右对齐,小数部分左对齐 
// _bin_integer为整数部分,_bin_fractional为小数部分
void bin2bcd(NUMBER_TYPE _bin_integer, NUMBER_TYPE _bin_fractional)
{
    int16_t i = 0;
    uint32_t var1, var2, var3, var4;

    var2 = _bin_integer;
    var4 = _bin_fractional; // bin小数部分
    var3 = 0;
    var1 = 0;
    for(i = (sizeof(NUMBER_TYPE) * 8); i > 0; i--) {
        var1 <<= 1;
        if(var2 & (0x01 << (sizeof(NUMBER_TYPE) * 8 - 1))) {
            var1 |= 1;
        }
        var2 <<= 1;

        var3 >>= 1;
        if(var4 & 0x01) {
            var3 |= (0x01 << (sizeof(NUMBER_TYPE) * 8 - 1));
        }
        var4 >>= 1;

        for(int8_t j = 0; j < (sizeof(NUMBER_TYPE) * 2); j++) {
            if(i > 1) {
                if((var1 + (0x03 << (j * 4))) & (0x08 << (j * 4))) {
                    var1 += (0x03 << (j * 4));
                }
            }
            if(var3 & (0x08 << (j * 4))) {
                    var3 -= (0x03 << (j * 4));
                }
        }
    }
    printf("in bin integer = %08d,\t out integer bcd = %08x ,\t in bin fractional = %08x,\t out fractional bcd = 0.%08x \r\n", _bin_integer,var1, _bin_fractional, var3);
}

void bcd2bin(uint32_t _bcd)
{
    uint16_t i = 0;
    uint32_t var1, var2;

    var1 = 0;
    var2 = _bcd;
    for(i = (sizeof(NUMBER_TYPE) * 8 - 1); i > 0; i--) {
        if(i < (sizeof(NUMBER_TYPE) * 8 - 1)) {
            for(int8_t j = 0; j < (sizeof(NUMBER_TYPE) * 2); j++) {

                if(var2 & (0x08 << (j * 4))) {
                    var2 -= (0x03 << (j * 4));
                }
            }
        }
        if(var2 & 0x01) {
            var1 |= (0x01 << (sizeof(NUMBER_TYPE) * 8 - 1));
        }
        var2 >>= 1;
        var1 >>= 1;
    }
    printf("in bcd = %08x, out bin = %08d \r\n", _bcd, var1);
}

int main(int argc, char** argv)
{
    bin2bcd(200, 200);
    bin2bcd(1024, 1024);
    bin2bcd(2048, 2048);
    bin2bcd(4095, 4096);
    bin2bcd(0x8000, 0x8000);
    bin2bcd(0x01000000, 0x01000000);
    bin2bcd(0x02000000, 0x02000000);
    bin2bcd(0x04000000, 0x04000000);
    bin2bcd(0x08000000, 0x08000000);
    bin2bcd(0x10000000, 0x10000000);
    bin2bcd(0x20000000, 0x20000000);
    bin2bcd(0x40000000, 0x40000000);
    bin2bcd(0x80000000, 0x80000000);
    
    bin2bcd(0x10000000, 0x88000000);
    bin2bcd(0x20000000, 0xC0000000);
    bin2bcd(0x40000000, 0xE0000000);
    bin2bcd(0x80000000, 0xF0000000);

    bcd2bin(0x8000);
    bcd2bin(0x5678);
    bcd2bin(0x9876);
    bcd2bin(0x99999999);
    return 0;
}

离线

#3 2019-05-26 16:01:22

晕哥
Administrator
注册时间: 2017-09-06
累计积分: 6,733

Re: 超长字节bin与bcd转换

感谢分享!

离线

页脚