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 指令
指令格式:BCD S D
- S (來源): 來源 BIN 值(範圍 0~9999)
- D (目的): 變換結果存放處
為什麼來源限制是 0~9999?
因為每個 10 進制的位數轉換後會佔用 4 個位元。4 個位數(9999)剛好佔滿 16 個位元,等於 1 個 D 暫存器的極限。如果數值超過 9999,就會佔用到第 2 個暫存器,這時就必須改用 32 位元的 DBCD 指令。
步驟 2:使用 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
轉換排列原則:
來源 (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 位元:不變動(保留原狀態)
四、 實作示範影片
如果文字看不太懂,可以直接參考下方的實際操作影片:
陳大好 關於暫存區的數值一事想請教
回覆刪除關於使用豐煒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的數值顯示,不曉得設定哪出了錯?希望可請你解惑,謝謝