• 正文
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

啥是 BCD 碼?

2021/02/28
331
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

在使用RTC外設(shè)時(shí),我們常常會(huì)接觸 BCD碼的概念,同時(shí)魚(yú)鷹在介紹 USB 協(xié)議版本時(shí)也說(shuō)了 BCD 碼,那么什么是 BCD 碼?

BCD 碼分為多種,今天魚(yú)鷹介紹最常用的 8421  BCD碼。

進(jìn)制 高四位 低四位
BCD碼 4 5
十六進(jìn)制 4 5
十進(jìn)制 6 9

假如我們需要設(shè)置 RTC時(shí)鐘的秒值為 45 秒,因?yàn)橐话?a class="article-link" target="_blank" href="/tag/%E8%8A%AF%E7%89%87/">芯片會(huì)使用 BCD碼進(jìn)行存儲(chǔ),所以我們需要存儲(chǔ)到芯片寄存器的值就是 0x45,注意這是十六進(jìn)制表示,如果你寫(xiě)入寄存器時(shí)用十進(jìn)制表示,那么就是 69。代碼表示如下:

//假設(shè) REG_SEC 為秒寄存器 REG_SEC = 0x45;  // 十六進(jìn)制寫(xiě)入寄存器
REG_SEC = 69;  // 十進(jìn)制寫(xiě)入寄存器

不管你使用哪種方式,最終寫(xiě)入的二進(jìn)制都是一樣的,沒(méi)有任何區(qū)別。不過(guò)因?yàn)槭?BCD碼格式,當(dāng)寫(xiě)入的值為立即數(shù)時(shí),建議使用十六進(jìn)制,這樣看起來(lái)更直觀一些。

從這個(gè)例子中我們其實(shí)也可以看出一點(diǎn)規(guī)律,那就是所謂的 BCD 碼就是把十六進(jìn)制的寫(xiě)法直接認(rèn)為是十進(jìn)制的值。實(shí)際上也確實(shí)如此。BCD 碼中,使用4個(gè)位(二進(jìn)制位)來(lái)表示一個(gè)十進(jìn)制的值,范圍 0~9。也就是說(shuō),本來(lái)十六進(jìn)制 4 個(gè)位可以表示0~15,但因?yàn)槭M(jìn)制的范圍是 0~9,所以這四個(gè)位的范圍也因此被限制住了。同時(shí)在一個(gè)字節(jié)中,高四位代表十進(jìn)制的十位,低四位代表十進(jìn)制的個(gè)位。了解這一點(diǎn),你就知道該如何把十進(jìn)制轉(zhuǎn)化成BCD碼的形式進(jìn)行存儲(chǔ),又該如何將 BCD碼轉(zhuǎn)化為十進(jìn)制了。

還是以存儲(chǔ)秒寄存器(BCD碼存儲(chǔ))為例:

// BCD 碼 轉(zhuǎn) 十進(jìn)制#define BCD_TO_DECIMAL(x)   ((((x) & 0xf0) >> 4) * 10 + ((x) & 0x0f))
// 十進(jìn)制 轉(zhuǎn) BCD 碼#define DECIMAL_TO_BCD(x)   ((((x) / 10) << 4) + ((x) % 10))

// 以十進(jìn)制形式寫(xiě)入秒寄存器,最終將以 BCD 碼存儲(chǔ)REG_SEC = DECIMAL_TO_BCD(45); // 設(shè)置為 45 秒 
// 讀取秒寄存器中的 BCD 碼,并轉(zhuǎn)化為十進(jìn)制值,方便處理second = BCD_TO_DECIMAL(REG_SEC);

通過(guò)以上兩個(gè)宏,我們就可以在0 ~ 99 范圍內(nèi)隨意轉(zhuǎn)化,當(dāng)需要更大范圍時(shí),理解原理,修改起來(lái)也不就是那么麻煩了。

相關(guān)推薦

  • LAT1209 Arm?v7-M架構(gòu)的STM32如何啟用DWT進(jìn)行計(jì)數(shù)
  • LAT1202 TIM DMA burst 輸出變頻 PWM 波形
  • LAT1255 直接修改寄存器來(lái)輸出內(nèi)部時(shí)鐘的方法
  • LAT1356 如何降低BlueNRG-LPS的開(kāi)機(jī)峰值電流
  • 登錄即可解鎖
    • 海量技術(shù)文章
    • 設(shè)計(jì)資源下載
    • 產(chǎn)業(yè)鏈客戶資源
    • 寫(xiě)文章/發(fā)需求
    立即登錄