目录

0. 前言:

1. BCD码

2. 算法原理

3. 进制转换

3.1 两位BCD码的转换:

3.2 其他进制转换

3.3 任意进制转二进制

参考资料:

0. 前言:

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

时间显示是这个样的 0 1 2 3 4 5 6 7 8 9 16 9之后突变成16了,没有数据10...11...

why?

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

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

这BCD码,真让人头大

1. BCD码

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

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

如下图:

最后一列是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码转化成十进制码也一样。

static uint8_t BCD2DEC(uint8_t bcd)

{

return (bcd-(bcd>>4)*6);

}

static uint8_t DEC2BCD(uint8_t dec)

{

return (dec+(dec/10)*6);

}

这里不太懂……

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转换。

实际应用举例

void DS1302_SetTime(void)

{

DS1302_WriteByte(DS1302_WP, 0x00);//解除芯片写保护

DS1302_WriteByte(DS1302_YEAR, DS1302_Time[0]/10*16+DS1302_Time[0]%10);//十进制转BCD码

DS1302_WriteByte(DS1302_MONTH, DS1302_Time[1]/10*16+DS1302_Time[1]%10);

DS1302_WriteByte(DS1302_DATE, DS1302_Time[2]/10*16+DS1302_Time[2]%10);

DS1302_WriteByte(DS1302_HOUR, DS1302_Time[3]/10*16+DS1302_Time[3]%10);

DS1302_WriteByte(DS1302_MINTUE, DS1302_Time[4]/10*16+DS1302_Time[4]%10);

DS1302_WriteByte(DS1302_SECOND, DS1302_Time[5]/10*16+DS1302_Time[5]%10);

DS1302_WriteByte(DS1302_DAY, DS1302_Time[6]/10*16+DS1302_Time[6]%10); //星期

DS1302_WriteByte(DS1302_WP, 0x80);//此句WP给0x80,打开芯片写保护

}

void DS1302_ReadTime(void) //此函数读取时钟芯片的数据,写到数组DS1302_Time里

{

unsigned char Temp;

Temp = DS1302_ReadByte(DS1302_YEAR);//读BCD码

DS1302_Time[0] = Temp/16*10+Temp%16;

Temp = DS1302_ReadByte(DS1302_MONTH);//月

DS1302_Time[1] = Temp/16*10+Temp%16;

Temp = DS1302_ReadByte(DS1302_DATE);

DS1302_Time[2] = Temp/16*10+Temp%16;

Temp = DS1302_ReadByte(DS1302_HOUR);

DS1302_Time[3] = Temp/16*10+Temp%16;

Temp = DS1302_ReadByte(DS1302_MINTUE);

DS1302_Time[4] = Temp/16*10+Temp%16;

Temp = DS1302_ReadByte(DS1302_SECOND);

DS1302_Time[5] = Temp/16*10+Temp%16;

Temp = DS1302_ReadByte(DS1302_DAY);

DS1302_Time[6] = Temp/16*10+Temp%16;

}

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 任意进制转二进制

//递归

void decToBin(int n)

{

int a;

a = n%2;

n /= 2;

if(n==0)

;

else

decToBin(n);

cout<

参考资料:

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

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

十进制与BCD码转换的算法

查看原文