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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 974|回復(fù): 6
收起左側(cè)

解析串口4接收的數(shù)據(jù)包中的一幀數(shù)據(jù)

[復(fù)制鏈接]
回帖獎(jiǎng)勵(lì) 10 黑幣 回復(fù)本帖可獲得 1 黑幣獎(jiǎng)勵(lì)! 每人限 1 次
ID:590050 發(fā)表于 2025-1-17 20:43 | 顯示全部樓層 |閱讀模式
      程序大部分是借鑒的網(wǎng)上或STC的例程,想實(shí)現(xiàn)從串口接收的數(shù)據(jù)包中,解析出一幀完整的命令。請(qǐng)教各位大神幫看一下程序,我用的STC單片機(jī),串口4接收數(shù)據(jù),接收的數(shù)據(jù)存在ucRX4_Buffer【】中,最大存UART4_BUF_LENGTH個(gè)數(shù)據(jù)。中斷部分程序如下:
unsigned char ucRX4_index=0;
void Uart4_isr() interrupt 18         //UART4 中斷服務(wù)程序
{
        UART4_INT_DISABLE();        //禁止串口4中斷        
        
        if(RI4)                                        //串口4接收到數(shù)據(jù)         
    {
                CLR_RI4();          //清除中斷4的接收標(biāo)志  

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

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

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

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

                case 1:        //判斷命令長(zhǎng)度,不同命令長(zhǎng)度不同;
                {                        
                        if(ucRX4_Buffer[ucRX4_Read_Cnt] == 0x06)                //06命令,06后4個(gè)字節(jié),加上命令,共計(jì)5個(gè)字節(jié)
                                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:                //接收數(shù)據(jù)
                {                                 
                        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;         //一幀數(shù)據(jù)接收完成
                        ucRX4_Read_State=0;
                        ucRX4_Head_Cnt = 0;

                }break;

                default:break;
        }
}

在其它程序中,需要讀數(shù)據(jù)時(shí),就調(diào)用        void  Uart4_Read_Cmd_Data(void)函數(shù)。

以上程序,現(xiàn)在的問(wèn)題是,總是查找出的數(shù)據(jù)總是不對(duì),用串口助手驗(yàn)證,比如發(fā)的數(shù)據(jù)包中包含了一幀數(shù)據(jù),F(xiàn)D FD FD 06 01 02 03 06,但解析出的數(shù)據(jù)卻不是這個(gè),求大神幫看一下是哪里的問(wèn)題,先謝。
回復(fù)

使用道具 舉報(bào)

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

使用道具 舉報(bào)

ID:338503 發(fā)表于 2025-1-18 08:16 | 顯示全部樓層
上述讀命令程序調(diào)用1次只能讀取一個(gè)字節(jié)數(shù)據(jù),只有根據(jù)命令(0x06,0x07,0x08,0x09)的不同調(diào)用相應(yīng)次數(shù)才可以。
回復(fù)

使用道具 舉報(bào)

ID:1143113 發(fā)表于 2025-1-19 11:04 | 顯示全部樓層
有一個(gè)問(wèn)題要注意,你是什么時(shí)候開(kāi)始解析,建議要在解析前先判斷接收字節(jié)數(shù)夠不夠。只有字節(jié)數(shù)夠了才調(diào)用判斷。這個(gè)非常重要的。
回復(fù)

使用道具 舉報(bào)

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

使用道具 舉報(bào)

ID:1133081 發(fā)表于 2025-1-20 08:51 | 顯示全部樓層
首先要充分了解該自定義通訊協(xié)議,通常通訊協(xié)議的每一個(gè)字節(jié)都有其特定含義。例如:數(shù)據(jù)頭,數(shù)據(jù)長(zhǎng)度,有效數(shù)據(jù),驗(yàn)證碼,數(shù)據(jù)尾等。假設(shè)這串?dāng)?shù)據(jù)的前3個(gè)FD為數(shù)據(jù)頭,那么當(dāng)串口連續(xù)收到3個(gè)FD即判斷為有真實(shí)信號(hào)到來(lái),即持續(xù)對(duì)后續(xù)數(shù)據(jù)保存。否則清除緩存。如果數(shù)據(jù)長(zhǎng)度固定很好辦,收完若干字節(jié)即給出結(jié)束標(biāo)志。數(shù)據(jù)長(zhǎng)度不固定,但有字節(jié)長(zhǎng)度信息也好辦,根據(jù)長(zhǎng)度信息確定結(jié)束接收并給出結(jié)束標(biāo)志。如不含根據(jù)長(zhǎng)度信息通常啟動(dòng)定時(shí)器,若干時(shí)間收不到數(shù)據(jù)表示傳輸結(jié)束即給出結(jié)束標(biāo)志。解析函數(shù)在得到結(jié)束標(biāo)志后才開(kāi)始解析并清除結(jié)束標(biāo)志和緩存,為下次接收做準(zhǔn)備。假設(shè)FD FD FD 06 01 02 03 06是固定長(zhǎng)度,串口中斷示例:

  1. void UARTInterrupt() interrupt 4
  2. {
  3.         static uchar num=0;                //靜態(tài)計(jì)數(shù)變量
  4.         uchar i;
  5.         RI=0;                                        //接收中斷請(qǐng)求標(biāo)志位清0
  6.         rec_buf[num]=SBUF;                //接收到的數(shù)據(jù)串保存在緩存數(shù)組
  7.         if(rec_buf[0]==0xFD)        //驗(yàn)證數(shù)據(jù)頭(起始位)
  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;                        //接收完成標(biāo)志置1
  21.                         num=0;                        //計(jì)數(shù)變量清0
  22.                 }
  23.         }
  24. }
復(fù)制代碼



回復(fù)

使用道具 舉報(bào)

ID:1143357 發(fā)表于 2025-1-24 12:50 | 顯示全部樓層
你調(diào)用這個(gè)函數(shù)時(shí)switch結(jié)構(gòu)只進(jìn)去了一次就出來(lái)了,而且用于計(jì)數(shù)的參數(shù)又是局部變量,再次調(diào)用計(jì)數(shù)參數(shù)又會(huì)歸零,這里可以改一下
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日韩成人在线视频 | 国产亚洲精品精品国产亚洲综合 | 怡红院怡春院一级毛片 | 欧美精品久久久久 | 欧美黄色大片在线观看 | 久久综合九九 | 国产精品一区久久久 | 欧美日韩精品影院 | 国产精品久久av | 亚洲一区二区三区免费在线观看 | 亚洲日韩欧美一区二区在线 | 国产一区不卡 | 久久久精品天堂 | 亚洲精品一区二区三区中文字幕 | 午夜小视频在线播放 | 免费影视在线观看 | 亚洲精品视频在线 | 欧美一区二区三区在线观看视频 | 看亚洲a级一级毛片 | 亚洲91视频 | 亚洲一区亚洲二区 | 成人一区二区在线 | 成人久久18免费网站图片 | 久久91av | 国产精品久久精品 | 91一区二区三区 | 91在线播 | 久草影视在线 | 91亚洲精品在线 | 米奇狠狠鲁 | 视频羞羞 | 久久久久国产精品午夜一区 | 免费久久久| 精品久久久久久国产 | 久久久久久久91 | 九九看片 | 欧美成人不卡 | 亚洲系列第一页 | 久久久久久免费毛片精品 | 国产精品视频一二三区 | 日本欧美大片 |