以下作品由安信可社區(qū)用戶
http://ckdsx.cn制作
目錄
1.什么是Modbus, RS485?
1.2RS485,RS232兩種協(xié)議之間的主要區(qū)別
1.3Modbus的內(nèi)容是什么?
1.4幀結(jié)構(gòu)
1.5Modbus指令實(shí)例1.5.1
1.6 Modbus-RTU協(xié)議
2.外設(shè)介紹
2.1常用芯片選擇
2.2初始化過程
3.移植過程
3.1資料介紹
3.2示例參考程序代碼
使用wb2進(jìn)行 modbus 485 通訊演示_嗶哩嗶哩_bilibiliwww.bilibili.com/video/BV1Hapxe4EsV/?vd_source=54c5db21948db2378659b7e8e42bafbf
一、什么是Modbus, RS485 ?
Modbus就是一種用在工業(yè)上的簡(jiǎn)單協(xié)議!顧名思義,它是一個(gè)Bus,即總線協(xié)議。比如串口協(xié)議、IIC協(xié)議、SPI都是通信協(xié)議。
RS485是一種通用的通信標(biāo)準(zhǔn),廣泛用于數(shù)據(jù)采集和控制應(yīng)用中。它的主要優(yōu)點(diǎn)之一是它允許將多個(gè) RS485設(shè)備放在同一條總線上,這使得多個(gè)節(jié)點(diǎn)可以相互連接。
RS-485(目前稱為EIA/TIA-485)是通信物理層的標(biāo)準(zhǔn)接口,一種信號(hào)傳輸方式,OSI(開放系統(tǒng)互連)模型的第一級(jí)。創(chuàng)建 RS-485是為了擴(kuò)展RS-232接口的物理功能。
串行EIA-485連接是使用兩根或三根電線的電纜完成的:一根數(shù)據(jù)線、一根帶反轉(zhuǎn)數(shù)據(jù)的電線,通常還有一根零線(接地,0V)。這樣,發(fā)射器和接收器通過22或24AWG 實(shí)心線的雙絞線電纜交換數(shù)據(jù)。
01、RS485 VS RS232
RS485和RS232串行通信協(xié)議已經(jīng)使用了50多年,并且仍在整個(gè)商業(yè)和工業(yè)中廣泛使用。擴(kuò)展RS232標(biāo)準(zhǔn)的功能是開發(fā)RS485協(xié)議的動(dòng)力。下表概述了這兩個(gè)標(biāo)準(zhǔn)。
02、RS485,RS232兩種協(xié)議之間的主要區(qū)別
發(fā)射器和接收器的數(shù)量
RS232串行接口設(shè)計(jì)用于連接兩個(gè)設(shè)備。該協(xié)議支持單個(gè)發(fā)射器和接收器之間的通信。 RS485接口,最多可以將32個(gè)串行設(shè)備連接到一個(gè)變送器。
操作距離
使用RS232協(xié)議的設(shè)備在發(fā)送器和接收器之間的距離限制為15米,同時(shí)仍能實(shí)現(xiàn)最大數(shù)據(jù)傳輸速率。如果可以容忍較慢的數(shù)據(jù)速率,則可以延長(zhǎng)此長(zhǎng)度。 RS485協(xié)議大大延長(zhǎng)了操作距離。它支持1200米長(zhǎng)度的最大數(shù)據(jù)速率,使RS485協(xié)議成為物理上相距遙遠(yuǎn)的設(shè)備之間通信的絕佳選擇。
數(shù)據(jù)傳輸速度
RS232接口的傳輸速度為1Mb/s,傳輸距離可達(dá)15米。RS485在15米的距離內(nèi)提供高達(dá)10Mb/s的更高速度。當(dāng)達(dá)到1200米的最大長(zhǎng)度時(shí),RS485協(xié)議以100Kb/s的速度傳輸數(shù)據(jù)。
電氣噪聲問題和接地電位
RS232接口是一種基于電壓電平的系統(tǒng),在接地電位差異最小的情況下性能最佳。表現(xiàn)出高水平電噪聲和可變接地電位的環(huán)境會(huì)影響RS232有效傳輸數(shù)據(jù)的能力,并可能導(dǎo)致數(shù)據(jù)丟失或損壞。
RS485協(xié)議采用差分電壓系統(tǒng),使其能夠在具有較高電噪聲水平的環(huán)境中有效運(yùn)行。差分電壓系統(tǒng)的一個(gè)副產(chǎn)品是數(shù)據(jù)傳輸距離的延長(zhǎng)、傳輸速度的提高以及RS485所見的更低電壓的使用。
03、Modbus的內(nèi)容是什么?
Modbus-RTU,Modbus-ASCII,Modbus-TCP以上三種協(xié)議,一個(gè)設(shè)備只會(huì)有一種協(xié)議,如果你的設(shè)備使用的是Modbus-RTU,只需查看以下對(duì)應(yīng)部分,一般來說大部分的設(shè)備都是Modbus-RTU協(xié)議的。
04、幀結(jié)構(gòu)
地址
占用一個(gè)字節(jié),范圍0-255,其中有效范圍是1-247,其他有特殊用途,比如255是廣播地址(廣播地址就是應(yīng)答所有地址,正常的需要兩個(gè)設(shè)備的地址一樣才能進(jìn)行查詢和回復(fù))。
功能碼
占用一個(gè)字節(jié),功能碼的意義就是,知道這個(gè)指令是干啥的,比如你可以查詢從機(jī)的數(shù)據(jù),也可以修改數(shù)據(jù),所以不同功能碼對(duì)應(yīng)不同功能。
數(shù)據(jù)
根據(jù)功能碼不同,有不同結(jié)構(gòu),在下面的實(shí)例中有說明。
校驗(yàn)
為了保證數(shù)據(jù)不錯(cuò)誤,增加這個(gè),然后再把前面的數(shù)據(jù)進(jìn)行計(jì)算看數(shù)據(jù)是否一致,如果一致,就說明這幀數(shù)據(jù)是正確的,我再回復(fù);如果不一樣,說明你這個(gè)數(shù)據(jù)在傳輸?shù)臅r(shí)候出了問題,數(shù)據(jù)不對(duì)的,所以就拋棄了。
這是一個(gè)基于ModbusRTU協(xié)議的Ai-WB2modbus庫(kù),它支持以下幾種modbus協(xié)議命令:
*0x01: 讀一個(gè)或多個(gè)線圈寄存器
*0x02: 讀一個(gè)或多個(gè)離散輸入寄存器
*0x03: 讀一個(gè)或多個(gè)保持寄存器
*0x04: 讀一個(gè)或多個(gè)輸入寄存器
*0x05: 寫單個(gè)線圈寄存器
*0x06: 寫單個(gè)保持寄存器
*0x0F: 寫多個(gè)線圈寄存器
*0x10: 寫多個(gè)保持寄存器
05、Modbus指令實(shí)例
查詢從機(jī)地址為01的數(shù)據(jù)
主機(jī)發(fā)送:01 03 00 00 00 01 84 0A
從機(jī)回復(fù):01 03 02 19 98 B2 7E
發(fā)送數(shù)據(jù)解析
回復(fù)數(shù)據(jù)解析
查詢數(shù)據(jù)基本流程就是:
發(fā)送:從機(jī)的地址+要干嘛的功能碼+要查的寄存器的地址+要查的寄存器地址的個(gè)數(shù)+校驗(yàn)碼
回復(fù):從機(jī)的地址+主機(jī)發(fā)我的功能碼+要發(fā)送給主機(jī)數(shù)據(jù)的字節(jié)數(shù)+數(shù)據(jù)+校驗(yàn)碼
修改從機(jī)地址為01的數(shù)據(jù)
主機(jī)發(fā)送:01 06 00 00 00 01 48 0A
從機(jī)回復(fù):01 06 00 00 00 01 48 0A
發(fā)送數(shù)據(jù)解析
回復(fù)數(shù)據(jù)解析
06、Modbus-RTU協(xié)議
只需要看懂功能碼0x03、0x06、0x10這三個(gè)基本的就已經(jīng)足夠了,分別回想下其數(shù)據(jù)域部分:
0x03—主機(jī)需要發(fā)送起始地址+寄存器數(shù)量,從機(jī)回復(fù)總字節(jié)數(shù)+數(shù)據(jù);
0x06—主機(jī)發(fā)送起始地址+數(shù)據(jù)內(nèi)容(因?yàn)槟阒恍枰薷囊粋€(gè),所以起始地址就是所要修改的地址),從機(jī)返回起始地址+數(shù)據(jù)內(nèi)容(發(fā)現(xiàn)居然一樣?。?br />
0x10—主機(jī)發(fā)送起始地址+寄存器個(gè)數(shù)+總字節(jié)數(shù)+數(shù)據(jù),從機(jī)返回起始地址+寄存器數(shù)量
二、外設(shè)介紹
RS485轉(zhuǎn)TTL模塊
RS485遠(yuǎn)程I/O聯(lián)網(wǎng)模塊IODO控制器modbus
3.3V與5.0V電源、信號(hào)兼容的RS485自動(dòng)流向控制模塊無需“收—發(fā)”控制,使用本模塊跟操作串口一樣簡(jiǎn)單,透?jìng)髂K實(shí)現(xiàn)了TTL信號(hào)與RS485信號(hào)的互轉(zhuǎn),但大家一定要知道,485是半雙工通信,這種通信方式可以實(shí)現(xiàn)雙向的通信,但不能在兩個(gè)方向上同時(shí)進(jìn)行,必須輪流交替地進(jìn)行;也就是說,通信信道的每一端都可以是發(fā)送端,也可以是接收端,但同一時(shí)刻里,信息只能有一個(gè)傳輸方向。
波特率:支持110~128000bps
模塊亮點(diǎn):
(1)供電范圍寬:3.3V~5.5V。
(2)3.3V與5.0V信號(hào)兼容。
(3)采用原裝進(jìn)口芯片,工業(yè)級(jí)設(shè)計(jì),抗干擾能力強(qiáng),同時(shí)采用更為有效的485防雷設(shè)計(jì),可在工業(yè)現(xiàn)場(chǎng)及野外惡劣的環(huán)境下使用,工作溫度為—40℃至+85℃,傳輸距離可達(dá)千米(用的850米的2*1.5的線纜做的測(cè)試,建議在800米內(nèi)使用,超過800米請(qǐng)加中繼器)。
(4)采用半孔工藝設(shè)計(jì),板厚0.8mm,可輕松作為子母板使用,也可焊接端子使用。
(5)具有RXD、TXD信號(hào)指示燈,收發(fā)狀況盡收眼底。
模塊特點(diǎn):
(1)本模塊充分考慮了485總線防雷設(shè)計(jì)和抗干擾設(shè)計(jì),在野外長(zhǎng)距離傳輸時(shí),將模塊的“接大地”端接入大地,可以起到很好的抗干擾和防雷的作用,使485總線更安全;室內(nèi)短距離傳輸時(shí)可以不接入大地。
(2)采用標(biāo)準(zhǔn)的2.54間距設(shè)計(jì),方便您的二次開發(fā)。
(3)具有120歐匹配電阻,短接RO即可使能匹配電阻,長(zhǎng)距離傳輸時(shí)建議短接。
(4)支持多機(jī)通訊,允許接在最多128個(gè)設(shè)備的總線上
(5)本模塊可以進(jìn)行熱插拔,不會(huì)出現(xiàn)其他485芯片熱插拔出現(xiàn)的信號(hào)栓死現(xiàn)象。
(6)大面積鋪銅,防止信號(hào)干擾。
01、常用芯片選擇
SN75176
SN75276
SN75179
SN75180
MAX485
MAX488
MAX490
02、初始化過程
引入頭文件
#include
#include
#include
#include
#include
#include"bl_sys.h"
#include
#include"softcrc.h"
#include"stdint.h"
#include"string.h"
設(shè)置初始化參數(shù)
波特率:默認(rèn)串口配置為9600波特率,8位數(shù)據(jù)位,無校驗(yàn)位,1位停止位。
hosal_uart_dev_tuart_dev_log = {
.config= {
.uart_id= 1,
.tx_pin= 16, // TXD GPIO
.rx_pin= 7, // RXD GPIO
.cts_pin= 255,
.rts_pin= 255,
.baud_rate= 115200,
.data_width= HOSAL_DATA_WIDTH_8BIT,
.parity= HOSAL_NO_PARITY,
.stop_bits= HOSAL_STOP_BITS_1,
.mode= HOSAL_UART_MODE_POLL,
},
};
hosal_uart_init(&uart_dev_log);
配置用到的引腳
默認(rèn)使用串口引腳:硬件串口
使用板載引腳4個(gè):TX,RX,3.3V,GND(接線方法見模塊說明書或下圖) RS485引腳:A+連接A+,B-連接B-,數(shù)據(jù)有干擾的情況下GND接地。
三、移植過程
01、資料介紹
地址和命令可以直接以16進(jìn)制的方式寫到數(shù)組里,CRC16校驗(yàn)需要計(jì)算或查表獲得;
參考網(wǎng)上CRC教程,使用本地CRC庫(kù)文件二次封裝完成CRC校驗(yàn)及校驗(yàn)值追加與打印函數(shù)(有關(guān)更多CRC計(jì)算請(qǐng)參考網(wǎng)上教程);
由于手頭方便的僅有modubusRS485遠(yuǎn)程控制IO模塊,僅以此模塊完成命令發(fā)送控制其輸出繼電器開關(guān)的例程。
電路連線圖
Ai-WB2 => 串口TTL=> MAX485 => A,B雙絞線=>RS485設(shè)備
注:AI-WB2與模塊之間連線時(shí),RX連接RX,TX連接TX。請(qǐng)根據(jù)模塊說明自行調(diào)整接線!
02、示例參考程序代碼
RS485發(fā)送示例代碼如下:
----------------------
#include
intcounter = 0;voidsetup() {
RS485.begin(9600);}
voidloop() {
RS485.beginTransmission();
RS485.print("hello");
RS485.println(counter);
RS485.endTransmission();
counter++;
delay(1000);
}
-------------------------------
RS485接收并串口打印示例代碼如下:
-----------------------------------
#include
voidsetup() {
Serial.begin(9600); while(!Serial);
RS485.begin(9600);
//enable reception, can be //disabled with: RS485.noReceive();
RS485.receive();}
voidloop() {
if(RS485.available()) {
Serial.write(RS485.read()); }}
--------------------------------
注:通過串口助手直接輸出指令,有可能因?yàn)椴皇鞘M(jìn)制,或指令尾部被增加回車換行(0D0A)而導(dǎo)致失??!
程序運(yùn)行過程:wb2通過串口向RS485轉(zhuǎn)TTL模塊發(fā)送指令,遠(yuǎn)程IO模塊通過Modbus端口A、B接收數(shù)據(jù)并解析,然后執(zhí)行指令動(dòng)作。
程序運(yùn)行現(xiàn)象:RS485轉(zhuǎn)TTL模塊,TX指示燈每隔兩秒點(diǎn)了一下,遠(yuǎn)程IO模塊輸出端口1234順序開啟,然后順序關(guān)閉。
若無硬件,則可以使用串口助手觀察命令發(fā)送情況,請(qǐng)注意勾選HEX顯示。(見下圖)
程序代碼見原貼中的附件
【外設(shè)移植】Ai-WB2+Modbus 485 RTU 遠(yuǎn)程控制。程序太過簡(jiǎn)單,未制作成庫(kù)文件,各位可直接修改使用,make相關(guān)內(nèi)容同helloworld文件一樣。
https://bbs.aithinker.com/forum.php?mod=viewthread&tid=45244&_dsign=2c20ee00
PS:感謝園長(zhǎng)、銀、狗哥、杰哥、妖哥等各位安信可技術(shù)社區(qū)的大佬熱情幫助!
審核編輯 黃宇
-
遠(yuǎn)程控制
+關(guān)注
關(guān)注
4文章
632瀏覽量
34928 -
RTU
+關(guān)注
關(guān)注
0文章
413瀏覽量
28679
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論