|
| 不要同时采集 |
| 理论上485总线挂多个设备需要自己设计通讯协议的,采用轮询问答的方式获取数据,不阻塞的方式就定时器定时计数,1采集谁,2采集谁,3采集谁,多少毫秒触发一次计数,问答间隔数据不冲突就行了 |
| 能用就行啦,优化要理解,为啥你共用COM2作缓存会冲突。 |
| 这本身就是你自己在通讯过程中造成的设备间的冲突,找错问题方向了 |
|
现在我把风速和温湿度的函数拆分开来,在主函数里定时调用,可以显示风速和温湿度了。不知道还有没有更好的方法? /** * @brief 任务1运行 读取温湿度 */ void Task1_TempHumi_Run(void) { // ========== 所有变量在函数开头定义 ========== // 时间相关变量 static u32 xdata lastWindQueryTime = 0; // 上次风速查询时间 static u32 xdata lastTempQueryTime = 0; // 上次温湿度查询时间 static u32 xdata lastDisplayTime = 0; // 上次显示更新时间 // 上次显示值(用于比较是否变化) static u16 xdata lastWindSpeed = 0; static u16 xdata lastWindLevel = 0; static int xdata lastTemp = 0; static u16 xdata lastHumi = 0; // 风速状态机变量 static u8 xdata windStep = 0; // 0:空闲, 1:等待响应 static u32 xdata windStartTime = 0; // 风速请求发送时间 // 温湿度状态机变量 static u8 xdata tempStep = 0; // 0:空闲, 1:等待响应 static u32 xdata tempStartTime = 0; // 温湿度请求发送时间 // 当前时间(非静态,每次调用重新获取) u32 currentTime; // ========== 函数体开始 ========== currentTime = GetSysTimeMs(); // ========== 温湿度查询(每2000ms一次)========== if (tempStep == 0) // 只在空闲状态才能发送新请求 { if (currentTime - lastTempQueryTime >= 1000) { ModbusMasterSendTempHumiData(); // 发送温湿度查询码 tempStep = 1; tempStartTime = currentTime; lastTempQueryTime = currentTime; // 更新查询时间 printf("发送温湿度请求...\n"); } } // ========== 处理温湿度响应 ========== if (tempStep == 1) { ModbusMasterReceiveTempHumi(); // 接收完成 if (COM2.RX_TimeOut == 0 && COM2.RX_Cnt == 0) { tempStep = 0; // 回到空闲状态 printf("温湿度接收完成\n"); } // 超时处理(500ms无响应) else if (currentTime - tempStartTime > 500) { printf("温湿度响应超时\n"); tempStep = 0; COM2.RX_Cnt = 0; // 清空接收计数器 } } // ========== 更新LCD显示========== if (temp != lastTemp || humi != lastHumi) { Temperature_Display(temp, 3, 4); Humidity_Display(humi, 4, 4); printf("LCD更新 - 温度:%d.%d℃ 湿度:%u.%u%%\n", temp/10, (temp<0 ? -(temp%10) : temp%10), humi/10, humi%10); lastTemp = temp; lastHumi = humi; } } /** * @brief 任务1运行 读取风速风力 */ void Task1_Wind_Run(void) { // ========== 所有变量在函数开头定义 ========== // 时间相关变量 static u32 xdata lastWindQueryTime = 0; // 上次风速查询时间 static u32 xdata lastDisplayTime = 0; // 上次显示更新时间 // 上次显示值(用于比较是否变化) static u16 xdata lastWindSpeed = 0; static u16 xdata lastWindLevel = 0; // 风速状态机变量 static u8 xdata windStep = 0; // 0:空闲, 1:等待响应 static u32 xdata windStartTime = 0; // 风速请求发送时间 // 温湿度状态机变量 // 当前时间(非静态,每次调用重新获取) u32 xdata currentTime; // ========== 函数体开始 ========== currentTime = GetSysTimeMs(); // ========== 风速查询(每1000ms一次)========== if (windStep == 0) // 只在空闲状态才能发送新请求 { if (currentTime - lastWindQueryTime >= 1000) { ModbusMasterSendWindData(); // 发送风速查询码 windStep = 1; windStartTime = currentTime; lastWindQueryTime = currentTime; // 更新查询时间 printf("发送风速请求...\n"); } } // ========== 处理风速响应 ========== if (windStep == 1) { ModbusMasterReceiveWind(); // 接收完成(COM2接收超时且计数为0) if (COM2.RX_TimeOut == 0 && COM2.RX_Cnt == 0) { windStep = 0; // 回到空闲状态 printf("风速接收完成\n"); } // 超时处理(500ms无响应) else if (currentTime - windStartTime > 500) { printf("风速响应超时\n"); windStep = 0; COM2.RX_Cnt = 0; // 清空接收计数器 } } // ========== 更新LCD显示========== if (windSpeed != lastWindSpeed || windLevel != lastWindLevel) { WindSpeed_Display(windSpeed, 1, 4); WindLevel_Display(windLevel, 2, 4); printf("LCD更新 - 风速:%u(%.2f) 风级:%u\n", windSpeed, windSpeed * 0.01f, windLevel); lastWindSpeed = windSpeed; lastWindLevel = windLevel; } } void main(void) { u8 i; u8 key_val; u32 xdata run_time; u32 xdata run_time2; Timer_config(); UART_config(); GPIO_config(); Lcd12864_Init(); EA = 1; Task1_Init(); printf("Init is finish\n"); while (1) { run_time = GetSysTimeMs(); if(run_time - run_time2 >= 1100) { run_time2 = run_time; P00 = ~P00; } if(P00 == 0) { Task1_TempHumi_Run(); } else Task1_Wind_Run(); } } |
glinfei 发表于 2026-3-19 08:52 485总线本身就可以挂载多个设备,我还想再添加几个 |
|
485总线冲突了,同一个总线上的数据不可能相互独立的 |
| 就应该删掉,因为就一个总线,它可能导致总线冲突 |