收藏 分销(赏)

源代码分析(Modbus通讯协议)及通讯原理分析档.doc

上传人:仙人****88 文档编号:7622199 上传时间:2025-01-10 格式:DOC 页数:9 大小:52KB
下载 相关 举报
源代码分析(Modbus通讯协议)及通讯原理分析档.doc_第1页
第1页 / 共9页
源代码分析(Modbus通讯协议)及通讯原理分析档.doc_第2页
第2页 / 共9页
源代码分析(Modbus通讯协议)及通讯原理分析档.doc_第3页
第3页 / 共9页
源代码分析(Modbus通讯协议)及通讯原理分析档.doc_第4页
第4页 / 共9页
源代码分析(Modbus通讯协议)及通讯原理分析档.doc_第5页
第5页 / 共9页
点击查看更多>>
资源描述

1、文件: C:DOCUME1sir5LOCALS1TempRar$DI00.984mbrtu.c 2008-11-15, 7:44:4747/* * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU. * Copyright (c) 2006 Christian Walter * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are

2、permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and

3、 the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS

4、 AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INC

5、LUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE US

6、E OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * File: $Id: mbrtu.c,v 1.18 2007/09/12 10:15:56 wolti Exp $ */* - System includes-*/#include stdlib.h#include string.h/* - Platform includes-*/#include port.h/* - Modbus includes-*/#include mb.h#include mbrtu.h#include mbfram

7、e.h#include mbcrc.h#include mbport.h/* - Defines-*/#define MB_SER_PDU_SIZE_MIN 4 /*! Minimum size of a Modbus RTUframe. */#define MB_SER_PDU_SIZE_MAX 256 /*! Maximum size of a Modbus RTUframe. */#define MB_SER_PDU_SIZE_CRC 2 /*! Size of CRC field in PDU. */第 1 页文件: C:DOCUME1sir5LOCALS1TempRar$DI00.9

8、84mbrtu.c 2008-11-15, 7:44:4747#define MB_SER_PDU_ADDR_OFF 0 /*! Offset of slave address inSer-PDU. */#define MB_SER_PDU_PDU_OFF 1 /*! Offset of Modbus-PDU in Ser-PDU.*/* - Type definitions-*/typedef enum STATE_RX_INIT, /*! Receiver is in initial state. */ STATE_RX_IDLE, /*! Receiver is in idle stat

9、e. */ STATE_RX_RCV, /*! Frame is beeing received. */ STATE_RX_ERROR /*! If the frame is invalid. */ eMBRcvState;typedef enum STATE_TX_IDLE, /*! Transmitter is in idle state. */ STATE_TX_XMIT /*! 19200 then we should use the fixed timer values * t35 = 1750us. Otherwise t35 must be 3.5 times the chara

10、cter time. */ if( ulBaudRate 19200 ) usTimerT35_50us = 35; /* 1800us. */ else /* The timer reload value for a character is given by: * * ChTimeValue = Ticks_per_1s / ( Baudrate / 11 ) * = 11 * Ticks_per_1s / Baudrate * = 220000 / Baudrate * The reload for t3.5 is 1.5 times this value and similary *

11、for t3.5. */ usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate ); if( xMBPortTimersInit( ( USHORT ) usTimerT35_50us ) != TRUE ) eStatus = MB_EPORTERR; EXIT_CRITICAL_SECTION( ); return eStatus;void eMBRTUStart( void ) #if OS_CRITICAL_METHOD = 3 OS_CPU_SR cpu_sr = 0;#endif ENTER_CRITICAL_SECTI

12、ON( ); /* Initially the receiver is in the state STATE_RX_INIT. we start * the timer and if no character is received within t3.5 we change * to STATE_RX_IDLE. This makes sure that we delay startup of the * modbus protocol stack until the bus is free. */ eRcvState = STATE_RX_INIT; eSndState = STATE_T

13、X_IDLE; /2008.11.12 修改 vMBPortSerialEnable( TRUE, FALSE ); vMBPortTimersEnable( ); EXIT_CRITICAL_SECTION( );void eMBRTUStop( void ) #if OS_CRITICAL_METHOD = 3 OS_CPU_SR cpu_sr = 0;#endif第 3 页文件: C:DOCUME1sir5LOCALS1TempRar$DI00.984mbrtu.c 2008-11-15, 7:44:4747 ENTER_CRITICAL_SECTION( ); vMBPortSeria

14、lEnable( FALSE, FALSE ); vMBPortTimersDisable( ); EXIT_CRITICAL_SECTION( );eMBErrorCode eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR * pucFrame, USHORT * pusLength ) #if OS_CRITICAL_METHOD = 3 OS_CPU_SR cpu_sr = 0;#endif BOOL xFrameReceived = FALSE; eMBErrorCode eStatus = MB_ENOERR; ENTER_CRITICAL_SE

15、CTION( ); assert( usRcvBufferPos = MB_SER_PDU_SIZE_MIN ) & ( usMBCRC16( ( UCHAR * ) ucRTUBuf, usRcvBufferPos ) = 0 ) ) /* Save the address field. All frames are passed to the upper layed * and the decision if a frame is used is done there. */ *pucRcvAddress = ucRTUBufMB_SER_PDU_ADDR_OFF; /* Total le

16、ngth of Modbus-PDU is Modbus-Serial-Line-PDU minus * size of address field and CRC checksum. */ *pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF -MB_SER_PDU_SIZE_CRC ); /* Return the start of the Modbus PDU to the caller. */ *pucFrame = ( UCHAR * ) & ucRTUBufMB_SER_PDU_PDU_OFF; xFrameRec

17、eived = TRUE; else eStatus = MB_EIO; EXIT_CRITICAL_SECTION( ); return eStatus;eMBErrorCode eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )#if OS_CRITICAL_METHOD = 3 OS_CPU_SR cpu_sr = 0;#endif eMBErrorCode eStatus = MB_ENOERR;第 4 页文件: C:DOCUME1sir5LOCALS1TempRar$DI00.984m

18、brtu.c 2008-11-15, 7:44:4747 USHORT usCRC16; ENTER_CRITICAL_SECTION( ); /* Check if the receiver is still in idle state. If not we where to * slow with processing the received frame and the master sent another * frame on the network. We have to abort sending the frame. */ if( eRcvState = STATE_RX_ID

19、LE ) /* First byte before the Modbus-PDU is the slave address. */ pucSndBufferCur = ( UCHAR * ) pucFrame - 1; usSndBufferCount = 1; /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */ pucSndBufferCurMB_SER_PDU_ADDR_OFF = ucSlaveAddress; usSndBufferCount += usLength; /* Calculate CRC16 che

20、cksum for Modbus-Serial-Line-PDU. */ usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount ); ucRTUBufusSndBufferCount+ = ( UCHAR )( usCRC16 & 0xFF ); ucRTUBufusSndBufferCount+ = ( UCHAR )( usCRC16 8 ); /* Activate the transmitter. */ eSndState = STATE_TX_XMIT; vMBPortSerialEnable( FALS

21、E, TRUE ); else eStatus = MB_EIO; EXIT_CRITICAL_SECTION( ); return eStatus;BOOL xMBRTUReceiveFSM( void ) BOOL xTaskNeedSwitch = FALSE; UCHAR ucByte; assert( eSndState = STATE_TX_IDLE ); /* Always read the character. V1.14版本修改*/ ( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte ); switch ( eRcvState

22、) /* If we have received a character in the init state we have to * wait until the frame is finished. */ case STATE_RX_INIT: vMBPortTimersEnable( ); /2008.11.5修改 出错后仍然要读寄存器,否则将造成串口一直处于中断中 /( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte ); break;第 5 页文件: C:DOCUME1sir5LOCALS1TempRar$DI00.984mbrtu.c

23、 2008-11-15, 7:44:4747 /* In the error state we wait until all characters in the * damaged frame are transmitted. */ case STATE_RX_ERROR: vMBPortTimersEnable( ); /2008.11.5修改 出错后仍然要读寄存器,否则将造成串口一直处于中断中 /( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte ); break; /* In the idle state we wait for a new

24、 character. If a character * is received the t1.5 and t3.5 timers are started and the * receiver is in the state STATE_RX_RECEIVCE. */ case STATE_RX_IDLE: usRcvBufferPos = 0; /( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte ); ucRTUBufusRcvBufferPos+ = ucByte; eRcvState = STATE_RX_RCV; /* Enable t

25、3.5 timers. */ vMBPortTimersEnable( ); break; /* We are currently receiving a frame. Reset the timer after * every character received. If more than the maximum possible * number of bytes in a modbus frame is received the frame is * ignored. */ case STATE_RX_RCV: if( usRcvBufferPos MB_SER_PDU_SIZE_MA

26、X ) /( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte ); ucRTUBufusRcvBufferPos+ = ucByte; else eRcvState = STATE_RX_ERROR; vMBPortTimersEnable( ); break; return xTaskNeedSwitch;BOOL xMBRTUTransmitFSM( void ) BOOL xNeedPoll = FALSE; assert( eRcvState = STATE_RX_IDLE ); switch ( eSndState ) 第 6 页文件:

27、 C:DOCUME1sir5LOCALS1TempRar$DI00.984mbrtu.c 2008-11-15, 7:44:4747 /* We should not get a transmitter event if the transmitter is in * idle state. */ case STATE_TX_IDLE: /* enable receiver/disable transmitter. */ vMBPortSerialEnable( TRUE, FALSE ); break; case STATE_TX_XMIT: /* check if we are finis

28、hed. */ if( usSndBufferCount != 0 ) xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur ); pucSndBufferCur+; /* next byte in sendbuffer. */ usSndBufferCount-; else xNeedPoll = xMBPortEventPost( EV_FRAME_SENT ); /* Disable transmitter. This prevents another transmit buffer * empty interrupt. */ vMBPortSer

29、ialEnable( TRUE, FALSE ); eSndState = STATE_TX_IDLE; break; return xNeedPoll;BOOL xMBRTUTimerT35Expired( void ) BOOL xNeedPoll = FALSE; switch ( eRcvState ) /* Timer t35 expired. Startup phase is finished. */ case STATE_RX_INIT: xNeedPoll = xMBPortEventPost( EV_READY ); break; /* A frame was receive

30、d and t35 expired. Notify the listener that * a new frame was received. */ case STATE_RX_RCV: xNeedPoll = xMBPortEventPost( EV_FRAME_RECEIVED ); break; /* An error occured while receiving the frame. */ case STATE_RX_ERROR: break; /* Function called in an illegal state. */ default: assert( ( eRcvState = STATE_RX_INIT ) | ( eRcvState = STATE_RX_RCV ) | ( eRcvState = STATE_RX_ERROR第 7 页文件: C:DOCUME1sir5LOCALS1TempRar$DI00.984mbrtu.c 2008-11-15, 7:44:4747) ); vMBPortTimersDisable( ); eRcvState = STATE_RX_IDLE; return xNeedPoll;

展开阅读全文
部分上传会员的收益排行 01、路***(¥15400+),02、曲****(¥15300+),
03、wei****016(¥13200+),04、大***流(¥12600+),
05、Fis****915(¥4200+),06、h****i(¥4100+),
07、Q**(¥3400+),08、自******点(¥2400+),
09、h*****x(¥1400+),10、c****e(¥1100+),
11、be*****ha(¥800+),12、13********8(¥800+)。
相似文档                                   自信AI助手自信AI助手
搜索标签

当前位置:首页 > 教育专区 > 小学其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服