diff --git a/FreeModbus 主机分析图.vsd b/FreeModbus 主机分析图.vsd index 26f7a56..3b1a09b 100644 Binary files a/FreeModbus 主机分析图.vsd and b/FreeModbus 主机分析图.vsd differ 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