久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: 解析串口4接收的數據包中的一幀數據 [打印本頁]

作者: hzh173    時間: 2025-1-17 20:43
標題: 解析串口4接收的數據包中的一幀數據
      程序大部分是借鑒的網上或STC的例程,想實現從串口接收的數據包中,解析出一幀完整的命令。請教各位大神幫看一下程序,我用的STC單片機,串口4接收數據,接收的數據存在ucRX4_Buffer【】中,最大存UART4_BUF_LENGTH個數據。中斷部分程序如下:
unsigned char ucRX4_index=0;
void Uart4_isr() interrupt 18         //UART4 中斷服務程序
{
        UART4_INT_DISABLE();        //禁止串口4中斷        
        
        if(RI4)                                        //串口4接收到數據         
    {
                CLR_RI4();          //清除中斷4的接收標志  

                ucRX4_Buffer[ucRX4_index] = S4BUF;         //將串口4接收到的數據放入ucRX4_Buffer[]
                ucRX4_index++;
                if(ucRX4_index>UART4_BUF_LENGTH)        ucRX4_index=0;                        
    }

    if (TI4)
    {
        CLR_TI4();         //清除中斷4的發送標志

                bTX4_Busy = 0;           //設置串口4發送為空閑
    }
        UART4_INT_ENABLE();                  //允許串口4中斷
}

數據接收后,從接收的數據包中查找以FD,FD,FD開頭的數據幀,不同的命令對應不同的數據長度,將查找出的數據存在ucRX4_CMD_Data_Buffer【】中,程序如下:
void  Uart4_Read_Cmd_Data(void)                //讀串口4接收的不同命令的數據
{
        unsigned char i;
        ucRX4_Read_Cnt = 0;        
        switch(ucRX4_Read_State)
        {
                case 0:                //判斷頭文件
                {
//從接收緩存中查找幀頭
                        if(ucRX4_Buffer[ucRX4_Read_Cnt] == 0xFD)         //幀頭0xFD 0xFD 0xFD
                        {
                                 ucRX4_Read_Cnt++;                 //讀下一個數
                                if(++ucRX4_Head_Cnt >= 3)        //頭0xFD 0xFD 0xFD
                                {
                                        ucRX4_Read_State=1;
                                }
                        }
                        else
                        {
                                ucRX4_Read_Cnt++;                 //讀下一個數
                                ucRX4_Head_Cnt = 0;
                                ucRX4_Read_State = 0;
                        }        
                }        
                break;

                case 1:        //判斷命令長度,不同命令長度不同;
                {                        
                        if(ucRX4_Buffer[ucRX4_Read_Cnt] == 0x06)                //06命令,06后4個字節,加上命令,共計5個字節
                                ucRX4_Recv_Data_Length=5;                                         
                        else if(ucRX4_Buffer[ucRX4_Read_Cnt] == 0x07)        //07命令
                                ucRX4_Recv_Data_Length=15;
                        else if(ucRX4_Buffer[ucRX4_Read_Cnt] == 0x08)        //08命令
                                ucRX4_Recv_Data_Length=10;
                        else if(ucRX4_Buffer[ucRX4_Read_Cnt] == 0x09)        //09命令
                                ucRX4_Recv_Data_Length=11;
                        else  ucRX4_Recv_Data_Length=0;

                        ucRX4_Read_State=2;                                                               
                }                                 
                break;

                case 2:                //接收數據
                {                                 
                        for(i=0;i<ucRX4_Recv_Data_Length;i++)
                        {
                                ucRX4_CMD_Data_Buffer[ i]=ucRX4_Buffer[ucRX4_Read_Cnt];
                                ucRX4_Read_Cnt++;        
                        }

                        bRX4_Flag=1;         //一幀數據接收完成
                        ucRX4_Read_State=0;
                        ucRX4_Head_Cnt = 0;

                }break;

                default:break;
        }
}

在其它程序中,需要讀數據時,就調用        void  Uart4_Read_Cmd_Data(void)函數。

以上程序,現在的問題是,總是查找出的數據總是不對,用串口助手驗證,比如發的數據包中包含了一幀數據,FD FD FD 06 01 02 03 06,但解析出的數據卻不是這個,求大神幫看一下是哪里的問題,先謝。
作者: gsr64    時間: 2025-1-18 08:07
你上述程序調用void  Uart4_Read_Cmd_Data(void)函數1次只能讀取1個字節數據,按你上述程序,要根據命令(0x06,0x07,0x08,0x09)的不同調用相應次數才可以。
作者: gsr64    時間: 2025-1-18 08:16
上述讀命令程序調用1次只能讀取一個字節數據,只有根據命令(0x06,0x07,0x08,0x09)的不同調用相應次數才可以。
作者: llzfry    時間: 2025-1-19 11:04
有一個問題要注意,你是什么時候開始解析,建議要在解析前先判斷接收字節數夠不夠。只有字節數夠了才調用判斷。這個非常重要的。
作者: lkc8210    時間: 2025-1-19 23:27
ucRX4_Read_Cnt 是全局變量嗎?
為什么要在Uart4_Read_Cmd_Data函數開頭清零?
作者: WL0123    時間: 2025-1-20 08:51
首先要充分了解該自定義通訊協議,通常通訊協議的每一個字節都有其特定含義。例如:數據頭,數據長度,有效數據,驗證碼,數據尾等。假設這串數據的前3個FD為數據頭,那么當串口連續收到3個FD即判斷為有真實信號到來,即持續對后續數據保存。否則清除緩存。如果數據長度固定很好辦,收完若干字節即給出結束標志。數據長度不固定,但有字節長度信息也好辦,根據長度信息確定結束接收并給出結束標志。如不含根據長度信息通常啟動定時器,若干時間收不到數據表示傳輸結束即給出結束標志。解析函數在得到結束標志后才開始解析并清除結束標志和緩存,為下次接收做準備。假設FD FD FD 06 01 02 03 06是固定長度,串口中斷示例:

  1. void UARTInterrupt() interrupt 4
  2. {
  3.         static uchar num=0;                //靜態計數變量
  4.         uchar i;
  5.         RI=0;                                        //接收中斷請求標志位清0
  6.         rec_buf[num]=SBUF;                //接收到的數據串保存在緩存數組
  7.         if(rec_buf[0]==0xFD)        //驗證數據頭(起始位)
  8.         {
  9.                 num++;
  10.                 if(num==3)
  11.                 {
  12.                         if((rec_buf[0]&rec_buf[1]&rec_buf[2])!=0xFD)
  13.                         {
  14.                                 for(i=0;i>7;i++)
  15.                                         rec_buf[i]=0x00;//清除緩存
  16.                         }
  17.                 }
  18.                 if(num>=8)
  19.                 {
  20.                         flag=1;                        //接收完成標志置1
  21.                         num=0;                        //計數變量清0
  22.                 }
  23.         }
  24. }
復制代碼




作者: Celika    時間: 2025-1-24 12:50
你調用這個函數時switch結構只進去了一次就出來了,而且用于計數的參數又是局部變量,再次調用計數參數又會歸零,這里可以改一下




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 精品日韩一区 | 日韩一区二区免费视频 | 黄色毛片视频 | 亚洲一区二区三区免费视频 | 91高清免费观看 | 天天操天天射综合 | 成人综合视频在线 | 免费h在线 | 亚洲视频在线观看免费 | 毛片高清 | 欧美一区 | 亚洲成人在线免费 | 在线色网 | 夜夜精品视频 | 欧美精品在线观看 | 成人免费视频久久 | 国产精品美女久久久久久免费 | 国户精品久久久久久久久久久不卡 | www日韩| 狠狠操狠狠操 | 免费在线观看av网址 | 祝你幸福电影在线观看 | 男人的天堂中文字幕 | 国产高清精品一区二区三区 | 日韩专区中文字幕 | 一区二区三区影院 | 日韩欧美国产一区二区三区 | 国产在线看片 | 久久国产高清视频 | 久久a久久| 中文字幕一区二区三区在线乱码 | 亚洲综合二区 | 日本黄色的视频 | 国产婷婷色综合av蜜臀av | 色吊丝在线 | 久久男人| 黄色网址免费看 | 日本天天操 | 久国久产久精永久网页 | 国产免费拔擦拔擦8x高清 | 精品一区二区视频 |