熱門: 51單片機(jī) | 24小時(shí)必答區(qū) | 單片機(jī)教程 | 單片機(jī)DIY制作 | STM32 | Cortex M3 | 模數(shù)電子 | 電子DIY制作 | 音響/功放 | 拆機(jī)樂園 | Arduino | 嵌入式OS | 程序設(shè)計(jì)
|
發(fā)布時(shí)間: 2026-3-18 18:27
正文摘要:本帖最后由 小橋流水不 于 2026-3-18 18:33 編輯 使用stc15f2k48s2單片機(jī),485接收溫濕度和風(fēng)速,如果把Task1_Run里的// if (currentTime - lastWindTime >= ... |
| 能用就行啦,優(yōu)化要理解,為啥你共用COM2作緩存會(huì)沖突。 |
| 這本身就是你自己在通訊過程中造成的設(shè)備間的沖突,找錯(cuò)問題方向了 |
|
現(xiàn)在我把風(fēng)速和溫濕度的函數(shù)拆分開來,在主函數(shù)里定時(shí)調(diào)用,可以顯示風(fēng)速和溫濕度了。不知道還有沒有更好的方法? /** * @brief 任務(wù)1運(yùn)行 讀取溫濕度 */ void Task1_TempHumi_Run(void) { // ========== 所有變量在函數(shù)開頭定義 ========== // 時(shí)間相關(guān)變量 static u32 xdata lastWindQueryTime = 0; // 上次風(fēng)速查詢時(shí)間 static u32 xdata lastTempQueryTime = 0; // 上次溫濕度查詢時(shí)間 static u32 xdata lastDisplayTime = 0; // 上次顯示更新時(shí)間 // 上次顯示值(用于比較是否變化) static u16 xdata lastWindSpeed = 0; static u16 xdata lastWindLevel = 0; static int xdata lastTemp = 0; static u16 xdata lastHumi = 0; // 風(fēng)速狀態(tài)機(jī)變量 static u8 xdata windStep = 0; // 0:空閑, 1:等待響應(yīng) static u32 xdata windStartTime = 0; // 風(fēng)速請求發(fā)送時(shí)間 // 溫濕度狀態(tài)機(jī)變量 static u8 xdata tempStep = 0; // 0:空閑, 1:等待響應(yīng) static u32 xdata tempStartTime = 0; // 溫濕度請求發(fā)送時(shí)間 // 當(dāng)前時(shí)間(非靜態(tài),每次調(diào)用重新獲取) u32 currentTime; // ========== 函數(shù)體開始 ========== currentTime = GetSysTimeMs(); // ========== 溫濕度查詢(每2000ms一次)========== if (tempStep == 0) // 只在空閑狀態(tài)才能發(fā)送新請求 { if (currentTime - lastTempQueryTime >= 1000) { ModbusMasterSendTempHumiData(); // 發(fā)送溫濕度查詢碼 tempStep = 1; tempStartTime = currentTime; lastTempQueryTime = currentTime; // 更新查詢時(shí)間 printf("發(fā)送溫濕度請求...\n"); } } // ========== 處理溫濕度響應(yīng) ========== if (tempStep == 1) { ModbusMasterReceiveTempHumi(); // 接收完成 if (COM2.RX_TimeOut == 0 && COM2.RX_Cnt == 0) { tempStep = 0; // 回到空閑狀態(tài) printf("溫濕度接收完成\n"); } // 超時(shí)處理(500ms無響應(yīng)) else if (currentTime - tempStartTime > 500) { printf("溫濕度響應(yīng)超時(shí)\n"); tempStep = 0; COM2.RX_Cnt = 0; // 清空接收計(jì)數(shù)器 } } // ========== 更新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 任務(wù)1運(yùn)行 讀取風(fēng)速風(fēng)力 */ void Task1_Wind_Run(void) { // ========== 所有變量在函數(shù)開頭定義 ========== // 時(shí)間相關(guān)變量 static u32 xdata lastWindQueryTime = 0; // 上次風(fēng)速查詢時(shí)間 static u32 xdata lastDisplayTime = 0; // 上次顯示更新時(shí)間 // 上次顯示值(用于比較是否變化) static u16 xdata lastWindSpeed = 0; static u16 xdata lastWindLevel = 0; // 風(fēng)速狀態(tài)機(jī)變量 static u8 xdata windStep = 0; // 0:空閑, 1:等待響應(yīng) static u32 xdata windStartTime = 0; // 風(fēng)速請求發(fā)送時(shí)間 // 溫濕度狀態(tài)機(jī)變量 // 當(dāng)前時(shí)間(非靜態(tài),每次調(diào)用重新獲取) u32 xdata currentTime; // ========== 函數(shù)體開始 ========== currentTime = GetSysTimeMs(); // ========== 風(fēng)速查詢(每1000ms一次)========== if (windStep == 0) // 只在空閑狀態(tài)才能發(fā)送新請求 { if (currentTime - lastWindQueryTime >= 1000) { ModbusMasterSendWindData(); // 發(fā)送風(fēng)速查詢碼 windStep = 1; windStartTime = currentTime; lastWindQueryTime = currentTime; // 更新查詢時(shí)間 printf("發(fā)送風(fēng)速請求...\n"); } } // ========== 處理風(fēng)速響應(yīng) ========== if (windStep == 1) { ModbusMasterReceiveWind(); // 接收完成(COM2接收超時(shí)且計(jì)數(shù)為0) if (COM2.RX_TimeOut == 0 && COM2.RX_Cnt == 0) { windStep = 0; // 回到空閑狀態(tài) printf("風(fēng)速接收完成\n"); } // 超時(shí)處理(500ms無響應(yīng)) else if (currentTime - windStartTime > 500) { printf("風(fēng)速響應(yīng)超時(shí)\n"); windStep = 0; COM2.RX_Cnt = 0; // 清空接收計(jì)數(shù)器 } } // ========== 更新LCD顯示========== if (windSpeed != lastWindSpeed || windLevel != lastWindLevel) { WindSpeed_Display(windSpeed, 1, 4); WindLevel_Display(windLevel, 2, 4); printf("LCD更新 - 風(fēng)速:%u(%.2f) 風(fēng)級(jí):%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 發(fā)表于 2026-3-19 08:52 485總線本身就可以掛載多個(gè)設(shè)備,我還想再添加幾個(gè) |
|
485總線沖突了,同一個(gè)總線上的數(shù)據(jù)不可能相互獨(dú)立的 |
| 就應(yīng)該刪掉,因?yàn)榫鸵粋(gè)總線,它可能導(dǎo)致總線沖突 |
Powered by 單片機(jī)教程網(wǎng)