From dfe745c166ae029fb513ab8e7fbb047c6eef2a7f Mon Sep 17 00:00:00 2001 From: armink Date: Mon, 19 Aug 2013 16:51:08 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E3=80=90=E6=9B=B4=E6=96=B0=E3=80=91?= =?UTF-8?q?=E3=80=8AFreeModbus=20=E4=B8=BB=E6=9C=BA=E5=88=86=E6=9E=90?= =?UTF-8?q?=E5=9B=BE=E3=80=8B=E4=B8=AD=E5=85=B3=E4=BA=8E=E5=8F=91=E9=80=81?= =?UTF-8?q?=E5=8F=8A=E6=8E=A5=E5=8F=97=E7=8A=B6=E6=80=81=E5=9B=BE=EF=BC=8C?= =?UTF-8?q?=E5=85=B6=E4=BD=99=E8=BF=98=E9=9C=80=E5=90=8E=E6=9C=9F=E5=AE=8C?= =?UTF-8?q?=E5=96=84=EF=BC=9B=202=E3=80=81=E3=80=90=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E3=80=91FreeModbus=E4=B8=BB=E6=9C=BA=E4=BC=A0=E8=BE=93?= =?UTF-8?q?=E5=B1=82=E9=80=BB=E8=BE=91=E5=AE=9E=E7=8E=B0=EF=BC=8C=E7=A8=B3?= =?UTF-8?q?=E5=AE=9A=E6=80=A7=E8=BF=98=E9=9C=80=E5=90=8E=E6=9C=9F=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: armink --- FreeModbus 主机分析图.vsd | Bin 144384 -> 160256 bytes FreeModbus/modbus/include/mbport.h | 21 +- FreeModbus/modbus/rtu/mbrtu.c | 1 + FreeModbus/modbus/rtu/mbrtu_m.c | 396 +++++++++++++++-------------- FreeModbus/port/port.h | 1 + FreeModbus/port/portevent_m.c | 9 +- FreeModbus/port/portserial_m.c | 4 + FreeModbus/port/porttimer_m.c | 44 +++- 8 files changed, 277 insertions(+), 199 deletions(-) diff --git a/FreeModbus 主机分析图.vsd b/FreeModbus 主机分析图.vsd index 26f7a56ea3a29179784a4ff60567255a0194cc7b..3b1a09b880b91691201c53dc2a458e68cd74b498 100644 GIT binary patch delta 47149 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

l#Nd+>nQ6y3-PbsNbVF2%pUXN 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 diff --git a/FreeModbus/modbus/include/mbport.h b/FreeModbus/modbus/include/mbport.h index 1615a38..5766823 100644 --- a/FreeModbus/modbus/include/mbport.h +++ b/FreeModbus/modbus/include/mbport.h @@ -46,6 +46,15 @@ typedef enum EV_FRAME_SENT /*!< Frame sent. */ } eMBEventType; +typedef enum +{ + EV_MASTER_READY, /*!< Startup finished. */ + EV_MASTER_FRAME_RECEIVED, /*!< Frame received. */ + EV_MASTER_EXECUTE, /*!< Execute function. */ + EV_MASTER_FRAME_SENT, /*!< Frame sent. */ + EV_MASTER_ERROR_PROCESS /*!< Frame error process*/ +} eMBMasterEventType; + /*! \ingroup modbus * \brief Parity used for characters in serial mode. * @@ -69,9 +78,9 @@ BOOL xMBPortEventGet( /*@out@ */ eMBEventType * eEvent ); BOOL xMBMasterPortEventInit( void ); -BOOL xMBMasterPortEventPost( eMBEventType eEvent ); +BOOL xMBMasterPortEventPost( eMBMasterEventType eEvent ); -BOOL xMBMasterPortEventGet( /*@out@ */ eMBEventType * eEvent ); +BOOL xMBMasterPortEventGet( /*@out@ */ eMBMasterEventType * eEvent ); /* ----------------------- Serial port functions ----------------------------*/ @@ -100,7 +109,7 @@ void vMBMasterPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ); INLINE BOOL xMBMasterPortSerialGetByte( CHAR * pucByte ); -INLINE BOOL xMBPortSerialPutByte( CHAR ucByte ); +INLINE BOOL xMBMasterPortSerialPutByte( CHAR ucByte ); /* ----------------------- Timers functions ---------------------------------*/ BOOL xMBPortTimersInit( USHORT usTimeOut50us ); @@ -115,7 +124,11 @@ BOOL xMBMasterPortTimersInit( USHORT usTimeOut50us ); void xMBMasterPortTimersClose( void ); -INLINE void vMBMasterPortTimersEnable( void ); +INLINE void vMBMasterPortTimersT35Enable( void ); + +INLINE void vMBMasterPortTimersConvertDelayEnable( void ); + +INLINE void vMBMasterPortTimersRespondTimeoutEnable( void ); INLINE void vMBMasterPortTimersDisable( void ); diff --git a/FreeModbus/modbus/rtu/mbrtu.c b/FreeModbus/modbus/rtu/mbrtu.c index 2ee5129..bdaeee4 100644 --- a/FreeModbus/modbus/rtu/mbrtu.c +++ b/FreeModbus/modbus/rtu/mbrtu.c @@ -346,6 +346,7 @@ xMBRTUTimerT35Expired( void ) default: assert_param( ( eRcvState == STATE_RX_INIT ) || ( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) ); + break; } vMBPortTimersDisable( ); diff --git a/FreeModbus/modbus/rtu/mbrtu_m.c b/FreeModbus/modbus/rtu/mbrtu_m.c index 4f16775..f44937e 100644 --- a/FreeModbus/modbus/rtu/mbrtu_m.c +++ b/FreeModbus/modbus/rtu/mbrtu_m.c @@ -57,13 +57,14 @@ typedef enum STATE_M_RX_INIT, /*!< Receiver is in initial state. */ STATE_M_RX_IDLE, /*!< Receiver is in idle state. */ STATE_M_RX_RCV, /*!< Frame is beeing received. */ - STATE_M_RX_ERROR /*!< If the frame is invalid. */ + STATE_M_RX_ERROR, /*!< If the frame is invalid. */ } eMBMasterRcvState; typedef enum { STATE_M_TX_IDLE, /*!< Transmitter is in idle state. */ STATE_M_TX_XMIT, /*!< Transmitter is in transfer state. */ + STATE_M_TX_XFWR, /*!< Transmitter is in transfer finish and wait receive state. */ } eMBMasterSndState; /* ----------------------- Static variables ---------------------------------*/ @@ -72,11 +73,11 @@ static volatile eMBMasterRcvState eRcvState; volatile UCHAR ucMasterRTUBuf[MB_SER_PDU_SIZE_MAX]; -static volatile UCHAR *pucSndBufferCur; -static volatile USHORT usSndBufferCount; - -static volatile USHORT usRcvBufferPos; +static volatile UCHAR *pucMasterSndBufferCur; +static volatile USHORT usMasterSndBufferCount; +static volatile USHORT usMasterRcvBufferPos; +static volatile BOOL bFrameIsBroadcast = FALSE; /* ----------------------- Start implementation -----------------------------*/ eMBErrorCode eMBMasterRTUInit(UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ) @@ -133,7 +134,7 @@ eMBMasterRTUStart( void ) */ eRcvState = STATE_M_RX_INIT; vMBMasterPortSerialEnable( TRUE, FALSE ); - vMBMasterPortTimersEnable( ); + vMBMasterPortTimersT35Enable( ); EXIT_CRITICAL_SECTION( ); } @@ -147,179 +148,191 @@ eMBMasterRTUStop( void ) EXIT_CRITICAL_SECTION( ); } -//eMBErrorCode -//eMBMasterRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength ) -//{ -// BOOL xFrameReceived = FALSE; -// eMBErrorCode eStatus = MB_ENOERR; -// -// ENTER_CRITICAL_SECTION( ); -// assert_param( usRcvBufferPos < MB_SER_PDU_SIZE_MAX ); -// -// /* Length and CRC check */ -// if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN ) -// && ( usMBCRC16( ( UCHAR * ) ucMasterRTUBuf, 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 = ucMasterRTUBuf[MB_SER_PDU_ADDR_OFF]; -// -// /* Total length 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 * ) & ucMasterRTUBuf[MB_SER_PDU_PDU_OFF]; -// xFrameReceived = TRUE; -// } -// else -// { -// eStatus = MB_EIO; -// } -// -// EXIT_CRITICAL_SECTION( ); -// return eStatus; -//} -// -//eMBErrorCode -//eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength ) -//{ -// eMBErrorCode eStatus = MB_ENOERR; -// 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_M_RX_IDLE ) -// { -// /* 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. */ -// pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress; -// usSndBufferCount += usLength; -// -// /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */ -// usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount ); -// ucMasterRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF ); -// ucMasterRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 ); -// -// /* Activate the transmitter. */ -// eSndState = STATE_M_TX_XMIT; -// vMBMasterPortSerialEnable( FALSE, TRUE ); -// } -// else -// { -// eStatus = MB_EIO; -// } -// EXIT_CRITICAL_SECTION( ); -// return eStatus; -//} -// -//BOOL -//xMBMasterRTUReceiveFSM( void ) -//{ -// BOOL xTaskNeedSwitch = FALSE; -// UCHAR ucByte; -// -// assert_param( eSndState == STATE_TX_IDLE ); -// -// /* Always read the character. */ -// ( void )xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte ); -// -// switch ( eRcvState ) -// { -// /* If we have received a character in the init state we have to -// * wait until the frame is finished. -// */ -// case STATE_RX_INIT: -// vMBMasterPortTimersEnable( ); -// break; -// -// /* In the error state we wait until all characters in the -// * damaged frame are transmitted. -// */ -// case STATE_RX_ERROR: -// vMBMasterPortTimersEnable( ); -// break; -// -// /* In the idle state we wait for a new 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_M_RX_IDLE: -// usRcvBufferPos = 0; -// ucMasterRTUBuf[usRcvBufferPos++] = ucByte; -// eRcvState = STATE_M_RX_RCV; -// -// /* Enable t3.5 timers. */ -// vMBMasterPortTimersEnable( ); -// 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_M_RX_RCV: -// if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX ) -// { -// ucMasterRTUBuf[usRcvBufferPos++] = ucByte; -// } -// else -// { -// eRcvState = STATE_RX_ERROR; -// } -// vMBMasterPortTimersEnable(); -// break; -// } -// return xTaskNeedSwitch; -//} -// -//BOOL -//xMBMasterRTUTransmitFSM( void ) -//{ -// BOOL xNeedPoll = FALSE; -// -// assert_param( eRcvState == STATE_RX_IDLE ); -// -// switch ( eSndState ) -// { -// /* We should not get a transmitter event if the transmitter is in -// * idle state. */ -// case STATE_M_TX_IDLE: -// /* enable receiver/disable transmitter. */ -// vMBMasterPortSerialEnable( TRUE, FALSE ); -// break; -// -// case STATE_M_TX_XMIT: -// /* check if we are finished. */ -// if( usSndBufferCount != 0 ) -// { -// xMBMasterPortSerialPutByte( ( CHAR )*pucSndBufferCur ); -// pucSndBufferCur++; /* next byte in sendbuffer. */ -// usSndBufferCount--; -// } -// else -// { -// xNeedPoll = xMBMasterPortEventPost( EV_FRAME_SENT ); -// /* Disable transmitter. This prevents another transmit buffer -// * empty interrupt. */ -// vMBMasterPortSerialEnable( TRUE, FALSE ); -// eSndState = STATE_M_TX_IDLE; -// } -// break; -// } -// -// return xNeedPoll; -//} -// +eMBErrorCode +eMBMasterRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength ) +{ + BOOL xFrameReceived = FALSE; + eMBErrorCode eStatus = MB_ENOERR; + + ENTER_CRITICAL_SECTION( ); + assert_param( usRcvBufferPos < MB_SER_PDU_SIZE_MAX ); + + /* Length and CRC check */ + if( ( usMasterRcvBufferPos >= MB_SER_PDU_SIZE_MIN ) + && ( usMBCRC16( ( UCHAR * ) ucMasterRTUBuf, usMasterRcvBufferPos ) == 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 = ucMasterRTUBuf[MB_SER_PDU_ADDR_OFF]; + + /* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus + * size of address field and CRC checksum. + */ + *pusLength = ( USHORT )( usMasterRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC ); + + /* Return the start of the Modbus PDU to the caller. */ + *pucFrame = ( UCHAR * ) & ucMasterRTUBuf[MB_SER_PDU_PDU_OFF]; + xFrameReceived = TRUE; + } + else + { + eStatus = MB_EIO; + } + + EXIT_CRITICAL_SECTION( ); + return eStatus; +} + +eMBErrorCode +eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength ) +{ + eMBErrorCode eStatus = MB_ENOERR; + 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_M_RX_IDLE ) + { + /* First byte before the Modbus-PDU is the slave address. */ + pucMasterSndBufferCur = ( UCHAR * ) pucFrame - 1; + usMasterSndBufferCount = 1; + + /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */ + pucMasterSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress; + usMasterSndBufferCount += usLength; + + /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */ + usCRC16 = usMBCRC16( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount ); + ucMasterRTUBuf[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF ); + ucMasterRTUBuf[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 ); + + /* Activate the transmitter. */ + eSndState = STATE_M_TX_XMIT; + vMBMasterPortSerialEnable( FALSE, TRUE ); + } + else + { + eStatus = MB_EIO; + } + EXIT_CRITICAL_SECTION( ); + return eStatus; +} + +BOOL +xMBMasterRTUReceiveFSM( void ) +{ + BOOL xTaskNeedSwitch = FALSE; + UCHAR ucByte; + + assert_param( eSndState == STATE_TX_IDLE ); + + /* Always read the character. */ + ( void )xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte ); + + switch ( eRcvState ) + { + /* If we have received a character in the init state we have to + * wait until the frame is finished. + */ + case STATE_M_RX_INIT: + vMBMasterPortTimersT35Enable( ); + break; + + /* In the error state we wait until all characters in the + * damaged frame are transmitted. + */ + case STATE_M_RX_ERROR: + vMBMasterPortTimersT35Enable( ); + break; + + /* In the idle state we wait for a new 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 and disable early + * the timer of respond timeout . + */ + case STATE_M_RX_IDLE: + /* In time of respond timeout,the receiver receive a frame. + * Disable timer of respond timeout and change the transmiter state to idle. + */ + vMBMasterPortTimersDisable( ); + eSndState = STATE_M_TX_IDLE; + + usMasterRcvBufferPos = 0; + ucMasterRTUBuf[usMasterRcvBufferPos++] = ucByte; + eRcvState = STATE_M_RX_RCV; + + /* Enable t3.5 timers. */ + vMBMasterPortTimersT35Enable( ); + 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_M_RX_RCV: + if( usMasterRcvBufferPos < MB_SER_PDU_SIZE_MAX ) + { + ucMasterRTUBuf[usMasterRcvBufferPos++] = ucByte; + } + else + { + eRcvState = STATE_M_RX_ERROR; + } + vMBMasterPortTimersT35Enable(); + break; + } + return xTaskNeedSwitch; +} + +BOOL +xMBMasterRTUTransmitFSM( void ) +{ + BOOL xNeedPoll = FALSE; + + assert_param( eRcvState == STATE_RX_IDLE ); + + switch ( eSndState ) + { + /* We should not get a transmitter event if the transmitter is in + * idle state. */ + case STATE_M_TX_IDLE: + /* enable receiver/disable transmitter. */ + vMBMasterPortSerialEnable( TRUE, FALSE ); + break; + + case STATE_M_TX_XMIT: + /* check if we are finished. */ + if( usMasterSndBufferCount != 0 ) + { + xMBMasterPortSerialPutByte( ( CHAR )*pucMasterSndBufferCur ); + pucMasterSndBufferCur++; /* next byte in sendbuffer. */ + usMasterSndBufferCount--; + } + else + { + bFrameIsBroadcast = ( ucMasterRTUBuf[MB_SER_PDU_ADDR_OFF] == MB_ADDRESS_BROADCAST ) ? TRUE : FALSE; + xNeedPoll = xMBMasterPortEventPost( EV_MASTER_FRAME_SENT ); + /* Disable transmitter. This prevents another transmit buffer + * empty interrupt. */ + vMBMasterPortSerialEnable( TRUE, FALSE ); + eSndState = STATE_M_TX_XFWR; + /* If the frame is broadcast ,master will enable timer of convert delay, + * else master will enable timer of respond timeout. */ + if ( bFrameIsBroadcast == TRUE ) vMBMasterPortTimersConvertDelayEnable( ); + else vMBMasterPortTimersRespondTimeoutEnable( ); + } + break; + } + + return xNeedPoll; +} + BOOL xMBMasterRTUTimerT35Expired(void) { @@ -329,13 +342,13 @@ xMBMasterRTUTimerT35Expired(void) { /* Timer t35 expired. Startup phase is finished. */ case STATE_M_RX_INIT: - xNeedPoll = xMBMasterPortEventPost(EV_READY); + xNeedPoll = xMBMasterPortEventPost(EV_MASTER_READY); break; /* A frame was received and t35 expired. Notify the listener that * a new frame was received. */ case STATE_M_RX_RCV: - xNeedPoll = xMBMasterPortEventPost(EV_FRAME_RECEIVED); + xNeedPoll = xMBMasterPortEventPost(EV_MASTER_FRAME_RECEIVED); break; /* An error occured while receiving the frame. */ @@ -348,19 +361,24 @@ xMBMasterRTUTimerT35Expired(void) ( eRcvState == STATE_M_RX_INIT ) || ( eRcvState == STATE_M_RX_RCV ) || ( eRcvState == STATE_M_RX_ERROR )); break; } - - vMBMasterPortTimersDisable(); eRcvState = STATE_M_RX_IDLE; - //TODO ״̬ڳʱ״̬תҪ - - switch(eSndState) + switch (eSndState) { - /* Timer t35 expired. . */ - case STATE_M_TX_XMIT : - + /* A frame was send finish and convert delay or respond timeout expired. + * If the frame is broadcast,The master will idle,and if the frame is not + * broadcast.Notify the listener process error.*/ + case STATE_M_TX_XFWR: + if ( bFrameIsBroadcast == FALSE ) xNeedPoll = xMBMasterPortEventPost(EV_MASTER_ERROR_PROCESS); + break; + /* Function called in an illegal state. */ + default: + assert_param( eSndState == STATE_M_TX_XFWR ); + break; } + eSndState = STATE_M_TX_IDLE; + vMBMasterPortTimersDisable(); return xNeedPoll; } #endif diff --git a/FreeModbus/port/port.h b/FreeModbus/port/port.h index ccc5c3f..89f07f5 100644 --- a/FreeModbus/port/port.h +++ b/FreeModbus/port/port.h @@ -23,6 +23,7 @@ #define _PORT_H #include +#include "mbconfig.h" #include #include diff --git a/FreeModbus/port/portevent_m.c b/FreeModbus/port/portevent_m.c index 8daf623..26d08f6 100644 --- a/FreeModbus/port/portevent_m.c +++ b/FreeModbus/port/portevent_m.c @@ -23,8 +23,9 @@ #include "mb.h" #include "mbport.h" +#if MB_MASTER_RTU_ENABLED > 0 /* ----------------------- Variables ----------------------------------------*/ -static eMBEventType eMasterQueuedEvent; +static eMBMasterEventType eMasterQueuedEvent; static BOOL xMasterEventInQueue; /* ----------------------- Start implementation -----------------------------*/ @@ -36,7 +37,7 @@ xMBMasterPortEventInit( void ) } BOOL -xMBMasterPortEventPost( eMBEventType eEvent ) +xMBMasterPortEventPost( eMBMasterEventType eEvent ) { xMasterEventInQueue = TRUE; eMasterQueuedEvent = eEvent; @@ -44,7 +45,7 @@ xMBMasterPortEventPost( eMBEventType eEvent ) } BOOL -xMBMasterPortEventGet( eMBEventType * eEvent ) +xMBMasterPortEventGet( eMBMasterEventType * eEvent ) { BOOL xEventHappened = FALSE; @@ -56,3 +57,5 @@ xMBMasterPortEventGet( eMBEventType * eEvent ) } return xEventHappened; } + +#endif diff --git a/FreeModbus/port/portserial_m.c b/FreeModbus/port/portserial_m.c index 4fe52ea..7ba7cab 100644 --- a/FreeModbus/port/portserial_m.c +++ b/FreeModbus/port/portserial_m.c @@ -24,6 +24,8 @@ /* ----------------------- Modbus includes ----------------------------------*/ #include "mb.h" #include "mbport.h" + +#if MB_MASTER_RTU_ENABLED > 0 /* ----------------------- static functions ---------------------------------*/ static void prvvUARTTxReadyISR(void); static void prvvUARTRxISR(void); @@ -188,3 +190,5 @@ void USART2_IRQHandler(void) } rt_interrupt_leave(); } + +#endif diff --git a/FreeModbus/port/porttimer_m.c b/FreeModbus/port/porttimer_m.c index 0d79c85..9de78a4 100644 --- a/FreeModbus/port/porttimer_m.c +++ b/FreeModbus/port/porttimer_m.c @@ -26,11 +26,15 @@ #include "mb.h" #include "mbport.h" +#if MB_MASTER_RTU_ENABLED > 0 +/* ----------------------- Variables ----------------------------------------*/ +static USHORT usT35TimeOut50us; + /* ----------------------- static functions ---------------------------------*/ static void prvvTIMERExpiredISR(void); /* ----------------------- Start implementation -----------------------------*/ -BOOL xMBMasterPortTimersInit(USHORT usTim1Timerout50us) +BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us) { uint16_t PrescalerValue = 0; @@ -48,7 +52,8 @@ BOOL xMBMasterPortTimersInit(USHORT usTim1Timerout50us) PrescalerValue = (uint16_t) (SystemCoreClock / 20000) - 1; //ʱ1ʼ - TIM_TimeBaseStructure.TIM_Period = (uint16_t) usTim1Timerout50us; + usT35TimeOut50us = usTimeOut50us; //T35ʱֵ + TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; @@ -72,8 +77,39 @@ BOOL xMBMasterPortTimersInit(USHORT usTim1Timerout50us) return TRUE; } -void vMBMasterPortTimersEnable() +void vMBMasterPortTimersT35Enable() { + //װؼֵ ׼50us + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + TIM_TimeBaseStructure.TIM_Period = (uint16_t) usT35TimeOut50us; + TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); + + TIM_ClearITPendingBit(TIM2, TIM_IT_Update); + TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); + TIM_SetCounter(TIM2, 0); + TIM_Cmd(TIM2, ENABLE); +} + +void vMBMasterPortTimersConvertDelayEnable() +{ + //װؼֵ ׼50us + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + TIM_TimeBaseStructure.TIM_Period = (uint16_t)(MB_MASTER_DELAY_MS_CONVERT * 1000 / 50) ; + TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); + + TIM_ClearITPendingBit(TIM2, TIM_IT_Update); + TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); + TIM_SetCounter(TIM2, 0); + TIM_Cmd(TIM2, ENABLE); +} + +void vMBMasterPortTimersRespondTimeoutEnable() +{ + //װؼֵ ׼50us + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + TIM_TimeBaseStructure.TIM_Period = (uint16_t)(MB_MASTER_TIMEOUT_MS_RESPOND * 1000 / 50); + TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); + TIM_ClearITPendingBit(TIM2, TIM_IT_Update); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); TIM_SetCounter(TIM2, 0); @@ -105,3 +141,5 @@ void TIM2_IRQHandler(void) } rt_interrupt_leave(); } + +#endif