diff --git a/APP/src/app_task.c b/APP/src/app_task.c index 3d39463..56a4e4c 100644 --- a/APP/src/app_task.c +++ b/APP/src/app_task.c @@ -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); } } diff --git a/FreeModbus/modbus/functions/mbfuncholding_m.c b/FreeModbus/modbus/functions/mbfuncholding_m.c index c4539e8..5cc2fbd 100644 --- a/FreeModbus/modbus/functions/mbfuncholding_m.c +++ b/FreeModbus/modbus/functions/mbfuncholding_m.c @@ -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) + +eMBMasterReqErrCode +eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,USHORT * pusDataBuffer, USHORT usRegAddr, USHORT usNRegs ) { - UCHAR *ucMBFrame; - USHORT usRegIndex = 0; - eMBException eExceStatus = MB_EX_NONE; - eMBErrorCode eErrStatus; + UCHAR *ucMBFrame; + USHORT usRegIndex = 0; + eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR; - if ( xMBMasterGetIsBusy() ) eErrStatus = MB_ETIMEDOUT; - else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM || usNRegs > MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX) 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_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; - - 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] ); + UCHAR *ucMBFrame; + eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR; - /* 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; - - eMBException eStatus = MB_EX_NONE; - eMBErrorCode eRegStatus; + UCHAR *ucMBFrame; + USHORT usRegIndex = 0; + eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR; - 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 diff --git a/FreeModbus/modbus/include/mb_m.h b/FreeModbus/modbus/include/mb_m.h index 95fc551..f4ee5b5 100644 --- a/FreeModbus/modbus/include/mb_m.h +++ b/FreeModbus/modbus/include/mb_m.h @@ -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 -----------------------------------------*/ diff --git a/FreeModbus/modbus/mb_m.c b/FreeModbus/modbus/mb_m.c index e9c9109..eb16ef1 100644 --- a/FreeModbus/modbus/mb_m.c +++ b/FreeModbus/modbus/mb_m.c @@ -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 diff --git a/FreeModbus/modbus/rtu/mbrtu_m.c b/FreeModbus/modbus/rtu/mbrtu_m.c index 190aed7..1629f39 100644 --- a/FreeModbus/modbus/rtu/mbrtu_m.c +++ b/FreeModbus/modbus/rtu/mbrtu_m.c @@ -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 diff --git a/FreeModbus/port/porttimer_m.c b/FreeModbus/port/porttimer_m.c index 17719e3..c5dc612 100644 --- a/FreeModbus/port/porttimer_m.c +++ b/FreeModbus/port/porttimer_m.c @@ -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;