
一句話: ISR 里寫了 60 行狀態機解析串口幀——每個字節都在中斷里判斷、跳轉、存數組。換成 512 字節環形隊列 queue_push queue_find_cmd 后ISR 縮減到 4 行只做字節推入幀解析移到主循環。適合誰讀ISR 越來越臃腫、串口收幀丟包不可復現的嵌入式開發者。舊方案ISR 里硬扛void ISR(void) { uint8_t ch UART-DR; switch (sn) { case 0: if (ch0x73) sn1; break; case 1: if (ch0x74) sn2; break; case 2: len_hch; sn3; break; case 3: len_lch; sn4; break; // ... 一共 12 個狀態 } }問題每個字節進一次 ISR → 狀態機跑一輪 → 幀長不定時狀態復雜度高 → 丟一個字節幀就散架。ISR 里做這么多事本身就是錯的——中斷要短邏輯留給主循環。新方案環形隊列// ISR 縮減到 4 行 void ISR(void) { uint8_t ch UART-DR; queue_push(g_UartQueue, ch); // 只管往里塞 }環形隊列結構512 字節 buffer head tail。queue_push寫 tail 位置、tail 前進。queue_find_cmd在主循環里掃隊列找幀頭和幀尾。幀解析移到主循環void Uart_Process(void) { uint8_t frame[MAX_FRAME]; if (queue_find_cmd(g_UartQueue, frame, len)) { // 拿到完整幀該干嘛干嘛 } }queue_find_cmd做的事從隊列滑窗掃描EE頭 → 匹配FF FC FF FF尾 → 復制完整幀到 buffer → 從隊列踢掉已讀字節。ISR 從不關中斷、不判狀態、不處理協議。ISR 只做一件事——往環形 buffer 塞字節。其他全是主循環的事。有用的話點個收藏下次調試直接用。有問題歡迎評論區交流看到了都會回。