1、【更新】《FreeModbus 主机分析图》中关于发送及接受状态图,其余还需后期完善;
2、【增加】FreeModbus主机传输层逻辑实现,稳定性还需后期测试; Signed-off-by: armink <armink.ztl@gmail.com>
This commit is contained in:
parent
31fab3ed4d
commit
dfe745c166
Binary file not shown.
|
@ -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 );
|
||||
|
||||
|
|
|
@ -346,6 +346,7 @@ xMBRTUTimerT35Expired( void )
|
|||
default:
|
||||
assert_param( ( eRcvState == STATE_RX_INIT ) ||
|
||||
( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) );
|
||||
break;
|
||||
}
|
||||
|
||||
vMBPortTimersDisable( );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define _PORT_H
|
||||
|
||||
#include <stm32f10x_conf.h>
|
||||
#include "mbconfig.h"
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue