<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > FreeModbus 移植于STM32 實(shí)現Modbus RTU通信

FreeModbus 移植于STM32 實(shí)現Modbus RTU通信

作者: 時(shí)間:2016-12-03 來(lái)源:網(wǎng)絡(luò ) 收藏
畢業(yè)設計自己要做個(gè)基于STM32的PLC能直接跑語(yǔ)句表的,現在看來(lái)好像沒(méi)有什么創(chuàng )新的地方,不過(guò)實(shí)現的方式絕對夠創(chuàng )新的了...呵呵。自己寫(xiě)的開(kāi)題報告中說(shuō)了要有高級的通信功能?,F在做以太網(wǎng)有點(diǎn)來(lái)不及了,CAN又感覺(jué)不搭調,硬件上也沒(méi)準備。串口上跑Modbus感覺(jué)不錯。本來(lái)西門(mén)子的S7-200就能跑Modbus,STM32-PLC當然也要支持Modbus 什么 組態(tài)軟件,觸摸屏都可以連上,不過(guò)FreeModbus只支持從機有點(diǎn)可惜,當然本來(lái)協(xié)議也不難而且也必要實(shí)現全協(xié)議棧。

Modbus中文協(xié)議.PDF

本文引用地址:http://dyxdggzs.com/article/201612/325168.htm

STM32移植FreeModbus的步驟:

首先去http://www.freemodbus.org下載文件 一定要是官方可靠的才行,我起先為了圖方便網(wǎng)上隨便下載了一個(gè),結果白白浪費了一下午的時(shí)間

不知道是哪里被改動(dòng)了。目前最新的版本是1.5。

http://115.com/file/bee0jrth#freemodbus-v1.5.0.zip這是官方的可靠版本。

Demo 文件夾下都是官方移植好的其他芯片的版本。選BARE文件下的“赤裸”文件加入工程 同時(shí)添加全部的庫文件,可參考下圖

需要移植修改的在 port 目錄下
porttimer.c
中 xMBPortTimersInit( USHORT usTim1Timerout50us ) 負責配置一個(gè) 時(shí)基 ,vMBPortTimersEnable( ) 啟用這個(gè)時(shí)基。

比如執行

xMBPortTimersInit( 10000 );
vMBPortTimersEnable( );
for( ;; );
定時(shí)器按中斷內 便會(huì )每500MS調用一次pxMBPortCBTimerExpired( );同時(shí)你也要檢測vMBPortTimersDisable( ) 是否可以可靠的關(guān)閉定時(shí)器。用仿真器 用LED燈都行的.


portother.c

//負責一個(gè)串口的配置 為了省事我只支持了波特率的修改

xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )

vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )負責控制串口【收/發(fā)】中斷的禁止與使能

pxMBFrameCBByteReceived( ); //在串口接收中斷內調用 用于通訊偵測

pxMBFrameCBTransmitterEmpty( ); //在串口發(fā)送中斷內調用 用于告知完成了發(fā)送 發(fā)送緩沖為空

xMBPortSerialGetByte( CHAR * pucByte ) xMBPortSerialPutByte( CHAR ucByte ) 兩個(gè)為 串口字節的收發(fā)

port.h

中定義了 全局中斷的開(kāi)關(guān)

#define ENTER_CRITICAL_SECTION( )   __set_PRIMASK(1) /*關(guān)中中斷*/
#define EXIT_CRITICAL_SECTION( )    __set_PRIMASK(0) /*開(kāi)總中斷*/
__set_PRIMASK() 來(lái)源于 core_cm3.c 
這個(gè)頭文件中添加了#include  assert() 斷言宏 freeModbus的作者有點(diǎn)意思,為此不可以定義NDEBUG 。#include "stm32f10x.h" 似乎要添加到#include 的后邊 不然編譯會(huì )有問(wèn)題。
port.C
添加了些Modbus協(xié)議棧與寄存器的接口函數 這個(gè)也要自己寫(xiě)。
FreeModbus 通過(guò) eMBRegInputCB eMBRegHoldingCB eMBRegCoilsCBeMBRegDiscreteCB 四個(gè)接口函數完成數據的讀寫(xiě)操作
其中最常用的是這個(gè) eMBRegHoldingCB 為了方便測試可以構造usRegHoldingBuf[]這樣的一個(gè)數組進(jìn)行讀寫(xiě)調試。
上位機可以用諸如Modbus調試精靈這樣的軟件。
// 寄存器的讀寫(xiě)函數 支持的命令為讀 0x03 和寫(xiě)0x06
eMBErrorCodeeMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode ){ eMBErrorCode eStatus = MB_ENOERR; int iRegIndex;u16 *PRT=(u16*)pucRegBuffer;
 if( ( usAddress >= REG_HOLDING_START ) && ( usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS ) ) { iRegIndex = ( int )( usAddress - usRegHoldingStart ); switch ( eMode ) { case MB_REG_READ: while( usNRegs > 0 ) { *PRT++ = __REV16(usRegHoldingBuf[iRegIndex++]); //數據序轉 REV16.W
//   *pucRegBuffer++ = ( unsigned char )( usRegHoldingBuf[iRegIndex] >> 8 );// *pucRegBuffer++ = ( unsigned char )( usRegHoldingBuf[iRegIndex] & 0xFF );//  iRegIndex++; usNRegs--; } break;
 case MB_REG_WRITE: while( usNRegs > 0 ) { usRegHoldingBuf[iRegIndex++] = __REV16(*PRT++); //數據序轉 REV16.W
//  usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;// usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;// iRegIndex++; usNRegs--; } } } else { eStatus = MB_ENOREG; } return eStatus;}
受到freeModbus作者使用“assert()”的影響在這個(gè)里我用了__REV16()這個(gè)函數 
*PRT++ = __REV16(usRegHoldingBuf[iRegIndex++]);
這是Cortex—M3中的一個(gè)匯編指令REV16 功能是交換一個(gè)字的高位和地位位的兩個(gè)字節,若0x1234==__REV16(0x3412)。字節在*pucRegBuffer中的順序與串口發(fā)送的順序是一致的所以要有這么個(gè)轉換,當然用代碼中注釋掉的部分也能實(shí)現同樣的功能。這是用__REV16()看起來(lái)更“酷”一些。當然這樣編譯后的結果是大約減少4條指令,效率提升有限。
序轉指令不少 功能非常強大~!__REV16()來(lái)源于core_cm3.c
后邊只要想法將STM32_PLC 輸出的地址映射這個(gè)寄存器上邊可以了
整個(gè)移植沒(méi)有什么難度 只是看官方的英文API文檔 生詞太多,其實(shí)意思非常簡(jiǎn)單。而且剛開(kāi)始又用了來(lái)路不明的FreeModbus庫文件,不倫怎樣都不工作,浪費不少時(shí)間。全部工作前后總共花了兩天的時(shí)間。
我移植好的demo 注釋很全 應該可以輕易看懂。
DOWNLOAD:
FreeModbus_For_STM32.7z
115:
FreeModbus_For_STM32.7z


評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>