我今天看了一些代码,用于将实时时钟与arduino集成,并且它有一些二进制到十进制(反之亦然),我不完全理解。
有问题的代码如下:
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
ex: decToBcd(12);
我真的无法理解这是如何运作的。我不确定我是否理解数学,或者是否正在利用某种假设。
有人会介意解释下面的数学和数据类型应该如何工作吗?如果可能的话,触及为什么价值" 16"用于转换而不是" 8"当我们应该使用字节值时。
对于上下文,可以在此处找到完整代码:http://www.codingcolor.com/microcontrollers/an-arduino-lcd-clock-using-a-chronodot-rtc/
答案 0 :(得分:1)
此处的关键提示是BCD - Binary-coded decimal - 在函数名称中。在BCD中,每个十进制数字由四位(一半字节)表示。因此,您可以使用BCD表示法存储的最大(十进制)数字在高半字节(字节的一半)中为99 - 9,在低半字节中为9。 我们来看看12号作为例子。数字12在二进制表示法中如下所示:
12 = %00001010
然而,在BCD中,它看起来如下:
12 = %00010010
,因为
0001 0010
1 2
现在,如果您查看decToBcd
函数val%10
,则负责计算某个地方的值(即最后一位数)。由于这是在字节的下半部分,我们不需要在这里做任何特别的事情。 val/10*16
首先计算十位的值 - val/10
。然而,由于该值必须转到字节的上半部分,因此需要将其向上移位4位 - 因此*16
。另一种(在我看来更具可读性)编写这个函数的方法是:
((val / 10) << 4) | (val % 10)
bcdToDec
执行反向转换。
答案 1 :(得分:0)
RTC通常将1字节的年份存储为仅2位数,即:2014年为14。 其中一些将它存储为1970年的数字,因此2014年= 44。 因此,在两种情况下,它可以保持的最大值为99。