RTT-筆記-freeModbus組件

1 獲取組件代碼

2 導(dǎo)入

通過(guò)env導(dǎo)入將自動(dòng)添加文件错敢,組件代碼在RTT\components\net\freemodbus\modbus目錄下,可以直接使用斑司,而通過(guò)git下載的代碼需要手動(dòng)加入怯疤,首先進(jìn)入FreeModbus_Slave-Master-RTT-STM32-1.1\FreeModbus目錄却盘,modbus文件夾是協(xié)議相關(guān)文件,port文件夾是移植相關(guān)文件。還需要在rtconfig中添加配置

#define RT_USING_MODBUS
#define RT_MODBUS_MASTER_RTU  //這里使用的是RTU

3 移植

目前使用stm32f103鉴竭,無(wú)需移植晤愧,之后更新補(bǔ)充該章節(jié)

3.1定時(shí)器

不同波特率定時(shí)時(shí)間計(jì)算:
1.freemodbus一幀的結(jié)束是通過(guò)串口3.5位傳輸?shù)臅r(shí)間來(lái)判斷的,當(dāng)串口的波特率大于19200時(shí)超時(shí)時(shí)間是固定為1750us大莫,當(dāng)串口通信的波特率小于等于19200時(shí),就有一個(gè)計(jì)算公式官份,用來(lái)計(jì)算超時(shí)時(shí)間只厘。
2.串口可以設(shè)置成以下模式
起始位1bit + 數(shù)據(jù)位8bit + 停止位1bit
起始位1bit + 數(shù)據(jù)位8bit + 停止位2bit
起始位1bit + 數(shù)據(jù)位8bit + 校驗(yàn)位1bit + 停止位1bit
起始位1bit + 數(shù)據(jù)位8bit + 校驗(yàn)位1bit + 停止位2bit
位數(shù)10 11 12 烙丛,取中間值11
3.5位時(shí)間的計(jì)算:1位傳輸時(shí)間是 1/BaudRate(s),1字節(jié)就是 11* 1/BaudRate(s) 羔味,定時(shí)器溢出時(shí)間3.511 1/BaudRate(s)河咽,轉(zhuǎn)成整數(shù)運(yùn)算711 1/BaudRate2(s)
定時(shí)配置是50us計(jì)一次數(shù),假設(shè)為X次赋元,則得出計(jì)算公式50
X(us) = 711 1/BaudRate2(s)忘蟹,推出X = 7220000UL/BaudRate 2,將X設(shè)置到定時(shí)器的計(jì)數(shù)值搁凸,將定時(shí)器配置成50us計(jì)數(shù)一次,x50us就會(huì)溢出中斷媚值。

這里說(shuō)明一下在定時(shí)器初始化中超時(shí)時(shí)間計(jì)算的代碼

(50 * usT35TimeOut50us) / (1000 * 1000 / RT_TICK_PER_SECOND) + 1

其中usT35TimeOut50us變量由函數(shù)傳入,是由波特率計(jì)算出的超時(shí)時(shí)間护糖,單位是us褥芒,轉(zhuǎn)化成ms,除以1000嫡良,然后再轉(zhuǎn)化成街拍數(shù)锰扶,乘上 RT_TICK_PER_SECOND/1000,最后的+1是為了至少大于超時(shí)時(shí)間寝受,因?yàn)榍懊孓D(zhuǎn)化小數(shù)被去掉了的坷牛。
這里要注意一下是,如果RT_TICK_PER_SECOND最好是調(diào)高一些很澄,例程中給的是10000京闰。

4 使用

4.1 運(yùn)行協(xié)議棧

需要建立一個(gè)線程,下列例子是參考的例程代碼

#define thread_ModbusMasterPoll_Prio         9
static rt_uint8_t thread_ModbusMasterPoll_stack[512];
struct rt_thread thread_ModbusMasterPoll;

void thread_entry_ModbusMasterPoll(void* parameter)
{
    eMBMasterInit(MB_RTU, 3, 115200,  MB_PAR_EVEN);
    eMBMasterEnable();
    while (1)
    {
        eMBMasterPoll();
        rt_thread_delay(1);
    }
}

int main()
{
        rt_thread_init(&thread_ModbusMasterPoll, "MBMasterPoll",
            thread_entry_ModbusMasterPoll, RT_NULL, thread_ModbusMasterPoll_stack,
            sizeof(thread_ModbusMasterPoll_stack), thread_ModbusMasterPoll_Prio,5);
        rt_thread_startup(&thread_ModbusMasterPoll);
}

4.2 讀寫

4.2.1 freemodebus功能字說(shuō)明

image.png

4.2.2 讀寫API

函數(shù)均返回eMBMasterReqErrCode 類型數(shù)據(jù)甩苛,當(dāng)返回值等于MB_MRE_NO_ERR時(shí)則表示操作失敗

功能 保持寄存器API函數(shù)
單寫 eMBMasterReqWriteHoldingRegister( 從機(jī)地址忙干,寄存器地址,無(wú)符號(hào)16位數(shù)據(jù)浪藻,超時(shí)時(shí)間);
多寫 eMBMasterReqWriteMultipleHoldingRegister(從機(jī)地址捐迫,寄存器地址,寫寄存器數(shù)爱葵,數(shù)據(jù)首地址施戴,超時(shí)時(shí)間)
多讀 eMBMasterReqReadHoldingRegister(從機(jī)地址,寄存器地址萌丈,讀取數(shù)量赞哗,超時(shí)時(shí)間)
讀寫 eMBMasterReqReadWriteMultipleHoldingRegister(從機(jī)地址,讀寄存器地址辆雾,讀寄存器數(shù)量肪笋,寫數(shù)據(jù)首地址,寫寄存器地址,寫寄存器數(shù)量藤乙,超時(shí)時(shí)間)
功能 輸入寄存器API函數(shù)
多讀 eMBMasterReqReadInputRegister(從機(jī)地址猜揪,讀寄存器地址,讀寄存器數(shù)量坛梁,超時(shí)時(shí)間)
功能 線圈API函數(shù)
單寫 eMBMasterReqWriteCoil(從機(jī)地址而姐,寫線圈地址,寫線圈數(shù)量划咐,超時(shí)時(shí)間)
多寫 eMBMasterReqWriteMultipleCoils(從機(jī)地址拴念,寫線圈起始地址,寫線圈數(shù)量褐缠,寫數(shù)據(jù)首地址政鼠,超時(shí)時(shí)間)
多讀 eMBMasterReqReadCoils(從機(jī)地址,讀線圈地址队魏,讀線圈數(shù)量缔俄,超時(shí)時(shí)間)
功能 離散輸入API函數(shù)
多讀 eMBMasterReqReadDiscreteInputs(從機(jī)地址,讀離散輸入地址器躏,讀離散輸入數(shù)量,超時(shí)時(shí)間)

例如

//執(zhí)行
if(MB_MRE_NO_ERR == eMBMasterReqReadHoldingRegister(1,3,1,1))
//則串口輸出 01 03 00 03 00 01 74 0A 

函數(shù)的超時(shí)時(shí)間是等待發(fā)送的時(shí)間蟹略,并不是發(fā)送完成等待應(yīng)答的時(shí)間登失,單位是毫秒

4.2.3 讀數(shù)據(jù)存儲(chǔ)

由user_mb_app_m.c和user_mb_app.c來(lái)管理,數(shù)據(jù)被分類保存在數(shù)組中挖炬。

從機(jī)默認(rèn)使用 一維數(shù)組 作為緩存區(qū)數(shù)據(jù)結(jié)構(gòu)揽浙,主機(jī)可以存儲(chǔ)所有網(wǎng)內(nèi)從機(jī)的數(shù)據(jù),所以主機(jī)采用 二維數(shù)組 對(duì)所有從機(jī)節(jié)點(diǎn)數(shù)據(jù)進(jìn)行存儲(chǔ)意敛。二維數(shù)組的列號(hào)代表寄存器馅巷、線圈及離散量地址,行號(hào)代表從機(jī)節(jié)點(diǎn)ID草姻,但需要做減一處理钓猬,例如usMRegHoldBuf[2][1]代表從機(jī)ID為 3,保持寄存器地址為 1 的從機(jī)數(shù)據(jù)撩独。
文件中的函數(shù)是協(xié)議內(nèi)部使用敞曹,并不是用來(lái)讀buffer的,也就如果需要讀buffer數(shù)據(jù)综膀,可以先這么處理:
讀從機(jī)地址為1.寄存器地址為3的數(shù)據(jù)

extern USHORT   usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS];
rt_kprintf("Receive success  reg %d",usMRegHoldBuf[0][3]);

4.3 使用例程

//main.c
#include <rtthread.h>
#include "user_mb_app.h"


#define thread_ModbusMasterPoll_Prio         9
#define thread_MDtest_Prio                       10

static rt_uint8_t thread_ModbusMasterPoll_stack[512];
static rt_uint8_t thread_MDtest_stack[512];

struct rt_thread thread_ModbusMasterPoll;
struct rt_thread thread_MDtest;


void thread_entry_ModbusMasterPoll(void* parameter)
{
    eMBMasterInit(MB_RTU, 3, 115200,  MB_PAR_EVEN);
    eMBMasterEnable();
    while (1)
    {
        eMBMasterPoll();
        rt_thread_delay(1);
    }
}



USHORT  usModbusUserData[10]={1,2,3,4,5,6,7,8,9,0};
UCHAR temp[2];

void mbMasterThreadEntry(void * para)
{
      rt_thread_mdelay(5000);
    while (1)
    {
       // if(MB_MRE_NO_ERR == eMBMasterReqReadInputRegister(1, 3, 2, 1)) //這里的超時(shí)時(shí)等待獲取信號(hào)量的時(shí)間 01 04 00 03 00 02 81 CB 
             // if(MB_MRE_NO_ERR == eMBMasterReqWriteHoldingRegister(1,3,usModbusUserData[0],1)) // 01 06 00 03 00 01 B8 0A 
              if(MB_MRE_NO_ERR == eMBMasterReqReadHoldingRegister(1,3,1,1))
        {               
                        //eMBMasterRegHoldingCB(temp,3,1,MB_REG_READ);
                        //rt_kprintf("Receive success  reg 3= %d\n",((uint16_t)temp[0])<<8 + temp[1]    );
                        extern USHORT   usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS];
                        rt_kprintf("Receive success  reg %d",usMRegHoldBuf[0][3]);                      
        }
        else
        {
            rt_kprintf(" poll failed\n");
        }
        rt_thread_mdelay(10000);
                 
    }

}


int main(void)
{
    /* user app entry */
        rt_thread_init(&thread_ModbusMasterPoll, "MBMasterPoll",
            thread_entry_ModbusMasterPoll, RT_NULL, thread_ModbusMasterPoll_stack,
            sizeof(thread_ModbusMasterPoll_stack), thread_ModbusMasterPoll_Prio,5);
        rt_thread_startup(&thread_ModbusMasterPoll);
    
        rt_thread_init(&thread_MDtest, "MBtest",
            mbMasterThreadEntry, RT_NULL, thread_MDtest_stack,
            sizeof(thread_MDtest_stack), thread_MDtest_Prio,5);
        rt_thread_startup(&thread_MDtest);

            
    return 0;
}

5 參考

https://blog.csdn.net/weixin_42867108/article/details/82227635
https://github.com/armink/FreeModbus_Slave-Master-RTT-STM32
https://blog.csdn.net/byxdaz/article/details/77979114

6 附件

度盤(nfjc)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末澳迫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子剧劝,更是在濱河造成了極大的恐慌橄登,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異拢锹,居然都是意外死亡谣妻,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門面褐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)拌禾,“玉大人,你說(shuō)我怎么就攤上這事展哭∨惹希” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵匪傍,是天一觀的道長(zhǎng)您市。 經(jīng)常有香客問(wèn)我,道長(zhǎng)役衡,這世上最難降的妖魔是什么茵休? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮手蝎,結(jié)果婚禮上榕莺,老公的妹妹穿的比我還像新娘。我一直安慰自己棵介,他們只是感情好钉鸯,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著邮辽,像睡著了一般唠雕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吨述,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天岩睁,我揣著相機(jī)與錄音,去河邊找鬼揣云。 笑死捕儒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的邓夕。 我是一名探鬼主播肋层,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼翎迁!你這毒婦竟也來(lái)了栋猖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤汪榔,失蹤者是張志新(化名)和其女友劉穎蒲拉,沒(méi)想到半個(gè)月后肃拜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡雌团,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年燃领,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锦援。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡猛蔽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出灵寺,到底是詐尸還是另有隱情曼库,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布略板,位于F島的核電站毁枯,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏叮称。R本人自食惡果不足惜种玛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瓤檐。 院中可真熱鬧赂韵,春花似錦、人聲如沸挠蛉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)碌秸。三九已至,卻和暖如春悄窃,著一層夾襖步出監(jiān)牢的瞬間讥电,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工轧抗, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恩敌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓横媚,卻偏偏與公主長(zhǎng)得像纠炮,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子灯蝴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容