- 传统 modbus rtu主站源代码port串口是采用单个字节发送,但是stm32 hal库提供一帧发送、一帧接收,同时提供完成的中断处理。如果不直接采用hal库会带来不必要的工作难度
- 因此,修改modbus rtu主站代码,使其适用于stm32 hal库
- 整体思想:
- 不使用原中断服务函数xMBMasterRTUReceiveFSM,将对应功能移植到合适地方
- 不使用原中断服务函数xMBMasterRTUTransmitFSM,将对应功能移植到合适地方
- portserial.c需要修改
- 串口使能函数
-
if( xRxEnable ==TRUE)/*串口接收使能*/{HAL_GPIO_WritePin(UART3_DE3_GPIO_Port, UART3_DE3_Pin, GPIO_PIN_RESET);// __HAL_UART_ENABLE_IT(&huart3,UART_IT_RXNE);//获取接收buffer的地址vMBMasterGetRTURcvBuf( &pucFrame );//由于需要发送数据的地方都调用了该函数,因此作为统一的收、发接口//使用hal库自带的串口功能(中断模式)//由于每次不会接收到完成长度,使用前要复位以下状态机 // huart3.RxState=HAL_UART_STATE_READY;HAL_UART_Receive_IT(&huart3,pucFrame,MB_SER_PDU_SIZE_MAX);}if( xTxEnable ==TRUE)/*串口发送使能*/{HAL_GPIO_WritePin(UART3_DE3_GPIO_Port, UART3_DE3_Pin, GPIO_PIN_SET);// __HAL_UART_ENABLE_IT(&huart3,UART_IT_TXE);// prvvMasterUARTTxReadyISR();//获取发送bufer的地址vMBMasterGetRTUSndBuf( &pucFrame );//获取需要发送的长度SndBufferLength=vMBMasterGetRTUSndBufCount();//由于需要发送数据的地方都调用了该函数,因此作为统一的收、发接口//使用hal库自带的串口功能(中断模式)HAL_UART_Transmit_IT(&huart3,pucFrame,SndBufferLength );}
- hal_uart.c需要修改
-
UART_Receive_IT函数
-
//主站if(huart ->Instance == USART3){//切换SndState,这样下次进定时器中断才不会认定为超时xMBMasterSetSndState(STATE_M_TX_IDLE);//切换RcvState,这样下次进定时器会认定为接收完一帧xMBMasterSetRcvState(STATE_M_RX_RCV);/* Enable t3.5 timers. */vMBMasterPortTimersEnable( );}
-
- 添加串口发送完成回调函数HAL_UART_TxCpltCallback
-
//主站if(huart->Instance==USART3 ){//主站发送完成后处理函数xMBMasterForHalTxCpltCallback();}/*** @brief 给 HAL_UART_TxCpltCallback()回调函数使用——接收完成* 由于很多变量都是.c文件内部static变量,不能外部调用,淫才采用该方法* @param None* @retval None*/ void xMBMasterForHalTxCpltCallback(void) {xFrameIsBroadcast = ( ucMasterRTUSndBuf[MB_SER_PDU_ADDR_OFF] == MB_ADDRESS_BROADCAST ) ? TRUE : FALSE;eMasterSndState = 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( );}/* Disable transmitter. This prevents another transmit buffer* empty interrupt. */vMBMasterPortSerialEnable( TRUE, FALSE ); }
-
- mbuart_m.c需要修改
- 定时器中断服务函数 xMBMasterRTUTimerExpired
-
case STATE_M_RX_RCV://接收完成,从huart结构体复制数据//接收完成后,获取接收帧的长度usMasterRcvBufferPos=(huart3.RxXferSize)-(huart3.RxXferCount);//切换状态机,否则下次调用HAL_UART_Receive_IT 不会进去/* Rx process is completed, restore huart->RxState to Ready */huart3.RxState = HAL_UART_STATE_READY; case STATE_M_TX_XFWR://切换状态机,否则下次调用HAL_UART_Receive_IT 不会进去/* Rx process is completed, restore huart->RxState to Ready */huart3.RxState = HAL_UART_STATE_READY;
详细解决方案
Modbus RTU主站移植到stm32 hal库
热度:83 发布时间:2023-12-18 09:10:43.0
相关解决方案
- STM32 串口通信以致hard fault 产生
- stm32 入门困难吗?解决方法
- stm32 PWM有关问题
- STM32 spi采集ADC128S022误差很大,下面是小弟我的记录值和误差,如何减小误差
- can协议 发送自动重传模式 深入的有关问题 STM32
- STM32 USB 驱动,该怎么解决
- stm32 串口,该怎么处理
- STM32 通用IO模拟串口
- 工作需要半个月让小弟我写四个驱动程序,Opc,DDE,MODBUS Tcp/Ip, 数据库驱动,以前都没接触过。时间紧,另外还有两个控件要调试。请各位前辈指教指教
- STM32 TIM4 输出比较模式 有关问题
- STM32 IAP程序编写解决方法
- stm32 spi 为何CS总是会自动拉高呢
- modbus TCP串口通信解决方案
- stm32-ADC学习,该怎么解决
- stm32 中地址的懂得
- stm32-野火DAC实验之DAC触发源~解决思路
- stm32 数据与地址的懂得
- stm32 基础知识求解解决思路
- stm32 .c .h文件治理
- stm32 编译预加工求解
- stm32 刚入手 有关问题求解
- stm32 C语言 define viod 0的了解
- stm32 IO口输出高电平失败啊
- STM32 GPIO输出高下电平转换速率测试
- freeRtos stm32 的ADC中断有关问题
- stm32 怎么入门
- stm32 spi时序看不懂解决方法
- stm32 flash擦写解决方法
- STM32 ucGUI 有关问题
- STM32 串口通信罗致hard fault 产生