2016年5月16日 星期一

[PLC基礎篇]2進制、10進制、BCD碼、ASCII碼轉換

💡 2026 年更新註記:本文原發表於 2014 年。為提供更好的閱讀體驗,已全面優化排版、加入高低位元轉換表格,並更新自適應(RWD)圖文與教學影片。

PLC 通訊必學:二進制、10進制、BCD碼與 ASCII 轉換完整教學

最近遇到不少人問:「PLC 裡面的數值,到底要怎麼轉成 10 進制?」
這個問題大多發生在處理「設備通訊」的時候,因為要把設備的數值透過 RS-232 / RS-485 傳送出去,通常必須轉換成 ASCII 碼。

在開始寫程式之前,我們先來複習一下 2 進制、10 進制、16 進制與 BCD 碼之間的轉換對應表:

進制轉換對應表

一、 基礎觀念:PLC 內部是如何儲存數值的?

在 PLC 內部的暫存器(Data Register),其實都是以「位元(Bit)」為單位在儲存的。所以,1 個 WORD(字組)的暫存器,其實是由 16 個位元(2 進制) 所組成。而這 16 個位元,剛好等於 4 個 16 進制的位數。

問題來了:給你 16 個位元,要怎麼表示成 10 進制?

  • 給 3 個位元,只能存 0~7。
  • 給 4 個位元,能存 0~15(但如果是 10 進制,10~15 的空間就被浪費了)。
⚠️ 為什麼找不到 16 進制轉 10 進制的指令?
因為「用 4 個位元,硬性規定只存 0~9(當作 10 進制)的儲存方式」,在 PLC 裡面就叫做 BCD 碼 (Binary-Coded Decimal)
這就是為什麼你在手冊裡找不到「轉 10 進制」的指令,因為你需要找的是「轉 BCD」指令!(註:浮點數轉換除外)

註:不管是人機介面(HMI)或是 PLC 編輯軟體,畫面上看到的 10 進制都是軟體「自動換算顯示」給你看的,並非真實的儲存狀態。平常純粹寫內部邏輯時,其實不太需要用到進制轉換。


二、 實戰教學:如何把 D 暫存器的值轉成 ASCII 碼?

這才是本篇的重頭戲!當你要把數值透過通訊丟出去時,標準流程分為兩大步驟:
先將 D 暫存器轉成 BCD 碼 ➔ 再把 BCD 碼轉成 ASCII 碼。

步驟 1:使用 BCD 指令

PLC BCD指令說明

指令格式:BCD S D

  • S (來源): 來源 BIN 值(範圍 0~9999)
  • D (目的): 變換結果存放處

為什麼來源限制是 0~9999?
因為每個 10 進制的位數轉換後會佔用 4 個位元。4 個位數(9999)剛好佔滿 16 個位元,等於 1 個 D 暫存器的極限。如果數值超過 9999,就會佔用到第 2 個暫存器,這時就必須改用 32 位元的 DBCD 指令

步驟 2:使用 ASCI 指令

PLC ASCI指令說明

指令格式:ASCI S D n

  • S (來源): 包含 Hex (16進制/BCD) 的來源暫存器
  • D (目的): 轉換成 ASCII 後存放的目的地
  • n (位數): 要轉換的位數

三、 ASCI 轉換後的高低位元存放規則(新手最容易卡關)

因為 ASCII 碼的範圍是 0~127,只需要佔用 8 個位元 (1 Byte)。但 PLC 的一個 D 暫存器是 16 個位元 (1 Word)。也就是說,一個 D 暫存器可以塞進 2 個 ASCII 字元

我們用原廠手冊的範例來說明轉換後「擺放位置」的邏輯:
假設指令為:ASCI D10 D20 K4(將 D10 轉 4 個 ASCII 放到 D20 開始的位置)
假設 D10 內容為:0123H

ASCI 高低位元範例

轉換排列原則:
來源 (D10) 會從最高位數開始讀取,並優先塞進目的暫存器 (D20, D21) 的 高 8 位元 (High Byte),接著再塞入 低 8 位元 (Low Byte)

來源資料 (D10) 目的暫存器 目的位元區間 轉換結果 (ASCII)
數值 0 D20 高 8 位元 (High Byte) '0' 的 ASCII 碼
數值 1 低 8 位元 (Low Byte) '1' 的 ASCII 碼
數值 2 D21 高 8 位元 (High Byte) '2' 的 ASCII 碼
數值 3 低 8 位元 (Low Byte) '3' 的 ASCII 碼

如果是 ASCI D10 D20 K3 呢?
指令只要求轉 3 個位數(抓取 123H):

  • D20 高 8 位元:放 1 的 ASCII
  • D20 低 8 位元:放 2 的 ASCII
  • D21 高 8 位元:放 3 的 ASCII
  • D21 低 8 位元:不變動(保留原狀態)

四、 實作示範影片

如果文字看不太懂,可以直接參考下方的實際操作影片:

1 則留言:

  1. 陳大好 關於暫存區的數值一事想請教
    關於使用豐煒PLC_VS_ENET模組 設定
    IP:192.168.16.29 PORT:502
    模組:Multi-Server
    Modbus PORT:502 SN-1不勾選
    通訊速率:19200
    ----------------------------------
    專案下的CP2通訊阜 設定
    類型:VS Computer link slave
    速率:19200
    站號:0
    ----------------------------------
    使用Modbus Poll_
    Connection 設定
    模式:Modbus TCP/IP
    IP:192.168.16.29 PORT:502
    Slave ID:0
    Function:03 Read Holding Registers(4x)
    Adress mode:Dec
    Adress 7000 plc address:47001

    使用Modbus poll可直接在欄位中修改數值寫入PLC暫存區
    但為何無法成功抓取到D7000的數值顯示,不曉得設定哪出了錯?希望可請你解惑,謝謝

    回覆刪除