这里写目录标题
初始化
//初始化函数
//初始化 RTU模式 从机地址为1 USART1 9600 无校验
eMBInit(MB_RTU, 0x01, 1, 115200, MB_PAR_ODD);
eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
{
eMBErrorCode eStatus = MB_ENOERR;
if( ( ucSlaveAddress == MB_ADDRESS_BROADCAST ) ||
( ucSlaveAddress < MB_ADDRESS_MIN ) || ( ucSlaveAddress > MB_ADDRESS_MAX ) )
{
eStatus = MB_EINVAL;
}
else
{
ucMBAddress = ucSlaveAddress;
/*这里根据所选择的模式,将函数指针指向不同的模式下对应的函数*/
switch ( eMode )
{
#if MB_RTU_ENABLED > 0
case MB_RTU:
pvMBFrameStartCur = eMBRTUStart;
pvMBFrameStopCur = eMBRTUStop;
peMBFrameSendCur = eMBRTUSend;
peMBFrameReceiveCur = eMBRTUReceive;
pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBPortClose : NULL;
pxMBFrameCBByteReceived = xMBRTUReceiveFSM;
pxMBFrameCBTransmitterEmpty = xMBRTUTransmitFSM;
pxMBPortCBTimerExpired = xMBRTUTimerT35Expired;
eStatus = eMBRTUInit( ucMBAddress, ucPort, ulBaudRate, eParity );
break;
#endif
#if MB_ASCII_ENABLED > 0
case MB_ASCII:
pvMBFrameStartCur = eMBASCIIStart;
pvMBFrameStopCur = eMBASCIIStop;
peMBFrameSendCur = eMBASCIISend;
peMBFrameReceiveCur = eMBASCIIReceive;
pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBPortClose : NULL;
pxMBFrameCBByteReceived = xMBASCIIReceiveFSM;
pxMBFrameCBTransmitterEmpty = xMBASCIITransmitFSM;
pxMBPortCBTimerExpired = xMBASCIITimerT1SExpired;
eStatus = eMBASCIIInit( ucMBAddress, ucPort, ulBaudRate, eParity );
break;
#endif
default:
eStatus = MB_EINVAL;
}
if( eStatus == MB_ENOERR )
{
if( !xMBPortEventInit( ) )
{
eStatus = MB_EPORTERR;
}
else
{
eMBCurrentMode = eMode;
eMBState = STATE_DISABLED;
}
}
}
return eStatus;
}
支持三种模式
typedef enum
{ MB_RTU,
MB_ASCII,
MB_TCP
} eMBMode;
状态参数
typedef enum
{
MB_ENOERR, /*!< 无误. */
MB_ENOREG, /*!< 错误寄存器地址 */
MB_EINVAL, /*!< 错误参数. */
MB_EPORTERR, /*!< 端口初始化失败. */
MB_ENORES, /*!< 资源不足 */
MB_EIO, /*!< I/O 错误*/
MB_EILLSTATE, /*!< 协议栈处于非法状态 */
MB_ETIMEDOUT /*!< 超时 */
} eMBErrorCode;
#define MB_ADDRESS_BROADCAST ( 0 ) /*广播地址*/
#define MB_ADDRESS_MIN ( 1 ) /* 最小设备地址*/
#define MB_ADDRESS_MAX ( 247 ) /*最大允许设备地址*/
总中断开关
#define ENTER_CRITICAL_SECTION( ) __disable_irq();
#define EXIT_CRITICAL_SECTION( ) __enable_irq();
开启rtu
void
eMBRTUStart( void )
{
ENTER_CRITICAL_SECTION( );
eRcvState = STATE_RX_INIT;
vMBPortSerialEnable( TRUE, FALSE );
vMBPortTimersEnable( );
EXIT_CRITICAL_SECTION( );
}
串口使能
void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
/* If xRXEnable enable serial receive interrupts. If xTxENable enable
* transmitter empty interrupts.
*/
if(xRxEnable)
{
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); // 使能接收非空中断
}
else
{
__HAL_UART_DISABLE_IT(&huart1, UART_IT_RXNE); // 禁能接收非空中断
}
if(xTxEnable)
{
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE); // 使能发送为空中断
}
else
{
__HAL_UART_DISABLE_IT(&huart1, UART_IT_TXE); // 禁能发送为空中断
}
}
开启定时器
inline void
vMBPortTimersEnable( )
{
__HAL_TIM_CLEAR_IT(&htim4,TIM_IT_UPDATE);
__HAL_TIM_SET_COUNTER(&htim4, 0); // 清空计数器
__HAL_TIM_ENABLE(&htim4);
}
数据格式
从机地址为0x01
功能代码0x04
寄存器地址0X0000 (即缓存数组的角标,这里从第0个开始读)