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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1190|回復: 6
收起左側

解析串口4接收的數據包中的一幀數據

[復制鏈接]
回帖獎勵 10 黑幣 回復本帖可獲得 1 黑幣獎勵! 每人限 1 次
ID:590050 發表于 2025-1-17 20:43 | 顯示全部樓層 |閱讀模式
      程序大部分是借鑒的網上或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,但解析出的數據卻不是這個,求大神幫看一下是哪里的問題,先謝。
回復

使用道具 舉報

ID:338503 發表于 2025-1-18 08:07 | 顯示全部樓層
你上述程序調用void  Uart4_Read_Cmd_Data(void)函數1次只能讀取1個字節數據,按你上述程序,要根據命令(0x06,0x07,0x08,0x09)的不同調用相應次數才可以。
回復

使用道具 舉報

ID:338503 發表于 2025-1-18 08:16 | 顯示全部樓層
上述讀命令程序調用1次只能讀取一個字節數據,只有根據命令(0x06,0x07,0x08,0x09)的不同調用相應次數才可以。
回復

使用道具 舉報

ID:1143113 發表于 2025-1-19 11:04 | 顯示全部樓層
有一個問題要注意,你是什么時候開始解析,建議要在解析前先判斷接收字節數夠不夠。只有字節數夠了才調用判斷。這個非常重要的。
回復

使用道具 舉報

ID:161164 發表于 2025-1-19 23:27 | 顯示全部樓層
ucRX4_Read_Cnt 是全局變量嗎?
為什么要在Uart4_Read_Cmd_Data函數開頭清零?
回復

使用道具 舉報

ID:1133081 發表于 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. }
復制代碼



回復

使用道具 舉報

ID:1143357 發表于 2025-1-24 12:50 | 顯示全部樓層
你調用這個函數時switch結構只進去了一次就出來了,而且用于計數的參數又是局部變量,再次調用計數參數又會歸零,這里可以改一下
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 午夜免费网站 | 在线欧美一区 | 色婷婷久久久久swag精品 | 国产91在线播放 | av免费成人 | 精品99在线| 欧美5区 | www.av在线| 7799精品视频天天看 | 欧美日韩电影一区 | 91成人在线 | 精品久久久久久久久久久下田 | 国产精品一区二区在线 | 日韩影院在线 | 日本中文字幕日韩精品免费 | 日韩不卡三区 | 午夜精品一区二区三区在线播放 | 久草热视频| 午夜男人免费视频 | 国产综合久久 | 亚洲精品久久久久久一区二区 | 欧美成人精品一区二区三区 | 免费看a| 在线视频中文字幕 | 综合久| 性视频一区 | 国产精品影视 | 国产成人99久久亚洲综合精品 | 日本免费一区二区三区 | 自拍偷拍亚洲欧美 | 国产精品久久久久久久一区二区 | 99精品国产在热久久 | 亚洲一区二区三区高清 | 国产一级在线视频 | 国产成人精品免高潮在线观看 | 国产成人精品视频在线观看 | 日韩视频一区二区在线 | 成人做爰9片免费看网站 | 黄色在线免费观看视频 | 日韩精品一区二区三区中文在线 | 精品国产乱码久久久久久图片 |