← 所有文章

有號與無號混用時如何驗證比較結果

· 站長

從原始位元、符號邊界與擴展規則,驗證有號無號混用造成的比較與告警錯誤。

先看位元再決定數值

監看畫面出現65535,另一個畫面卻顯示−1,不一定是通訊讀錯;同樣十六個位元可以依不同型別解讀。本篇帶你從原始十六進位值開始,確認有號性、比較門檻與轉型順序,找出數值看似合理但告警判斷相反的原因。

十六位元無號整數的範圍是0到65535;採二補數的十六位元有號整數是−32768到32767。位元寬度和有號性必須同時寫進資料字典,不能只寫整數。本文以二補數為明示假設,不由變數名稱或畫面負號推定外部設備型別。

Modbus暫存器傳送十六位元資料,但單一回覆不會自動告訴接收端這是溫度、旗標、有號值還是無號累計。先查產品資料表的欄位型別、有效範圍、倍率和保留碼;若文件缺少這些資訊,就先保留raw,不能憑常見做法決定。

對普通數值欄位,先取得無號位元樣式U。若規格是有號二補數,U小於32768時值為U,否則值為U−65536。這個數學解碼式讓你不靠特定PLC語法也能驗算;真正實作時仍需確認平台的運算型別,不讓減法先在無號窄型別中回捲。

保留raw_hex、欄位型別、解碼值、單位和規則版本,顯示格式另列。HMI把某欄設成有號顯示,不會自動改變PLC中比較指令的語意。應沿著來源、通訊映射、PLC計算、HMI顯示逐層核對,而不是只修最後一個畫面。

用四個邊界值檢查比較

先測0x0000與0x7FFF。兩者依有號或無號解讀,都是0與32767,單靠這些資料無法發現型別混用。接著測0x8000:無號是32768,有號是32768−65536=−32768,這一筆正好跨過符號邊界。

再測0xFFFF:無號是65535,有號是−1。假設告警條件是值大於1000,無號解讀會成立,有號解讀不成立。這不是大於運算本身有問題,而是比較前的數值意義不同;驗收表要同時寫出型別與預期布林結果。

對採有號契約的溫度,若0xFFFF代表−1個最小刻度,接收端卻把它當65535再乘倍率,就可能造成虛假的高溫警報。排查時先查看原始word,再查有號轉換,最後才看倍率;不要為消除警報把高限臨時改到不合理的大值。

比較的另一端也需要型別。若資料值為有號−1、門檻存在無號三十二位元變數中,混合運算的提升規則取決於語言與指令。本文不指定通用結果,建議先把雙方轉到能表示全部允許範圍的共同型別,並在隔離測試中驗證。

例如已明確解碼的有號十六位元−1與數學整數100,若共同使用足夠寬的有號型別,相加是99,比較−1>100為假。若要處理完整無號三十二位元範圍,普通有號三十二位元不足以容納全部值,不能為了統一型別而引入另一個溢位。

擴展位寬與無效碼分開處理

把有號十六位元−1擴成有號三十二位元時,符號擴展得到0xFFFFFFFF,數值仍是−1。把無號十六位元65535擴成三十二位元時,補零得到0x0000FFFF,仍是65535。兩種操作保留的是不同數值,不可只看原始兩個byte相同就任選。

0x8000的符號擴展是0xFFFF8000,數值−32768;補零擴展是0x00008000,數值32768。若先補零再把完整三十二位元解讀成有號,仍會得到正32768;原本十六位元的負數意義已經沒有被保留。

反向縮小位寬也要檢查。三十二位元的40000不在有號十六位元範圍內;只保留低十六位再按有號解讀會變−25536。這可以用來示範錯誤,不能當成正常轉型方案。輸出前先判定範圍,依規格拒絕或採明示飽和政策。

無效碼先依資料契約辨識。若某產品明訂FFFF表示感測器斷線,就不能把它當合法−1或65535。若另一產品允許全部無號範圍且另有狀態欄,FFFF可能是合法最大值。相同位元樣式的意思必須由欄位契約決定,沒有通用故障碼。

品質與值也不要混淆。資料無效時,應使供控制使用的新值資格失效;畫面是否保留最後有效數字,另依用途設計並附過期標記。不能把Bad或逾時替換成數值零,因為零可能是合法的壓力、位置或計數。

也要查常數的寫法。十六進位常數FFFF在不同語言或指令中可能依上下文採不同寬度,不能由字面猜它就是有號負一。先在指定工具查常數型別與指令運算規則,再把相同位元樣式、有號值及門檻結果放在同一份驗收紀錄。

按資料路徑找錯並完成驗收

用一個明示測試介面輸入0000、7FFF、8000、FFFF,逐筆核對每一層的raw與解碼值。若通訊raw已錯,先查位址、byte排列與封包解析;若raw相同而數值不同,查有號性與位寬;若數值相同而比較不同,再查門檻、指令與隱式轉型。

批量讀取並不表示整批共用同一型別。例如第一個word可能是無號狀態位元,第二個才是有號溫度。建立逐欄映射,禁止用一個全區塊有號選項取代產品規格;位元遮罩欄位也不應先當溫度套倍率。

完成後應看到一張邊界表,能清楚列出0000為零、7FFF為32767、8000依型別分成32768或−32768、FFFF依型別分成65535或−1。每列再附門檻1000的比較結果,讓維護者可獨立重算,而不是只看到一個通過標記。

加入負值到零、最大值到超界、無效碼及品質失效測試。跨語言傳送時明訂欄位寬度與有號性;若用文字格式,保留負號與解析規則,不能在某層先轉無號再送出一串大正數。資料契約變更要同步更新接收端和驗收資料。

本篇為通用型別教學,適用於人工核對PLC、HMI與通訊資料。Q系列具體比較、轉換與中間結果寬度,要查對應CPU及所用指令手冊。

常見問題

問:FFFF為什麼有時是−1?答:在十六位元二補數有號解讀下是−1,無號解讀則是65535,還要排除產品保留碼。

問:小正數測試都正確就能交付嗎?答:還要測8000與FFFF等符號邊界,否則有號性錯誤可能一直被隱藏。

問:把所有資料轉成三十二位元就會正常嗎?答:還要選對符號或補零擴展,寬度增加本身不會修正錯誤解讀。

問:HMI顯示負數代表PLC也用有號比較嗎?答:不能推論,顯示設定與PLC比較指令需分別確認。

參考:Modbus Application Protocol V1.1b3,第4.2節資料編碼;產品型別需另查資料表。

延伸閱讀


使用 PLC 工具箱 →