亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码

標題: 串行通信數據包解析不正常 [打印本頁]

作者: samxon    時間: 2026-6-6 17:01
標題: 串行通信數據包解析不正常


通過PC機串口發送hex數據 5A 02 01 02 5F。返回給PC的數據不穩定,有時是5A 02, 有時是5A 01, 并且每次都返回四次。請大家幫忙分析一下原因。拋磚引玉。謝謝。

unsigned char tempsbuf;

typedef enum{
        WAIT_HEADER,
        WAIT_LEN,
        WAIT_DATA,
        WAIT_CHECKSUM
} ParserState;

typedef struct Parser{
        ParserState state; //當前狀態
        unsigned char len;        //數據長度
        unsigned char buf_data[3]; //數據緩沖區
        unsigned char index;        //數據接收計數
        unsigned char checksum;        //檢驗和
} Parser;

void parser_init(Parser *p){
        p->state=WAIT_HEADER;
        p->len=0;
        p->index=0;
        p->checksum=0;
}

int parser_input_byte(Parser *p,unsigned char byte){
        switch(p->state){
                //1、等待幀頭0x5a
                case WAIT_HEADER:
                        if(byte==0x5A){
                                p->checksum=byte; //累加校驗
                                p->state=WAIT_LEN;
                        }
                break;
                //2、等待長度
                case WAIT_LEN:
                        p->len=byte;
                        p->checksum+=byte;
                        p->index=0;
                        p->state=WAIT_DATA;
                break;
                //3、等待數據
                case WAIT_DATA:
                        p->buf_data[p->index++]=byte;
                        //p->index++;
                        p->checksum+=byte;
                        if(p->index>=p->len){p->state=WAIT_CHECKSUM;}
                break;
                //4、等待校驗
                case WAIT_CHECKSUM:
                        p->state=WAIT_HEADER; //解析完成回到初始狀態
                                if(byte==p->checksum){
                                        return 1;
                                }
                                break;
        }       
        return 0;
}


void Uart() interrupt 4 //串行中斷函數
{
        if(TI)
                {                       
                        TI=0; //清楚TI傳送完成標記
                }
               
        if(RI){       
                RI=0;
                tempsbuf=SBUF;
               
        }
       



Parser p;
parser_init(&p);

void main(){
    while(1)
        {
               
                if(parser_input_byte(&p,tempsbuf)){
                SendByte(p.buf_data[0]);
                SendByte(p.buf_data[1]);
                }
        }

}

作者: lkc8210    時間: 2026-6-8 13:16
啥芯片?晶振多少?串口初始化代碼呢?
作者: 人中狼    時間: 2026-6-8 16:02
接收數據的判斷應該在串口接收中斷里判斷
作者: WL0123    時間: 2026-6-8 20:00
樓主說明下通訊協議
作者: joyb    時間: 2026-6-9 08:38
串口初始化,誤差大
作者: joyb    時間: 2026-6-9 08:47
這段代碼實現了一個基于狀態機的串口數據包解析器,結構基本正確,但存在幾個嚴重且典型的問題,在實際項目中可能導致數據錯亂、死循環甚至程序崩潰。下面逐一分析。

1. 代碼功能簡述
2. 存在的關鍵問題① 主循環與中斷完全無同步 —— 數據競爭 / 重復解析 / 丟字節if(RI){    RI=0;    tempsbuf=SBUF;}// main loopif(parser_input_byte(&p,tempsbuf)){    ...}
正確做法:使用 volatile 標志位,中斷置位,主循環檢測后清除并處理。
volatile bit hasNewByte = 0;// 中斷中:tempsbuf = SBUF;hasNewByte = 1;// 主循環:if(hasNewByte) {    hasNewByte = 0;    if(parser_input_byte(&p, tempsbuf)) { ... }}
② 數據緩沖區 buf_data[3] 沒有長度保護,極易溢出unsigned char buf_data[3;...p->buf_data[p->index++ = byte;if(p->index >= p->len) { p->state = WAIT_CHECKSUM; }
case WAIT_LEN:    p->len = byte;    if(p->len > sizeof(p->buf_data)) {        p->state = WAIT_HEADER;  // 長度非法,復位        break;    }    ...
③ 同步恢復能力極差,錯誤字節極易造成永久失步④ parser_init(&p) 位置錯誤 —— C 語言不允許在文件作用域執行函數Parser p;parser_init(&p);   // ← 這行不能在全局作用域調用void main() { ... }
這種寫法在某些編譯器下可能被當作聲明甚至報錯。必須移到 main 內部:
void main() {    parser_init(&p);    while(1) { ... }}
⑤ 校驗和在失敗后未清除,且校驗包含幀頭本身⑥ main 函數缺少串口初始化⑦ 發送函數 SendByte 未定義,且 while(1) 內無其他保護
3. 改進后的代碼框架(關鍵部分)volatile bit hasNewByte = 0;unsigned char tempsbuf;// ... Parser 定義、parser_init、parser_input_byte(加入長度檢查) ...void Uart() interrupt 4 {    if(TI) {        TI = 0;    }    if(RI) {        RI = 0;        tempsbuf = SBUF;        hasNewByte = 1;    }}void main() {    Parser p;    parser_init(&p);    Uart_Init();  // 假設已實現    while(1) {        if(hasNewByte) {            hasNewByte = 0;            if(parser_input_byte(&p, tempsbuf)) {                SendByte(p.buf_data[0);                SendByte(p.buf_data[1);            }        }    }}
并且在 WAIT_LEN 中添加:
if(byte > sizeof(p->buf_data)) {    p->state = WAIT_HEADER;    break;}
總結
代碼展現了狀態機解析思想,但缺少實時系統中的同步機制、無邊界檢查、初始化位置錯誤,是典型的“能跑但一有干擾就崩”的嵌入式代碼。上述幾點修正后,才能在實際串口通信中穩定工作。


作者: samxon    時間: 2026-6-9 09:46
人中狼 發表于 2026-6-8 16:02
接收數據的判斷應該在串口接收中斷里判斷

對的。在接收中斷內判定是好很多,但還是有誤碼問題。




歡迎光臨 (http://www.denmoz.com/bbs/) Powered by Discuz! X3.1