【C语言】BCD码、十进制互相转换

简介: 【C语言】BCD码、十进制互相转换

前言:

记录今天用15单片机写DS1302时钟芯片程序的时候遇到的问题

时间显示是这个样的 0 1 2 3 4 5 6 7 8 9 16

9之后突变成16了,没有数据10...11...

why?

172527d3ae0cf5ff5cd250de581c212a_5624de8f02dd4c4ab31e2a72f2a5e83f.png

读取DS1302时钟芯片的数据是BCD码,需要将BCD码转换成十进制显示

写入数据的时候需要十进制转BCD码

这BCD码,真让人头大

195f2db011c7a144541be32346b32977_d50d0000da14431085e83c51a4d3bcfa.gif


1. BCD码

主要学习什么是BCD码,以及二进制、八进制、十进制、十六进制之间的相互转换

BCD码就是以四位二进制数为一个单位来表示相应的十进制数,因此4位二进制数表示最大的十进制数9(1001),只取十六个数中的十个数。

如下图:

b514975e3e89bb9ae17d1af43d8c8f0f_2643094ec5ff4a2a9ff14290fd7e6575.png

最后一列是BCD码的十进制表示形式,将BCD码按8421法相加即得出最后一栏的数值

图中可以看到0-9位 几个进制的BCD码都是以二进制的正常形式换算,从十开始的BCD码开始不一样了起来。

BCD码:用4位二进制数来表示1位十进制数。   逢九进一

例如:十进制数10的BCD码为0001 0000;

显而易见前四位的 0001 表示的是十进制的十位,0000则就是个位了。十六进制转BCD码也是同理。

例:0001 011(BCD码) 表示13(十进制), 1000 0101(BCD码) 表示85(十进制),0000 1010不合法


2. 算法原理

十进制是逢十进一,而十六进制是逢十六进一,它们之间的每次进位差,所以一个十进制数要转换成BCD码,要先算清多进位的位数,比如,十进制进位了次,每次进位和十六进制进位相比差,所以一共差了,即(BCD)。BCD码转化成十进制码也一样。

1. static uint8_t BCD2DEC(uint8_t bcd)  
2. {  
3.     return (bcd-(bcd>>4)*6);
4. }  
5. 
6. static uint8_t DEC2BCD(uint8_t dec)  
7. {  
8.     return (dec+(dec/10)*6);
9. }

这里不太懂……


3. 进制转换

3.1 两位BCD码的转换:

BCD码转十进制:DEC = BCD / 16 * 10  +  BCD % 16 ;

详解:先将BCD的前一位提出BCD/16,再提出BCD后一位BCD%16。最后将两位数整合转换成十进制。多位BCD码同理。

十进制转BCD码:BCD = DEC / 10 * 16 + DEC % 10 ;同上分别提出高低两位,做BCD转换。

实际应用举例

1. void DS1302_SetTime(void)
2. {
3.  DS1302_WriteByte(DS1302_WP, 0x00);//解除芯片写保护
4.  DS1302_WriteByte(DS1302_YEAR,   DS1302_Time[0]/10*16+DS1302_Time[0]%10);//十进制转BCD码
5.  DS1302_WriteByte(DS1302_MONTH,  DS1302_Time[1]/10*16+DS1302_Time[1]%10);  
6.  DS1302_WriteByte(DS1302_DATE,   DS1302_Time[2]/10*16+DS1302_Time[2]%10);
7.  DS1302_WriteByte(DS1302_HOUR,   DS1302_Time[3]/10*16+DS1302_Time[3]%10);
8.  DS1302_WriteByte(DS1302_MINTUE, DS1302_Time[4]/10*16+DS1302_Time[4]%10);
9.  DS1302_WriteByte(DS1302_SECOND, DS1302_Time[5]/10*16+DS1302_Time[5]%10);
10.   DS1302_WriteByte(DS1302_DAY,    DS1302_Time[6]/10*16+DS1302_Time[6]%10);  //星期
11.   DS1302_WriteByte(DS1302_WP, 0x80);//此句WP给0x80,打开芯片写保护
12. }
13. 
14. void DS1302_ReadTime(void) //此函数读取时钟芯片的数据,写到数组DS1302_Time里
15. {
16.   unsigned char Temp;
17.   Temp = DS1302_ReadByte(DS1302_YEAR);//读BCD码
18.   DS1302_Time[0] = Temp/16*10+Temp%16;  
19.   Temp = DS1302_ReadByte(DS1302_MONTH);//月
20.   DS1302_Time[1] = Temp/16*10+Temp%16;
21.   Temp = DS1302_ReadByte(DS1302_DATE);
22.   DS1302_Time[2] = Temp/16*10+Temp%16;
23.   Temp = DS1302_ReadByte(DS1302_HOUR);
24.   DS1302_Time[3] = Temp/16*10+Temp%16;
25.   Temp = DS1302_ReadByte(DS1302_MINTUE);
26.   DS1302_Time[4] = Temp/16*10+Temp%16;
27.   Temp = DS1302_ReadByte(DS1302_SECOND);
28.   DS1302_Time[5] = Temp/16*10+Temp%16;
29.   Temp = DS1302_ReadByte(DS1302_DAY);
30.   DS1302_Time[6] = Temp/16*10+Temp%16;
31. }

3.2 其他进制转换

二进制 转 十进制

1110 = 1 * 2^3 + 1 * 2^2 + 1 * 2^1 + 0 * 2^0

八进制 转 十进制

36=  3 * 8^1 + 6 * 8^0  

十六进制转十进制

0110 = 0 * 16^3 + 1 * 16^2 + 1 * 16^1 + 0 * 16^0

十六进制转二进制转十进制

0x11 = 0001 0001 >>> 0 * 2^7 .... + 1 * 2^4 + 0 + 1 * 2^0

3.3 任意进制转二进制

1. //递归
2. void decToBin(int n)
3. {
4.     int a;
5.     a = n%2;
6.     n /= 2;
7.     if(n==0)
8.         ;
9.     else
10.         decToBin(n);
11.     cout<<a;

a4f665f16442a936ef81403c12d92dac_ab3741c3163e4575b7919078758ef132.gif

参考资料:

BCD码以及各进制之间的相互转换

C语言:十进制、BCD码互换

十进制与BCD码转换的算法


相关文章
|
6月前
|
存储 C语言
C语言实现二进制到十进制
C语言实现二进制到十进制
67 0
|
6月前
|
C语言
c语言点分十进制IP转整型
c语言点分十进制IP转整型
|
6月前
|
存储 C语言
C语言实现十进制转化为十六进制-------数组,switch语句,while循环语句
C语言实现十进制转化为十六进制-------数组,switch语句,while循环语句
105 0
|
C语言
C语言之将十进制整数转换为任意进制整数
C语言之将十进制整数转换为任意进制整数
233 0
|
C语言
C语言之十进制转化为十六进制
C语言之十进制转化为十六进制
151 0
C语言:十进制、BCD码互换
C语言:十进制、BCD码互换
C语言:十进制、BCD码互换
|
存储 C语言 C++
C语言之数据的存储2(浮点数在内存中如何存储,如何输出,查看不同类型数据在内存中表示的范围的方法,十进制浮点数转化为二进制的方法)
C语言之数据的存储2(浮点数在内存中如何存储,如何输出,查看不同类型数据在内存中表示的范围的方法,十进制浮点数转化为二进制的方法)
129 0
|
6月前
|
存储 C语言
十进制转二进制,C语言的必备技能
十进制转二进制,C语言的必备技能
|
6月前
|
存储 C语言
C语言十进制转二进制
C语言十进制转二进制
123 0
|
11月前
|
C语言
C 语言实例 - 八进制与十进制相互转换
C 语言实例 - 八进制与十进制相互转换
174 2