我正在为Arduino中的RTC模块编写一个库,其中数据存储在BCD中。我知道如何将十进制数转换为 BCD,但在以编程方式编写它时遇到一些问题。在网上搜索后,我得到了两个公式,如下所示,并且运行良好,但无法理解它是如何计算的。
1。公式1
DEC 至 BCD
(value / 10 * 16) + (value % 10)
示例
DEC -> 40,转换为 BCD 中的 01000000,再次等于 64。
因此,如果我代入公式,我会得到相同的结果。
(40/10 * 16) + (40%10)
= (4*16) + 0
= 64
BCD 至 DEC
(value / 16 * 10) + (value % 16)
2。公式2
DEC 至 BCD
val + 6 * (val / 10)
BCD 至 DEC
val - 6 * (val >> 4)
如果有人能详细解释一下,那将会很有帮助。
提前感谢大家。
正确的转换函数是:
byte bcdToDec(byte val)
{
return( (val/16*10) + (val%16) );
}
byte decToBcd(byte val)
{
return( (val/10*16) + (val%10) );
}
为什么这有效?让我们取一个数字 5。用二进制表示,它是
0101 = 5
现在让我们采用相同的数字,通过在右侧添加四个零来将其向左移动四位:
0101 0000 = 50 BCD
这就是 BCD 的工作原理。由于需要四个二进制数字来表示十进制数字 0 到 9,因此每个十进制数字都由四位表示。关键是 在二进制中移动四位会乘或除 16,所以这就是公式中
16
值的原因。
我们就拿 96 来说吧:
0110 = 6
1001 = 9
1001 0110 = 96 BCD
一些 16 位代码:
uint16_t decToBcd16(uint16_t val)
{
return((((val / 1000) % 10) << 12) | (((val / 100) % 10) << 8) | (((val / 10) % 10) << 4) | (val % 10));
}
uint16_t bcdToDec16(uint16_t val)
{
return(((((val & 0xf000) >> 12) % 10) * 1000) + ((((val & 0x0f00) >> 8) % 10) * 100) + ((((val & 0x00f0) >> 4) % 10) * 10) + ((val & 0x000f) % 10));
}
Maybe someone will need it,
//BIN -->BCD
#include "arduino.h"
unsigned long a =0;
unsigned long x=0;
unsigned long y=0;
unsigned long c=0;
unsigned long b=0;
int d=0;
int e=0;
byte f=0;
//=================================
void setup() {
Serial.begin (9600);
unsigned long start = micros();
unsigned long val =964827;
x=val;
if(x>100000){
a=x/100000;
x=x-(a*100000);
};
if(x>10000){
b=x/10000;
x=x-(b*10000);
};
if(x>1000){
c=x/1000;
x=x-(c*1000);
};
if(x>100){
d=x/100;
x=x-(d*100);
};
if(x>10){
e=x/10;
x=x-(e*10);
};
Serial.println (a,DEC);
Serial.println (b,DEC);
Serial.println (c,DEC);
Serial.println (d,DEC);
Serial.println (e,DEC);
Serial.println (x,DEC);
unsigned long end = micros();
unsigned long delta = end - start;
Serial.println(delta);
}
void loop() {
// put your main code here, to run repeatedly:
}