FreeModbus從站源碼解析(mbrtu.c)_第1頁(yè)
FreeModbus從站源碼解析(mbrtu.c)_第2頁(yè)
FreeModbus從站源碼解析(mbrtu.c)_第3頁(yè)
FreeModbus從站源碼解析(mbrtu.c)_第4頁(yè)
FreeModbus從站源碼解析(mbrtu.c)_第5頁(yè)
已閱讀5頁(yè),還剩1頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

FreeModbus從站源碼解析(mbrtu.c)mbrtu.c#include"stdlib.h"#include"string.h"#include"port.h"#include"mb.h"#include"mbrtu.h"#include"mbframe.h"#include"mbcrc.h"#include"mbport.h"#defineMB_SER_PDU_SIZE_MIN4/*ADU最?字節(jié)數(shù)*/#defineMB_SER_PDU_SIZE_MAX256/*ADU最?字節(jié)數(shù)*/#defineMB_SER_PDU_SIZE_CRC2/*2CRC校驗(yàn)碼*/字節(jié)#defineMB_SER_PDU_ADDR_OFF#defineMB_SER_PDU_PDU_OFF0/*從機(jī)ID偏移地址*/1/*PDU*/偏移地址typedefenum{STATE_RX_INIT,STATE_RX_IDLE,STATE_RX_RCV,STATE_RX_ERROR}eMBRcvState;/*接收器初始化狀態(tài)*//*接收器空閑狀態(tài)*//*接收器接收數(shù)據(jù)狀態(tài)*//*接收器錯(cuò)誤狀態(tài)*/typedefenum{STATE_TX_IDLE,STATE_TX_XMIT}eMBSndState;/*發(fā)送器空閑狀態(tài)*//*發(fā)送器發(fā)送數(shù)據(jù)狀態(tài)*/staticvolatileeMBSndStateeSndState;staticvolatileeMBRcvStateeRcvState;//發(fā)送狀態(tài)//接收狀態(tài)volatileUCHARucRTUBuf[MB_SER_PDU_SIZE_MAX];//Buffer數(shù)據(jù)staticvolatileUCHAR*pucSndBufferCur;staticvolatileUSHORTusSndBufferCount;//Buffer發(fā)送//Buffer發(fā)送索引staticvolatileUSHORTusRcvBufferPos;//Buffer接收索引/******************************************@Func:ModbusRTU模式初始化******************************************/eMBErrorCodeeMBRTUInit(UCHARucSlaveAddress,UCHARucPort,ULONGulBaudRate,eMBParityeParity){eMBErrorCodeULONGeStatus=MB_ENOERR;usTimerT35_50us;(void)ucSlaveAddress;ENTER_CRITICAL_SECTION();//串?初始化if(xMBPortSerialInit(ucPort,ulBaudRate,8,eParity)!=TRUE){eStatus=MB_EPORTERR;}else{/**波特率>19200定時(shí)器固定周期t3.5=1750us*否則t3.5必須是單個(gè)字符時(shí)間的3.5倍*/if(ulBaudRate>19200){usTimerT35_50us=35;//35*50=1750us}else{/*?個(gè)字節(jié)由11位組成:1起始位+8數(shù)據(jù)位+1奇偶校驗(yàn)位+1停?位*傳送?個(gè)字節(jié)所需要的時(shí)間:*ChTimeValue=(11*1000/BaudRate)ms*T3.5字符的時(shí)間就是(3.5ChTimeValue)ms*假設(shè)波特率19200,3.5ChTimeValue=2ms*usTimerT35_50us代表T3.5個(gè)字符,50us的倍數(shù)*2ms4050us,19200代?下?的公式剛好40是個(gè)將*/usTimerT35_50us=(7UL*220000UL)/(2UL*ulBaudRate);}//定時(shí)器初始化if(xMBPortTimersInit((USHORT)usTimerT35_50us)!=TRUE){eStatus=MB_EPORTERR;}}EXIT_CRITICAL_SECTION();returneStatus;}/******************************************@Func:Modbus協(xié)議啟動(dòng)******************************************/voideMBRTUStart(void){ENTER_CRITICAL_SECTION();/*初始化接收器STATE_RX_INIT狀態(tài).啟動(dòng)定時(shí)器,如果T3.5時(shí)間內(nèi)*未收到數(shù)據(jù)改為STATE_RX_IDLE.請(qǐng)確保延遲開(kāi)始協(xié)議通信直到協(xié)*就緒議*/eRcvState=STATE_RX_INIT;vMBPortSerialEnable(TRUE,FALSE);vMBPortTimersEnable();EXIT_CRITICAL_SECTION();}voideMBRTUStop(void){//禁?串?收發(fā)、停?定時(shí)器ENTER_CRITICAL_SECTION();vMBPortSerialEnable(FALSE,FALSE);vMBPortTimersDisable();EXIT_CRITICAL_SECTION();}/**************************************************************@Func:將串?收到的數(shù)據(jù)從ucRTUBuf提取給參數(shù)返回應(yīng)?層*@pucRcvAddress:保存從機(jī)地址*@pucRcvAddress:保存從機(jī)地址*@pucFrame:保存去除從機(jī)地址數(shù)據(jù)的幀數(shù)據(jù)功能碼+數(shù)據(jù)域+CRC)*@pusLength:功能碼+數(shù)據(jù)域長(zhǎng)度*************************************************************/(eMBErrorCodeeMBRTUReceive(UCHAR*pucRcvAddress,UCHAR**pucFrame,USHORT*pusLength){eMBErrorCodeeStatus=MB_ENOERR;ENTER_CRITICAL_SECTION();assert(usRcvBufferPos<MB_SER_PDU_SIZE_MAX);//CRC檢查幀長(zhǎng)度與if((usRcvBufferPos>=MB_SER_PDU_SIZE_MIN)&&(usMBCRC16((UCHAR*)ucRTUBuf,usRcvBufferPos)==0)){//從機(jī)地址賦值給pucRcvAddress*pucRcvAddress=ucRTUBuf[MB_SER_PDU_ADDR_OFF];/*Modbus-PDU長(zhǎng)度即有效數(shù)據(jù)長(zhǎng)度*從機(jī)地址1字節(jié)+CRC2字節(jié)不計(jì)算在內(nèi)*/*pusLength=(USHORT)(usRcvBufferPos-MB_SER_PDU_PDU_OFF-MB_SER_PDU_SIZE_CRC);//去掉了從機(jī)地址后幀數(shù)據(jù)*pucFrame=(UCHAR*)&ucRTUBuf[MB_SER_PDU_PDU_OFF];}else{eStatus=MB_EIO;}EXIT_CRITICAL_SECTION();returneStatus;}/******************************************@Func:發(fā)送數(shù)據(jù)*@ucSlaveAddress:從機(jī)地址*@pucFrame,ucRTUBuf:有效數(shù)據(jù)指針指向*@usLength:數(shù)據(jù)長(zhǎng)度*****************************************/eMBErrorCodeeMBRTUSend(UCHARucSlaveAddress,constUCHAR*pucFrame,USHORTusLength){eMBErrorCodeUSHORTeStatus=MB_ENOERR;usCRC16;ENTER_CRITICAL_SECTION();/*檢查接收器是否處于空閑狀態(tài)*/if(eRcvState==STATE_RX_IDLE){/*pucFrame指向的第?個(gè)字節(jié)是功能碼,pucFrame-1留出從機(jī)地址*/pucSndBufferCur=(UCHAR*)pucFrame-1;usSndBufferCount=1;/*將地址置于發(fā)送幀中*/pucSndBufferCur[MB_SER_PDU_ADDR_OFF]=ucSlaveAddress;usSndBufferCount+=usLength;/*計(jì)算CRC*/usCRC16=usMBCRC16((UCHAR*)pucSndBufferCur,usSndBufferCount);ucRTUBuf[usSndBufferCount++]=(UCHAR)(usCRC16&0xFF);ucRTUBuf[usSndBufferCount++]=(UCHAR)(usCRC16>>8);/*啟動(dòng)發(fā)送*//*啟動(dòng)發(fā)送*/eSndState=STATE_TX_XMIT;vMBPortSerialEnable(FALSE,TRUE);}else{eStatus=MB_EIO;}EXIT_CRITICAL_SECTION();returneStatus;}/******************************************@Func:接收狀態(tài)機(jī)*****************************************/BOOLxMBRTUReceiveFSM(void){BOOLxTaskNeedSwitch=FALSE;UCHARucByte;assert(eSndState==STATE_TX_IDLE);//獲取串?數(shù)據(jù)(void)xMBPortSerialGetByte((CHAR*)&ucByte);switch(eRcvState){/*如果收到?個(gè)字節(jié)在STATE_RX_INIT狀態(tài)*丟棄,并開(kāi)啟定時(shí)器,等待進(jìn)?STATE_RX_IDLE狀態(tài)*/caseSTATE_RX_INIT:vMBPortTimersEnable();break;/*接收出現(xiàn)錯(cuò)誤,此次數(shù)據(jù)丟棄*開(kāi)啟定時(shí)器,準(zhǔn)備下?次接收數(shù)據(jù)*/caseSTATE_RX_ERROR:vMBPortTimersEnable();break;/*在空閑狀態(tài)下,我們等待?個(gè)新的字符。*如果接收到?個(gè)字符,則啟動(dòng)計(jì)時(shí)器,*并且接收器處于STATE_RX_RECEIVCE.*/caseSTATE_RX_IDLE:usRcvBufferPos=0;ucRTUBuf[usRcvBufferPos++]=ucByte;eRcvState=STATE_RX_RCV;//開(kāi)啟定時(shí)器vMBPortTimersEnable();break;/*收到?個(gè)字節(jié)數(shù)據(jù),復(fù)位?次定時(shí)器防?定時(shí)器溢出*如果收到超出最?字節(jié)數(shù)據(jù),進(jìn)?STATE_RX_RCV*/caseSTATE_RX_RCV:if(usRcvBufferPos<MB_SER_PDU_SIZE_MAX){ucRTUBuf[usRcvBufferPos++]=ucByte;}else{eRcvState=STATE_RX_ERROR;}vMBPortTimersEnable();vMBPortTimersEnable();break;}returnxTaskNeedSwitch;}/******************************************@Func:發(fā)送狀態(tài)機(jī)*****************************************/BOOLxMBRTUTransmitFSM(void){BOOLxNeedPoll=FALSE;assert(eRcvState==STATE_RX_IDLE);switch(eSndState){caseSTATE_TX_IDLE:/*使能接收/禁?發(fā)送.*/vMBPortSerialEnable(TRUE,FALSE);break;caseSTATE_TX_XMIT:/*檢查是否發(fā)送完成*/if(usSndBufferCount!=0){xMBPortSerialPutByte((CHAR)*pucSndBufferCur);pucSndBufferCur++;/*發(fā)送數(shù)據(jù)指針后移*/usSndBufferCount--;/*發(fā)送數(shù)據(jù)量減?*/}else{xNeedPoll=xMBPortEventPost(EV_FRAME_SENT);/*發(fā)送完成,使能接收,禁?發(fā)送*/vMBPortSerialEnable(TRUE,FALSE);eSndState=STATE_TX_IDLE;}break;}returnxNeedPoll;}BOOLxMBRTUTimerT35Expired(void){BOOLxNeedPoll=FALSE;switch(eRcvState){//協(xié)議棧準(zhǔn)備就緒caseSTATE_RX_INIT:xNeedPoll=xMBPortEventPost(EV_READY);break;//,,接收?陣數(shù)據(jù)后定時(shí)周期到拋出事件EV_FRAME_RECEIVEDcaseSTATE_RX_RCV:xNeedPoll

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論