企业 网站 建设 规范,内容营销的经典案例,江门网站快速排名优化,张家界网站目录 一、前言二、实验核心逻辑#xff1a;双串口主从任务设计三、实验现象与功能验证四、总结五、结尾 一、前言 在上一篇笔记中#xff0c;我们完成了 libmodbus 适配 STM32 板载串口后端的核心代码改造#xff0c;实现了板载串口与 libmodbus 协议层的解耦与统一管理…目录一、前言二、实验核心逻辑双串口主从任务设计三、实验现象与功能验证四、总结五、结尾一、前言在上一篇笔记中我们完成了 libmodbus 适配 STM32 板载串口后端的核心代码改造实现了板载串口与 libmodbus 协议层的解耦与统一管理。本次实验基于该改造成果搭建双串口主从通信场景将 UART2 作为 Modbus 主机Client发送请求UART4 作为 Modbus 从机Server接收并响应请求通过 LED 闪烁、LCD 显示寄存器累加数值的直观现象验证板载串口后端的实际运行效果。二、实验核心逻辑双串口主从任务设计实验通过 FreeRTOS 创建两个独立任务分别实现 Modbus 主机UART2与从机UART4的核心逻辑同时在 FreeRTOS 初始化函数中完成任务创建以下是完整代码关键逻辑已添加注释未修改原有代码1. 从机任务CH2_UART4_ServerTaskUART4 接收请求并响应staticvoidCH2_UART4_ServerTask(void*pvParameters){uint8_t*query;// 请求报文缓冲区modbus_t*ctx;// Modbus从机上下文intrc;// 函数返回值modbus_mapping_t*mb_mapping;// 寄存器映射结构体charbuf[100];// 临时缓冲区未使用intcnt0;// 计数变量未使用// 创建UART4的RTU上下文波特率115200、无校验、8数据位、1停止位ctxmodbus_new_st_rtu(uart4,115200,N,8,1);modbus_set_slave(ctx,1);// 设置从机地址为1querypvPortMalloc(MODBUS_RTU_MAX_ADU_LENGTH);// 分配请求缓冲区// 初始化寄存器映射四类寄存器起始地址0数量各10mb_mappingmodbus_mapping_new_start_address(0,10,0,10,0,10,0,10);// 初始化线圈寄存器为0LED初始熄灭memset(mb_mapping-tab_bits,0,mb_mapping-nb_bits);// 初始化保持寄存器为0x55测试用初始值memset(mb_mapping-tab_registers,0x55,mb_mapping-nb_registers*2);// 建立UART4串口连接rcmodbus_connect(ctx);if(rc-1){//fprintf(stderr, Unable to connect %s\n, modbus_strerror(errno));modbus_free(ctx);vTaskDelete(NULL);;// 连接失败则删除任务}// 无限循环接收并响应主机请求for(;;){do{// 接收主机请求报文过滤无效请求返回0的查询rcmodbus_receive(ctx,query);/* Filtered queries return 0 */}while(rc0);/* The connection is not closed on errors which require on reply such as bad CRC in RTU. */// 非CRC错误则继续循环if(rc-1errno!EMBBADCRC){/* Quit */continue;}// 解析请求并回复主机rcmodbus_reply(ctx,query,rc,mb_mapping);if(rc-1){//break;}// 线圈寄存器第0位控制PC12引脚LED1点亮0熄灭if(mb_mapping-tab_bits[0])HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_RESET);elseHAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_SET);// 延时1秒后保持寄存器1的值自增1vTaskDelay(1000);mb_mapping-tab_registers[1];}// 释放资源实际循环不会执行到此处modbus_mapping_free(mb_mapping);vPortFree(query);modbus_close(ctx);modbus_free(ctx);vTaskDelete(NULL);}2. 主机任务CH1_UART2_ClientTaskUART2 发送请求staticvoidCH1_UART2_ClientTask(void*pvParameters){modbus_t*ctx;// Modbus主机上下文intrc;// 函数返回值uint16_tval;// 存储读取的寄存器值intnb1;// 单次读取的寄存器数量intlevel1;// LED控制电平初始为1charbuf[100];// 临时缓冲区未使用intcnt0;// 计数变量未使用// 创建UART2的RTU上下文波特率115200、无校验、8数据位、1停止位ctxmodbus_new_st_rtu(uart2,115200,N,8,1);modbus_set_slave(ctx,1);// 设置目标从机地址为1// 建立UART2串口连接rcmodbus_connect(ctx);if(rc-1){//fprintf(stderr, Unable to connect %s\n, modbus_strerror(errno));modbus_free(ctx);vTaskDelete(NULL);;// 连接失败则删除任务}// 无限循环执行主机操作for(;;){/* read hoding register 1 */// 读取从机保持寄存器1的值rcmodbus_read_registers(ctx,1,nb,val);if(rc!nb){continue;// 读取失败则跳过本次循环}/* display on lcd */// 将读取到的寄存器值显示在LCD屏幕上Draw_Number(0,0,val,0xff0000);/* delay 2s */// 延时2秒后翻转LED控制电平并写入从机线圈寄存器0vTaskDelay(2000);modbus_write_bit(ctx,0,level);level!level;}// 释放资源实际循环不会执行到此处modbus_close(ctx);modbus_free(ctx);vTaskDelete(NULL);}3. FreeRTOS 任务初始化voidMX_FREERTOS_Init(void){// 创建主机任务UART2客户端任务xTaskCreate(CH1_UART2_ClientTask,CH1_UART2_ClientTask,200,// 任务栈大小NULL,osPriorityNormal,// 任务优先级NULL);// 创建从机任务UART4服务端任务xTaskCreate(CH2_UART4_ServerTask,CH2_UART4_ServerTask,200,// 任务栈大小NULL,osPriorityNormal,// 任务优先级NULL);}补充双任务均采用osPriorityNormal普通优先级栈大小配置为 200适配本实验的轻量通信需求若需扩展功能如更多寄存器操作、复杂数据处理可适当增大栈大小。三、实验现象与功能验证烧录程序后开发板呈现以下核心现象验证双串口主从通信逻辑正常LED 闪烁主机每 2 秒翻转一次从机线圈寄存器 0 的电平从机根据该值控制 LED 亮灭实现周期性闪烁LCD 数值累加从机每 1 秒将保持寄存器 1 的值自增 1主机每 2 秒读取该值并显示在 LCD 上可见数值持续累加。实验效果如下图所示四、总结实验基于双串口UART2 主机、UART4 从机搭建主从通信场景验证了板载串口作为 libmodbus 后端的有效性主机任务实现寄存器读取、LCD 显示、LED 电平控制从机任务实现请求响应、寄存器累加、LED 硬件联动功能闭环完整FreeRTOS 双任务调度稳定核心现象LED 闪烁、数值累加符合预期证明代码改造与任务设计的正确性。五、结尾本次实验完成了 libmodbus 板载串口后端的最终功能验证通过双串口主从通信实现了硬件联动与数据可视化这套双串口主从设计方案可直接复用至工业现场的多设备通信场景。至此libmodbus 在 STM32 平台的 USB 串口、板载串口后端适配与验证已全部完成形成了完整的移植与应用闭环。感谢各位的阅读持续关注本系列笔记一起探索更多嵌入式通信与开源库落地的实战方案