1、【更新】《FreeModbus 主机分析图》中关于发送及接受状态图,其余还需后期完善;

2、【增加】FreeModbus主机传输层逻辑实现,稳定性还需后期测试;

Signed-off-by: armink <armink.ztl@gmail.com>
This commit is contained in:
armink 2013-08-19 16:51:08 +08:00
parent 31fab3ed4d
commit dfe745c166
8 changed files with 277 additions and 199 deletions

Binary file not shown.

View File

@ -46,6 +46,15 @@ typedef enum
EV_FRAME_SENT /*!< Frame sent. */ EV_FRAME_SENT /*!< Frame sent. */
} eMBEventType; } 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 /*! \ingroup modbus
* \brief Parity used for characters in serial mode. * \brief Parity used for characters in serial mode.
* *
@ -69,9 +78,9 @@ BOOL xMBPortEventGet( /*@out@ */ eMBEventType * eEvent );
BOOL xMBMasterPortEventInit( void ); BOOL xMBMasterPortEventInit( void );
BOOL xMBMasterPortEventPost( eMBEventType eEvent ); BOOL xMBMasterPortEventPost( eMBMasterEventType eEvent );
BOOL xMBMasterPortEventGet( /*@out@ */ eMBEventType * eEvent ); BOOL xMBMasterPortEventGet( /*@out@ */ eMBMasterEventType * eEvent );
/* ----------------------- Serial port functions ----------------------------*/ /* ----------------------- Serial port functions ----------------------------*/
@ -100,7 +109,7 @@ void vMBMasterPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable );
INLINE BOOL xMBMasterPortSerialGetByte( CHAR * pucByte ); INLINE BOOL xMBMasterPortSerialGetByte( CHAR * pucByte );
INLINE BOOL xMBPortSerialPutByte( CHAR ucByte ); INLINE BOOL xMBMasterPortSerialPutByte( CHAR ucByte );
/* ----------------------- Timers functions ---------------------------------*/ /* ----------------------- Timers functions ---------------------------------*/
BOOL xMBPortTimersInit( USHORT usTimeOut50us ); BOOL xMBPortTimersInit( USHORT usTimeOut50us );
@ -115,7 +124,11 @@ BOOL xMBMasterPortTimersInit( USHORT usTimeOut50us );
void xMBMasterPortTimersClose( void ); void xMBMasterPortTimersClose( void );
INLINE void vMBMasterPortTimersEnable( void ); INLINE void vMBMasterPortTimersT35Enable( void );
INLINE void vMBMasterPortTimersConvertDelayEnable( void );
INLINE void vMBMasterPortTimersRespondTimeoutEnable( void );
INLINE void vMBMasterPortTimersDisable( void ); INLINE void vMBMasterPortTimersDisable( void );

View File

@ -346,6 +346,7 @@ xMBRTUTimerT35Expired( void )
default: default:
assert_param( ( eRcvState == STATE_RX_INIT ) || assert_param( ( eRcvState == STATE_RX_INIT ) ||
( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) ); ( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) );
break;
} }
vMBPortTimersDisable( ); vMBPortTimersDisable( );

View File

@ -57,13 +57,14 @@ typedef enum
STATE_M_RX_INIT, /*!< Receiver is in initial state. */ STATE_M_RX_INIT, /*!< Receiver is in initial state. */
STATE_M_RX_IDLE, /*!< Receiver is in idle state. */ STATE_M_RX_IDLE, /*!< Receiver is in idle state. */
STATE_M_RX_RCV, /*!< Frame is beeing received. */ 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; } eMBMasterRcvState;
typedef enum typedef enum
{ {
STATE_M_TX_IDLE, /*!< Transmitter is in idle state. */ STATE_M_TX_IDLE, /*!< Transmitter is in idle state. */
STATE_M_TX_XMIT, /*!< Transmitter is in transfer state. */ STATE_M_TX_XMIT, /*!< Transmitter is in transfer state. */
STATE_M_TX_XFWR, /*!< Transmitter is in transfer finish and wait receive state. */
} eMBMasterSndState; } eMBMasterSndState;
/* ----------------------- Static variables ---------------------------------*/ /* ----------------------- Static variables ---------------------------------*/
@ -72,11 +73,11 @@ static volatile eMBMasterRcvState eRcvState;
volatile UCHAR ucMasterRTUBuf[MB_SER_PDU_SIZE_MAX]; volatile UCHAR ucMasterRTUBuf[MB_SER_PDU_SIZE_MAX];
static volatile UCHAR *pucSndBufferCur; static volatile UCHAR *pucMasterSndBufferCur;
static volatile USHORT usSndBufferCount; static volatile USHORT usMasterSndBufferCount;
static volatile USHORT usRcvBufferPos;
static volatile USHORT usMasterRcvBufferPos;
static volatile BOOL bFrameIsBroadcast = FALSE;
/* ----------------------- Start implementation -----------------------------*/ /* ----------------------- Start implementation -----------------------------*/
eMBErrorCode eMBErrorCode
eMBMasterRTUInit(UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ) eMBMasterRTUInit(UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
@ -133,7 +134,7 @@ eMBMasterRTUStart( void )
*/ */
eRcvState = STATE_M_RX_INIT; eRcvState = STATE_M_RX_INIT;
vMBMasterPortSerialEnable( TRUE, FALSE ); vMBMasterPortSerialEnable( TRUE, FALSE );
vMBMasterPortTimersEnable( ); vMBMasterPortTimersT35Enable( );
EXIT_CRITICAL_SECTION( ); EXIT_CRITICAL_SECTION( );
} }
@ -147,179 +148,191 @@ eMBMasterRTUStop( void )
EXIT_CRITICAL_SECTION( ); EXIT_CRITICAL_SECTION( );
} }
//eMBErrorCode eMBErrorCode
//eMBMasterRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength ) eMBMasterRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
//{ {
// BOOL xFrameReceived = FALSE; BOOL xFrameReceived = FALSE;
// eMBErrorCode eStatus = MB_ENOERR; eMBErrorCode eStatus = MB_ENOERR;
//
// ENTER_CRITICAL_SECTION( ); ENTER_CRITICAL_SECTION( );
// assert_param( usRcvBufferPos < MB_SER_PDU_SIZE_MAX ); assert_param( usRcvBufferPos < MB_SER_PDU_SIZE_MAX );
//
// /* Length and CRC check */ /* Length and CRC check */
// if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN ) if( ( usMasterRcvBufferPos >= MB_SER_PDU_SIZE_MIN )
// && ( usMBCRC16( ( UCHAR * ) ucMasterRTUBuf, usRcvBufferPos ) == 0 ) ) && ( usMBCRC16( ( UCHAR * ) ucMasterRTUBuf, usMasterRcvBufferPos ) == 0 ) )
// { {
// /* Save the address field. All frames are passed to the upper layed /* Save the address field. All frames are passed to the upper layed
// * and the decision if a frame is used is done there. * and the decision if a frame is used is done there.
// */ */
// *pucRcvAddress = ucMasterRTUBuf[MB_SER_PDU_ADDR_OFF]; *pucRcvAddress = ucMasterRTUBuf[MB_SER_PDU_ADDR_OFF];
//
// /* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus /* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
// * size of address field and CRC checksum. * size of address field and CRC checksum.
// */ */
// *pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC ); *pusLength = ( USHORT )( usMasterRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );
//
// /* Return the start of the Modbus PDU to the caller. */ /* Return the start of the Modbus PDU to the caller. */
// *pucFrame = ( UCHAR * ) & ucMasterRTUBuf[MB_SER_PDU_PDU_OFF]; *pucFrame = ( UCHAR * ) & ucMasterRTUBuf[MB_SER_PDU_PDU_OFF];
// xFrameReceived = TRUE; xFrameReceived = TRUE;
// } }
// else else
// { {
// eStatus = MB_EIO; eStatus = MB_EIO;
// } }
//
// EXIT_CRITICAL_SECTION( ); EXIT_CRITICAL_SECTION( );
// return eStatus; return eStatus;
//} }
//
//eMBErrorCode eMBErrorCode
//eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength ) eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
//{ {
// eMBErrorCode eStatus = MB_ENOERR; eMBErrorCode eStatus = MB_ENOERR;
// USHORT usCRC16; USHORT usCRC16;
//
// ENTER_CRITICAL_SECTION( ); ENTER_CRITICAL_SECTION( );
//
// /* Check if the receiver is still in idle state. If not we where to /* 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 * slow with processing the received frame and the master sent another
// * frame on the network. We have to abort sending the frame. * frame on the network. We have to abort sending the frame.
// */ */
// if( eRcvState == STATE_M_RX_IDLE ) if( eRcvState == STATE_M_RX_IDLE )
// { {
// /* First byte before the Modbus-PDU is the slave address. */ /* First byte before the Modbus-PDU is the slave address. */
// pucSndBufferCur = ( UCHAR * ) pucFrame - 1; pucMasterSndBufferCur = ( UCHAR * ) pucFrame - 1;
// usSndBufferCount = 1; usMasterSndBufferCount = 1;
//
// /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */ /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
// pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress; pucMasterSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
// usSndBufferCount += usLength; usMasterSndBufferCount += usLength;
//
// /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */ /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
// usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount ); usCRC16 = usMBCRC16( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount );
// ucMasterRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF ); ucMasterRTUBuf[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
// ucMasterRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 ); ucMasterRTUBuf[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
//
// /* Activate the transmitter. */ /* Activate the transmitter. */
// eSndState = STATE_M_TX_XMIT; eSndState = STATE_M_TX_XMIT;
// vMBMasterPortSerialEnable( FALSE, TRUE ); vMBMasterPortSerialEnable( FALSE, TRUE );
// } }
// else else
// { {
// eStatus = MB_EIO; eStatus = MB_EIO;
// } }
// EXIT_CRITICAL_SECTION( ); EXIT_CRITICAL_SECTION( );
// return eStatus; return eStatus;
//} }
//
//BOOL BOOL
//xMBMasterRTUReceiveFSM( void ) xMBMasterRTUReceiveFSM( void )
//{ {
// BOOL xTaskNeedSwitch = FALSE; BOOL xTaskNeedSwitch = FALSE;
// UCHAR ucByte; UCHAR ucByte;
//
// assert_param( eSndState == STATE_TX_IDLE ); assert_param( eSndState == STATE_TX_IDLE );
//
// /* Always read the character. */ /* Always read the character. */
// ( void )xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte ); ( void )xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte );
//
// switch ( eRcvState ) switch ( eRcvState )
// { {
// /* If we have received a character in the init state we have to /* If we have received a character in the init state we have to
// * wait until the frame is finished. * wait until the frame is finished.
// */ */
// case STATE_RX_INIT: case STATE_M_RX_INIT:
// vMBMasterPortTimersEnable( ); vMBMasterPortTimersT35Enable( );
// break; break;
//
// /* In the error state we wait until all characters in the /* In the error state we wait until all characters in the
// * damaged frame are transmitted. * damaged frame are transmitted.
// */ */
// case STATE_RX_ERROR: case STATE_M_RX_ERROR:
// vMBMasterPortTimersEnable( ); vMBMasterPortTimersT35Enable( );
// break; break;
//
// /* In the idle state we wait for a new character. If a character /* 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 * is received the t1.5 and t3.5 timers are started and the
// * receiver is in the state STATE_RX_RECEIVCE. * receiver is in the state STATE_RX_RECEIVCE and disable early
// */ * the timer of respond timeout .
// case STATE_M_RX_IDLE: */
// usRcvBufferPos = 0; case STATE_M_RX_IDLE:
// ucMasterRTUBuf[usRcvBufferPos++] = ucByte; /* In time of respond timeout,the receiver receive a frame.
// eRcvState = STATE_M_RX_RCV; * Disable timer of respond timeout and change the transmiter state to idle.
// */
// /* Enable t3.5 timers. */ vMBMasterPortTimersDisable( );
// vMBMasterPortTimersEnable( ); eSndState = STATE_M_TX_IDLE;
// break;
// usMasterRcvBufferPos = 0;
// /* We are currently receiving a frame. Reset the timer after ucMasterRTUBuf[usMasterRcvBufferPos++] = ucByte;
// * every character received. If more than the maximum possible eRcvState = STATE_M_RX_RCV;
// * number of bytes in a modbus frame is received the frame is
// * ignored. /* Enable t3.5 timers. */
// */ vMBMasterPortTimersT35Enable( );
// case STATE_M_RX_RCV: break;
// if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
// { /* We are currently receiving a frame. Reset the timer after
// ucMasterRTUBuf[usRcvBufferPos++] = ucByte; * every character received. If more than the maximum possible
// } * number of bytes in a modbus frame is received the frame is
// else * ignored.
// { */
// eRcvState = STATE_RX_ERROR; case STATE_M_RX_RCV:
// } if( usMasterRcvBufferPos < MB_SER_PDU_SIZE_MAX )
// vMBMasterPortTimersEnable(); {
// break; ucMasterRTUBuf[usMasterRcvBufferPos++] = ucByte;
// } }
// return xTaskNeedSwitch; else
//} {
// eRcvState = STATE_M_RX_ERROR;
//BOOL }
//xMBMasterRTUTransmitFSM( void ) vMBMasterPortTimersT35Enable();
//{ break;
// BOOL xNeedPoll = FALSE; }
// return xTaskNeedSwitch;
// assert_param( eRcvState == STATE_RX_IDLE ); }
//
// switch ( eSndState ) BOOL
// { xMBMasterRTUTransmitFSM( void )
// /* We should not get a transmitter event if the transmitter is in {
// * idle state. */ BOOL xNeedPoll = FALSE;
// case STATE_M_TX_IDLE:
// /* enable receiver/disable transmitter. */ assert_param( eRcvState == STATE_RX_IDLE );
// vMBMasterPortSerialEnable( TRUE, FALSE );
// break; switch ( eSndState )
// {
// case STATE_M_TX_XMIT: /* We should not get a transmitter event if the transmitter is in
// /* check if we are finished. */ * idle state. */
// if( usSndBufferCount != 0 ) case STATE_M_TX_IDLE:
// { /* enable receiver/disable transmitter. */
// xMBMasterPortSerialPutByte( ( CHAR )*pucSndBufferCur ); vMBMasterPortSerialEnable( TRUE, FALSE );
// pucSndBufferCur++; /* next byte in sendbuffer. */ break;
// usSndBufferCount--;
// } case STATE_M_TX_XMIT:
// else /* check if we are finished. */
// { if( usMasterSndBufferCount != 0 )
// xNeedPoll = xMBMasterPortEventPost( EV_FRAME_SENT ); {
// /* Disable transmitter. This prevents another transmit buffer xMBMasterPortSerialPutByte( ( CHAR )*pucMasterSndBufferCur );
// * empty interrupt. */ pucMasterSndBufferCur++; /* next byte in sendbuffer. */
// vMBMasterPortSerialEnable( TRUE, FALSE ); usMasterSndBufferCount--;
// eSndState = STATE_M_TX_IDLE; }
// } else
// break; {
// } bFrameIsBroadcast = ( ucMasterRTUBuf[MB_SER_PDU_ADDR_OFF] == MB_ADDRESS_BROADCAST ) ? TRUE : FALSE;
// xNeedPoll = xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
// return xNeedPoll; /* 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 BOOL
xMBMasterRTUTimerT35Expired(void) xMBMasterRTUTimerT35Expired(void)
{ {
@ -329,13 +342,13 @@ xMBMasterRTUTimerT35Expired(void)
{ {
/* Timer t35 expired. Startup phase is finished. */ /* Timer t35 expired. Startup phase is finished. */
case STATE_M_RX_INIT: case STATE_M_RX_INIT:
xNeedPoll = xMBMasterPortEventPost(EV_READY); xNeedPoll = xMBMasterPortEventPost(EV_MASTER_READY);
break; break;
/* A frame was received and t35 expired. Notify the listener that /* A frame was received and t35 expired. Notify the listener that
* a new frame was received. */ * a new frame was received. */
case STATE_M_RX_RCV: case STATE_M_RX_RCV:
xNeedPoll = xMBMasterPortEventPost(EV_FRAME_RECEIVED); xNeedPoll = xMBMasterPortEventPost(EV_MASTER_FRAME_RECEIVED);
break; break;
/* An error occured while receiving the frame. */ /* 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 )); ( eRcvState == STATE_M_RX_INIT ) || ( eRcvState == STATE_M_RX_RCV ) || ( eRcvState == STATE_M_RX_ERROR ));
break; break;
} }
vMBMasterPortTimersDisable();
eRcvState = STATE_M_RX_IDLE; eRcvState = STATE_M_RX_IDLE;
//TODO 发送状态在超时后的状态转换需要添加 switch (eSndState)
switch(eSndState)
{ {
/* Timer t35 expired. . */ /* A frame was send finish and convert delay or respond timeout expired.
case STATE_M_TX_XMIT : * 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; return xNeedPoll;
} }
#endif #endif

View File

@ -23,6 +23,7 @@
#define _PORT_H #define _PORT_H
#include <stm32f10x_conf.h> #include <stm32f10x_conf.h>
#include "mbconfig.h"
#include <rthw.h> #include <rthw.h>
#include <rtthread.h> #include <rtthread.h>

View File

@ -23,8 +23,9 @@
#include "mb.h" #include "mb.h"
#include "mbport.h" #include "mbport.h"
#if MB_MASTER_RTU_ENABLED > 0
/* ----------------------- Variables ----------------------------------------*/ /* ----------------------- Variables ----------------------------------------*/
static eMBEventType eMasterQueuedEvent; static eMBMasterEventType eMasterQueuedEvent;
static BOOL xMasterEventInQueue; static BOOL xMasterEventInQueue;
/* ----------------------- Start implementation -----------------------------*/ /* ----------------------- Start implementation -----------------------------*/
@ -36,7 +37,7 @@ xMBMasterPortEventInit( void )
} }
BOOL BOOL
xMBMasterPortEventPost( eMBEventType eEvent ) xMBMasterPortEventPost( eMBMasterEventType eEvent )
{ {
xMasterEventInQueue = TRUE; xMasterEventInQueue = TRUE;
eMasterQueuedEvent = eEvent; eMasterQueuedEvent = eEvent;
@ -44,7 +45,7 @@ xMBMasterPortEventPost( eMBEventType eEvent )
} }
BOOL BOOL
xMBMasterPortEventGet( eMBEventType * eEvent ) xMBMasterPortEventGet( eMBMasterEventType * eEvent )
{ {
BOOL xEventHappened = FALSE; BOOL xEventHappened = FALSE;
@ -56,3 +57,5 @@ xMBMasterPortEventGet( eMBEventType * eEvent )
} }
return xEventHappened; return xEventHappened;
} }
#endif

View File

@ -24,6 +24,8 @@
/* ----------------------- Modbus includes ----------------------------------*/ /* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h" #include "mb.h"
#include "mbport.h" #include "mbport.h"
#if MB_MASTER_RTU_ENABLED > 0
/* ----------------------- static functions ---------------------------------*/ /* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR(void); static void prvvUARTTxReadyISR(void);
static void prvvUARTRxISR(void); static void prvvUARTRxISR(void);
@ -188,3 +190,5 @@ void USART2_IRQHandler(void)
} }
rt_interrupt_leave(); rt_interrupt_leave();
} }
#endif

View File

@ -26,11 +26,15 @@
#include "mb.h" #include "mb.h"
#include "mbport.h" #include "mbport.h"
#if MB_MASTER_RTU_ENABLED > 0
/* ----------------------- Variables ----------------------------------------*/
static USHORT usT35TimeOut50us;
/* ----------------------- static functions ---------------------------------*/ /* ----------------------- static functions ---------------------------------*/
static void prvvTIMERExpiredISR(void); static void prvvTIMERExpiredISR(void);
/* ----------------------- Start implementation -----------------------------*/ /* ----------------------- Start implementation -----------------------------*/
BOOL xMBMasterPortTimersInit(USHORT usTim1Timerout50us) BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us)
{ {
uint16_t PrescalerValue = 0; uint16_t PrescalerValue = 0;
@ -48,7 +52,8 @@ BOOL xMBMasterPortTimersInit(USHORT usTim1Timerout50us)
PrescalerValue = (uint16_t) (SystemCoreClock / 20000) - 1; PrescalerValue = (uint16_t) (SystemCoreClock / 20000) - 1;
//¶¨Ê±Æ÷1³õʼ»¯ //¶¨Ê±Æ÷1³õʼ»¯
TIM_TimeBaseStructure.TIM_Period = (uint16_t) usTim1Timerout50us; usT35TimeOut50us = usTimeOut50us; //保存T35定时器计数值
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
@ -72,8 +77,39 @@ BOOL xMBMasterPortTimersInit(USHORT usTim1Timerout50us)
return TRUE; 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_ClearITPendingBit(TIM2, TIM_IT_Update);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_SetCounter(TIM2, 0); TIM_SetCounter(TIM2, 0);
@ -105,3 +141,5 @@ void TIM2_IRQHandler(void)
} }
rt_interrupt_leave(); rt_interrupt_leave();
} }
#endif