1、【增加】FreeModbus主机请求读写单个、多个寄存器方法,测试通过。处理从机响应的方法还有待完善;

2、【优化】FreeModbus主机忙信号设置相关逻辑;

Signed-off-by: armink <armink.ztl@gmail.com>
This commit is contained in:
armink 2013-09-07 13:33:33 +08:00
parent cefc33de89
commit 3cf7da44e0
6 changed files with 170 additions and 202 deletions

View File

@ -9,6 +9,7 @@ extern int __bss_end;
#endif
uint8_t CpuUsageMajor, CpuUsageMinor; //CPU使用率
USHORT usModbusUserData[MB_PDU_SIZE_MAX];
//====================操作系统各线程优先级==================================
#define thread_SysMonitor_Prio 11
@ -32,8 +33,6 @@ struct rt_thread thread_ModbusMasterPoll;
//******************************************************************
void thread_entry_SysMonitor(void* parameter)
{
extern void vMBMasterWriteHoldReg(UCHAR ucSlaveAddress, USHORT usRegAddress, USHORT ucRegValue);
while (1)
{
cpu_usage_get(&CpuUsageMajor, &CpuUsageMinor);
@ -47,7 +46,11 @@ void thread_entry_SysMonitor(void* parameter)
rt_thread_delay(DELAY_SYS_RUN_LED);
IWDG_Feed(); //喂狗
//Test Modbus Master
vMBMasterWriteHoldReg(1,3,(USHORT)(rt_tick_get()/10));
usModbusUserData[0] = (USHORT)(rt_tick_get()/10);
usModbusUserData[1] = (USHORT)(rt_tick_get()%10);
// eMBMasterFuncWriteHoldingRegister(1,usModbusUserData,3);
// eMBMasterFuncWriteMultipleHoldingRegister(1,usModbusUserData,3,2);
eMBMasterReqReadHoldingRegister(1,3,2);
}
}

View File

@ -68,220 +68,132 @@
#define MB_PDU_FUNC_READWRITE_SIZE_MIN ( 9 )
/* ----------------------- Static functions ---------------------------------*/
eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
/* ----------------------- Start implementation -----------------------------*/
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
eMBException
eMBMasterFuncWriteHoldingRegister( UCHAR ucSndAddr, USHORT * pusDataBuffer, USHORT usRegAddr)
eMBMasterReqErrCode
eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT * pusDataBuffer, USHORT usRegAddr )
{
UCHAR *ucMBFrame;
eMBException eExceStates = MB_EX_NONE;
eMBErrorCode eErrStatus;
UCHAR *ucMBFrame;
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_ETIMEDOUT;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM) eErrStatus = MB_EINVAL;
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
else
{
vMBMasterGetPDUSndBuf(&ucMBFrame);
vMBMasterSetDestAddress(ucSndAddr);
ucMBFrame[MB_PDU_FUNC_OFF] = ( UCHAR ) MB_FUNC_WRITE_REGISTER;
ucMBFrame[MB_PDU_FUNC_READ_ADDR_OFF] = ( UCHAR ) usRegAddr >> 8;
ucMBFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] = ( UCHAR ) usRegAddr;
ucMBFrame[MB_PDU_FUNC_READ_REGCNT_OFF] = ( UCHAR ) pusDataBuffer[0] >> 8;
ucMBFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] = ( UCHAR ) pusDataBuffer[0] ;
vMBMasterSetRTUSndSndLength( MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE );
ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_WRITE_REGISTER;
ucMBFrame[MB_PDU_FUNC_WRITE_ADDR_OFF] = usRegAddr >> 8;
ucMBFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] = usRegAddr;
ucMBFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] = pusDataBuffer[0] >> 8;
ucMBFrame[MB_PDU_FUNC_WRITE_VALUE_OFF + 1] = pusDataBuffer[0] ;
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_FUNC_WRITE_SIZE );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
}
/* If an error occured convert it into a Modbus exception. */
if( eErrStatus != MB_ENOERR )
{
eExceStates = prveMBError2Exception( eErrStatus );
}
return eExceStates;
return eErrStatus;
}
#endif
#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
eMBException
eMBMasterFuncWriteMultipleHoldingRegister( UCHAR ucSndAddr,USHORT * pusDataBuffer, USHORT usRegAddr, USHORT usNRegs)
{
UCHAR *ucMBFrame;
USHORT usRegIndex = 0;
eMBException eExceStatus = MB_EX_NONE;
eMBErrorCode eErrStatus;
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_ETIMEDOUT;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM || usNRegs > MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX) eErrStatus = MB_EINVAL;
eMBMasterReqErrCode
eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,USHORT * pusDataBuffer, USHORT usRegAddr, USHORT usNRegs )
{
UCHAR *ucMBFrame;
USHORT usRegIndex = 0;
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
else
{
vMBMasterGetPDUSndBuf(&ucMBFrame);
vMBMasterSetDestAddress(ucSndAddr);
ucMBFrame[MB_PDU_FUNC_OFF] = ( UCHAR ) MB_FUNC_WRITE_MULTIPLE_REGISTERS;
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] = ( UCHAR ) usRegAddr >> 8;
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] = ( UCHAR ) usRegAddr;
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF] = ( UCHAR ) usNRegs >> 8;
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF + 1] = ( UCHAR ) usNRegs ;
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF] = ( UCHAR ) usNRegs * 2;
ucMBFrame += MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF + 1;
while( usNRegs-- > 0)
ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_WRITE_MULTIPLE_REGISTERS;
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] = usRegAddr >> 8;
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] = usRegAddr;
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF] = usNRegs >> 8;
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF + 1] = usNRegs ;
ucMBFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF] = usNRegs * 2;
ucMBFrame += MB_PDU_FUNC_WRITE_MUL_VALUES_OFF;
while( usNRegs > usRegIndex)
{
*ucMBFrame++ = pusDataBuffer[usRegIndex] >> 8;
*ucMBFrame++ = pusDataBuffer[usRegIndex++] ;
}
vMBMasterSetRTUSndSndLength( MB_PDU_SIZE_MIN + MB_PDU_FUNC_WRITE_MUL_SIZE_MIN + 2*usNRegs );
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_FUNC_WRITE_MUL_SIZE_MIN + 2*usNRegs );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
}
/* If an error occured convert it into a Modbus exception. */
if( eErrStatus != MB_ENOERR )
{
eExceStatus = prveMBError2Exception( eErrStatus );
}
return eExceStatus;
return eErrStatus;
}
#endif
#if MB_FUNC_READ_HOLDING_ENABLED > 0
eMBException
eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
eMBMasterReqErrCode
eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs )
{
USHORT usRegAddress;
USHORT usRegCount;
UCHAR *pucFrameCur;
UCHAR *ucMBFrame;
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
usRegAddress++;
usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8 );
usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );
/* Check if the number of registers to read is valid. If not
* return Modbus illegal data value exception.
*/
if( ( usRegCount >= 1 ) && ( usRegCount <= MB_PDU_FUNC_READ_REGCNT_MAX ) )
{
/* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READ_HOLDING_REGISTER;
*usLen += 1;
/* Second byte in the response contain the number of bytes. */
*pucFrameCur++ = ( UCHAR ) ( usRegCount * 2 );
*usLen += 1;
/* Make callback to fill the buffer. */
eRegStatus = eMBRegHoldingCB( pucFrameCur, usRegAddress, usRegCount, MB_REG_READ );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
else
{
*usLen += usRegCount * 2;
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
else
{
/* Can't be a valid request because the length is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
vMBMasterGetPDUSndBuf(&ucMBFrame);
vMBMasterSetDestAddress(ucSndAddr);
ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_READ_HOLDING_REGISTER;
ucMBFrame[MB_PDU_FUNC_READ_ADDR_OFF] = usRegAddr >> 8;
ucMBFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] = usRegAddr;
ucMBFrame[MB_PDU_FUNC_READ_REGCNT_OFF] = usNRegs >> 8;
ucMBFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] = usNRegs;
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
}
return eStatus;
return eErrStatus;
}
#endif
#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
eMBException
eMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
eMBMasterReqErrCode
eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,USHORT * pusDataBuffer, USHORT usReadRegAddr, USHORT usNReadRegs ,
USHORT usWriteRegAddr, USHORT usNWriteRegs)
{
USHORT usRegReadAddress;
USHORT usRegReadCount;
USHORT usRegWriteAddress;
USHORT usRegWriteCount;
UCHAR ucRegWriteByteCount;
UCHAR *pucFrameCur;
UCHAR *ucMBFrame;
USHORT usRegIndex = 0;
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen >= ( MB_PDU_FUNC_READWRITE_SIZE_MIN + MB_PDU_SIZE_MIN ) )
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
else
{
usRegReadAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF] << 8U );
usRegReadAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF + 1] );
usRegReadAddress++;
usRegReadCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF] << 8U );
usRegReadCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF + 1] );
usRegWriteAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF] << 8U );
usRegWriteAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF + 1] );
usRegWriteAddress++;
usRegWriteCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF] << 8U );
usRegWriteCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF + 1] );
ucRegWriteByteCount = pucFrame[MB_PDU_FUNC_READWRITE_BYTECNT_OFF];
if( ( usRegReadCount >= 1 ) && ( usRegReadCount <= 0x7D ) &&
( usRegWriteCount >= 1 ) && ( usRegWriteCount <= 0x79 ) &&
( ( 2 * usRegWriteCount ) == ucRegWriteByteCount ) )
{
/* Make callback to update the register values. */
eRegStatus = eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_READWRITE_WRITE_VALUES_OFF],
usRegWriteAddress, usRegWriteCount, MB_REG_WRITE );
if( eRegStatus == MB_ENOERR )
{
/* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READWRITE_MULTIPLE_REGISTERS;
*usLen += 1;
/* Second byte in the response contain the number of bytes. */
*pucFrameCur++ = ( UCHAR ) ( usRegReadCount * 2 );
*usLen += 1;
/* Make the read callback. */
eRegStatus =
eMBRegHoldingCB( pucFrameCur, usRegReadAddress, usRegReadCount, MB_REG_READ );
if( eRegStatus == MB_ENOERR )
{
*usLen += 2 * usRegReadCount;
}
}
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
vMBMasterGetPDUSndBuf(&ucMBFrame);
vMBMasterSetDestAddress(ucSndAddr);
ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_READWRITE_MULTIPLE_REGISTERS;
ucMBFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF] = usReadRegAddr >> 8;
ucMBFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF + 1] = usReadRegAddr;
ucMBFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF] = usNReadRegs >> 8;
ucMBFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF + 1] = usNReadRegs ;
ucMBFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF] = usWriteRegAddr >> 8;
ucMBFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF + 1] = usWriteRegAddr;
ucMBFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF] = usNWriteRegs >> 8;
ucMBFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF + 1] = usNWriteRegs ;
ucMBFrame[MB_PDU_FUNC_READWRITE_BYTECNT_OFF] = usNWriteRegs * 2;
ucMBFrame += MB_PDU_FUNC_READWRITE_WRITE_VALUES_OFF;
while( usNWriteRegs > usRegIndex)
{
*ucMBFrame++ = pusDataBuffer[usRegIndex] >> 8;
*ucMBFrame++ = pusDataBuffer[usRegIndex++] ;
}
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_FUNC_READWRITE_SIZE_MIN + 2*usNWriteRegs );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
}
return eStatus;
return eErrStatus;
}
#endif

View File

@ -69,7 +69,31 @@ PR_BEGIN_EXTERN_C
#define MB_MASTER_TCP_PORT_USE_DEFAULT 0
/* ----------------------- Type definitions ---------------------------------*/
/*! \ingroup modbus
* \brief Errorcodes used by all function in the Master request.
*/
typedef enum
{
MB_MRE_NO_ERR, /*!< no error. */
MB_MRE_NO_REG, /*!< illegal register address. */
MB_MRE_ILL_ARG, /*!< illegal argument. */
MB_MRE_PORT_ERR, /*!< porting layer error. */
MB_MRE_NO_RES, /*!< insufficient resources. */
MB_MRE_IO, /*!< I/O error. */
MB_MRE_ILL_STATE, /*!< protocol stack in illegal state. */
MB_MRE_TIMEDOUT, /*!< timeout error occurred. */
MB_MRE_MASTER_BUSY, /*!< master is busy now. */
MB_MRE_SLAVE_EXCE /*!< slave has exception. */
} eMBMasterReqErrCode;
/*! \ingroup modbus
* \brief TimerMode is Master 3 kind of Timer modes.
*/
typedef enum
{
MB_TMODE_T35, /*!< Master receive frame T3.5 timeout. */
MB_TMODE_RESPOND_TIMEOUT, /*!< Master wait respond for slave. */
MB_TMODE_CONVERT_DELAY /*!< Master sent broadcast ,then delay sometime.*/
}eMBMasterTimerMode;
/* ----------------------- Function prototypes ------------------------------*/
/*! \ingroup modbus
@ -165,19 +189,33 @@ eMBErrorCode eMBMasterDisable( void );
*/
eMBErrorCode eMBMasterPoll( void );
/* Get Modbus Master busy flag,It will return TRUE when Master is busy. */
BOOL xMBMasterGetIsBusy( void );
/*! \ingroup modbus
*\brief These Modbus functions are called for user when Modbus run in Master Mode.
*/
eMBMasterReqErrCode
eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT * pusDataBuffer, USHORT usRegAddr );
eMBMasterReqErrCode
eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,USHORT * pusDataBuffer, USHORT usRegAddr, USHORT usNRegs );
eMBMasterReqErrCode
eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs );
eMBMasterReqErrCode
eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,USHORT * pusDataBuffer, USHORT usReadRegAddr, USHORT usNReadRegs ,
USHORT usWriteRegAddr, USHORT usNWriteRegs);
/*£¡ \ingroup modbus
*\brief These functions are interface for Modbus Master
*/
BOOL xMBMasterGetIsBusy( void );
void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame );
UCHAR ucMBMasterGetDestAddress( void );
void vMBMasterSetDestAddress( UCHAR Address );
void vMBMasterSetIsBusy( BOOL IsBusy );
BOOL xMBMasterGetCBRunInMasterMode( void );
void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode );
/* Get Modbus Master send PDU's buffer length.*/
UCHAR ucMBMasterGetPDUSndLength( void );
/* Set Modbus Master send PDU's buffer length.*/
void vMBMasterSetRTUSndSndLength( UCHAR SendPDULength );
void vMBMasterSetPDUSndLength( UCHAR SendPDULength );
void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode );
/* ----------------------- Callback -----------------------------------------*/

View File

@ -308,7 +308,9 @@ eMBMasterPoll( void )
}
/* If receive frame has exception .The receive function code highest bit is 1.*/
if(ucFunctionCode >> 7) eException = (eMBException)ucMBFrame[MB_PDU_DATA_OFF];
/* If master has exception ,Master will send error process.Otherwise the Master is idle.*/
if (eException != MB_EX_NONE) ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
else vMBMasterSetIsBusy( FALSE );
break;
case EV_MASTER_FRAME_SENT:
@ -319,54 +321,41 @@ eMBMasterPoll( void )
break;
case EV_MASTER_ERROR_PROCESS:
vMBMasterSetIsBusy( FALSE );
break;
}
}
return MB_ENOERR;
}
/* Get whether the Modbus Master is busy.*/
BOOL xMBMasterGetIsBusy( void )
{
return xMasterIsBusy;
}
/* Set whether the Modbus Master is busy.*/
void vMBMasterSetIsBusy( BOOL IsBusy )
{
xMasterIsBusy = IsBusy;
}
/* Get whether the Modbus Master is run in master mode.*/
BOOL xMBMasterGetCBRunInMasterMode( void )
{
return xMBRunInMasterMode;
}
/* Set whether the Modbus Master is run in master mode.*/
void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode )
{
xMBRunInMasterMode = IsMasterMode;
}
/* Get Modbus Master send destination address*/
UCHAR ucMBMasterGetDestAddress( void )
{
return ucMBMasterDestAddress;
}
/* Set Modbus Master send destination address*/
void vMBMasterSetDestAddress( UCHAR Address )
{
ucMBMasterDestAddress = Address;
}
//Test Modbus Master
void vMBMasterWriteHoldReg(UCHAR ucSlaveAddress, USHORT usRegAddress, USHORT ucRegValue)
{
static UCHAR *ucMBFrame;
vMBMasterGetPDUSndBuf( &ucMBFrame );
vMBMasterSetDestAddress(ucSlaveAddress);
ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_WRITE_REGISTER;
ucMBFrame[MB_PDU_DATA_OFF + 0] = usRegAddress >> 8;
ucMBFrame[MB_PDU_DATA_OFF + 1] = usRegAddress;
ucMBFrame[MB_PDU_DATA_OFF + 2] = ucRegValue >> 8;
ucMBFrame[MB_PDU_DATA_OFF + 3] = ucRegValue ;
vMBMasterSetRTUSndSndLength(5);
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
}
#endif

View File

@ -37,6 +37,7 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mb_m.h"
#include "mbrtu.h"
#include "mbframe.h"
@ -80,6 +81,9 @@ static volatile USHORT usMasterSndBufferCount;
static volatile USHORT usMasterRcvBufferPos;
static volatile BOOL xFrameIsBroadcast = FALSE;
static volatile eMBMasterTimerMode eMasterCurTimerMode;
/* ----------------------- Start implementation -----------------------------*/
eMBErrorCode
eMBMasterRTUInit(UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
@ -325,8 +329,14 @@ xMBMasterRTUTransmitFSM( void )
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 ( xFrameIsBroadcast == TRUE ) vMBMasterPortTimersConvertDelayEnable( );
else vMBMasterPortTimersRespondTimeoutEnable( );
if ( xFrameIsBroadcast == TRUE )
{
vMBMasterPortTimersConvertDelayEnable( );
}
else
{
vMBMasterPortTimersRespondTimeoutEnable( );
}
}
break;
}
@ -379,9 +389,9 @@ xMBMasterRTUTimerExpired(void)
}
eSndState = STATE_M_TX_IDLE;
vMBMasterPortTimersDisable();
/* Master is idel now. */
vMBMasterSetIsBusy(FALSE);
vMBMasterPortTimersDisable( );
/* If timer mode is convert delay ,then Master is idel now. */
if (eMasterCurTimerMode == MB_TMODE_CONVERT_DELAY) vMBMasterSetIsBusy( FALSE );
return xNeedPoll;
}
@ -395,11 +405,11 @@ void vMBMasterGetRTUSndBuf( UCHAR ** pucFrame )
/* Get Modbus Master send PDU's buffer address pointer.*/
void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame )
{
*pucFrame = ( UCHAR * ) ucMasterRTUSndBuf[MB_SER_PDU_PDU_OFF];
*pucFrame = ( UCHAR * ) &ucMasterRTUSndBuf[MB_SER_PDU_PDU_OFF];
}
/* Set Modbus Master send PDU's buffer length.*/
void vMBMasterSetRTUSndSndLength( UCHAR SendPDULength )
void vMBMasterSetPDUSndLength( UCHAR SendPDULength )
{
ucMasterSendPDULength = SendPDULength;
}
@ -409,5 +419,11 @@ UCHAR ucMBMasterGetPDUSndLength( void )
{
return ucMasterSendPDULength;
}
/* Set Modbus Master current timer mode.*/
void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode )
{
eMasterCurTimerMode = eMBTimerMode;
}
#endif

View File

@ -24,6 +24,7 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mb_m.h"
#include "mbport.h"
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED
@ -72,6 +73,9 @@ BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us)
void vMBMasterPortTimersT35Enable()
{
/* Set current timer mode,don't change it.*/
vMBMasterSetCurTimerMode(MB_TMODE_T35);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Prescaler = usPrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
@ -87,6 +91,9 @@ void vMBMasterPortTimersT35Enable()
void vMBMasterPortTimersConvertDelayEnable()
{
/* Set current timer mode,don't change it.*/
vMBMasterSetCurTimerMode(MB_TMODE_CONVERT_DELAY);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Prescaler = usPrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
@ -102,6 +109,9 @@ void vMBMasterPortTimersConvertDelayEnable()
void vMBMasterPortTimersRespondTimeoutEnable()
{
/* Set current timer mode,don't change it.*/
vMBMasterSetCurTimerMode(MB_TMODE_RESPOND_TIMEOUT);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Prescaler = usPrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;