關(guān)注+星標(biāo)公眾號,不錯過精彩內(nèi)容
來源 | 瑞薩嵌入式小百科
1
學(xué)習(xí)Modbus的快速方法
1.1?寄存器速記
作為初學(xué)者,你閱讀Modbus協(xié)議時會發(fā)現(xiàn)它的概念別扭、重復(fù)、不易區(qū)分,比如線圈狀態(tài)(Coil Status)、離散輸入狀態(tài)(Discrete Input Status)、保持寄存器(Holding Register)、輸入寄存器(Input Register)。
回到事情的本質(zhì),在工業(yè)控制PLC領(lǐng)域,涉及數(shù)字信號的輸入、輸出,模擬信號的輸入、輸出,如下圖所示:

對于軟件開發(fā)而言:
①想得到按鍵輸入狀態(tài)時,讀取到的是一位數(shù)據(jù)。
②想控制LED時,需要輸出一位數(shù)據(jù),想讀取LED當(dāng)前狀態(tài)時,也可以讀取到一位數(shù)據(jù)。
③想讀取模擬信號時,讀取到的是多位數(shù)據(jù),比如16位數(shù)據(jù)。
④想輸出模擬信號時,寫入的是多位數(shù)據(jù),比如16位數(shù)據(jù);也可以讀取“模擬量輸出”的當(dāng)前值。
在上圖中,“數(shù)字量輸入DI”是只讀的,“數(shù)字量輸出DO”是可讀可寫的,“模擬量輸入AI”是只讀的,“模擬量輸出AO”是可讀可寫的。
上圖里的“模擬量輸入AI”、“模擬量輸出AO”都表示“多位數(shù)值”,這些“多位數(shù)值”無需局限于只表示“模擬量”,也可以表示“多位數(shù)字量”。把AI、AO的含義擴(kuò)展后,如下圖所示:

對于軟件開發(fā)而言:
①想得到按鍵輸入狀態(tài)時,讀取到的是一位數(shù)據(jù)。
②想控制LED時,需要輸出一位數(shù)據(jù),想讀取LED當(dāng)前狀態(tài)時,也可以讀取到一位數(shù)據(jù)。
③想讀取參數(shù)時,讀取到的“輸入寄存器”,得到多位數(shù)據(jù),比如16位數(shù)據(jù)。
④想設(shè)置參數(shù)時,寫的是“保存寄存器”,寫入的是多位數(shù)據(jù),比如16位數(shù)據(jù);也可以讀“保存寄存器”。
在電子系統(tǒng)里,無論是單bit的數(shù)值、多bit的數(shù)值,都是保存在寄存器里。根據(jù)上圖,這些寄存器可以分為4類:
寄存器種類 | 說明 | 與PLC類比 | 舉例說明 |
線圈狀態(tài) (Coil?Status) | 輸出端口。可設(shè)定端口輸出狀態(tài),也可以讀取該位的輸出狀態(tài)。可分為兩種不同的執(zhí)行狀態(tài),例如保持型或邊沿觸發(fā)型。 | DO (數(shù)字量 輸出) | 電磁閥輸出、 MOSFEF輸出、LED顯示等 |
離散輸入狀態(tài) (Discrete?Input Status) | 輸入端口。通過外部設(shè)定改變輸入狀態(tài),可讀但不可以寫。 | DI (數(shù)字量 輸入) | 撥碼開關(guān)、接近開關(guān)等 |
保持寄存器(Holding Register) | 輸出參數(shù)或保持參數(shù),控制器運行時被設(shè)定的某些參數(shù),可讀可寫。 | AO (模擬量 輸出) | 模擬量輸出設(shè)定值,PID運行參數(shù),變量閥輸出大小,傳感器報警上限下限 |
輸入寄存器(Input Register) | 輸入?yún)?shù)。控制器運行時從外部設(shè)備獲得的參數(shù),但可讀不可寫。 | AI (模擬量 輸入) | 模擬量輸入 |
在Modbus中,多位操作時都是16位(2bytes)的,總結(jié)如下:
①bit操作涉及的寄存器有2類:線圈狀態(tài)(可讀可寫)、離散輸入狀態(tài)(只讀)。
②16bit操作的寄存器有2類:保存寄存器(可讀可寫)、輸入寄存器(只讀)。
?
一個設(shè)備里,可能有多個“線圈狀態(tài)”、多個“離散輸入狀態(tài)”、多個“保存寄存器”、多個“輸入寄存器”。怎么分辨某類寄存器中的某一個?它們有“寄存器地址”,如下圖所示:
寄存器種類 | PLC寄存器 地址范圍 | Modbus寄存器 地址范圍 | 簡稱 | 讀寫 狀態(tài) |
線圈狀態(tài) | 00001~09999 | 0000H~FFFFH | 0x | 可讀可寫 |
離散輸入狀態(tài) | 10001~19999 | 0000H~FFFFH | 1x | 只讀 |
保持寄存器 | 40001~49999 | 0000H~FFFFH | 4x | 可讀可寫 |
輸入寄存器 | 30001~39999 | 0000H~FFFFH | 3x | 只讀 |
在上表中,“線圈狀態(tài)”的寄存器N、“離散輸入狀態(tài)”的寄存器N,是兩個不同的寄存器。
?
簡單記憶方法:
①偶數(shù)類的寄存器”是可讀可寫的,比如“0x”和“4x”。
②“奇數(shù)類的寄存器”是只讀的,比如“1x”和“3x”。
③“0x”和“1x”是bit寄存器。
④“3x”和“4x”是16bit寄存器。
1.2?協(xié)議速記
Modbus是一主多從的協(xié)議,如下圖所示:

主控發(fā)出的數(shù)據(jù)里,必定含有如下信息:
①設(shè)備地址:你要訪問從設(shè)備1,還是訪問從設(shè)備2。
②訪問哪類寄存器,是讀還是寫,只訪問1個寄存器,還是多個寄存器:這被稱為功能碼。
③起始寄存器地址、寄存器數(shù)量:這在數(shù)據(jù)里定義。
④為了保證數(shù)據(jù)傳輸?shù)目煽浚€附帶有CRC檢驗碼。
?
以Modbus RTU協(xié)議為例,主控發(fā)出的數(shù)據(jù)包格式如下:

功能代碼有哪些?常用的功能碼如下:
①讀線圈狀態(tài)(01)
②讀離散輸入狀態(tài)(02)
③寫單個線圈(05)、寫多個線圈(15)
④讀保持寄存器(03)
⑤讀輸入寄存器(04)
⑥寫單個保存寄存器(06)、寫多個保存寄存器(16)
?
數(shù)據(jù)的格式,由功能代碼確定。以“讀線圈狀態(tài)”為例,主控發(fā)出的請求、從設(shè)備返回的響應(yīng)包,或者從設(shè)備返回的錯誤包,格式如下:

上圖中,寄存器起始地址(“Starting Address”)是16位的,先傳輸高字節(jié),再傳輸?shù)妥止?jié)。線圈數(shù)量(“Quantiti of coils”)也是16位的,先傳輸高字節(jié),再傳輸?shù)妥止?jié)。
響應(yīng)包回復(fù)多少個數(shù)據(jù)呢(上圖中N為多少)?N= Quantiti of coils / 8,如果余數(shù)不等于0,則N再加1。比如Quantiti of coils=9,則返回2個字節(jié)。
?
在《Modbus_Application_Protocol_V1_1b3.pdf》中, 列出了如下功能表。根據(jù)次表,在結(jié)合《5.5 Moubus功能碼詳解》的示例,就可以對Modbus RTU協(xié)議有很好的理解了。

------------?END?------------

MPU使用GCC編譯的過程

單片機(jī)和PHY芯片連接時的注意事項

瑞薩RA8系列教程 | RA8輸出PWM實現(xiàn)方法