找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3334|回復(fù): 11
打印 上一主題 下一主題
收起左側(cè)

關(guān)于單片機(jī)串口數(shù)據(jù)解析

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
50黑幣
由串口接收回的數(shù)據(jù)存儲在u8 USART2_RX_BUF[];下面是串口接收中斷函數(shù)
void  USART2_IRQHandler(void)
{
      
        u8 Res;
        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中斷(接收到的數(shù)據(jù)必須是0x0d 0x0a結(jié)尾)
                        {
                        Res =USART_ReceiveData(USART2);        //讀取接收到的數(shù)據(jù)
                  Res&=0x7F;
                       
                        if((USART2_RX_STA&0x8000)==0)//接收未完成
                                {
                                if(USART2_RX_STA&0x4000)//接收到了0x0d
                                        {
                                        if(Res!=0x0a)USART2_RX_STA=0;//接收錯(cuò)誤,重新開始
                                        else USART2_RX_STA|=0x8000;        //接收完成了
                                        }
                                else //還沒收到0X0D
                                        {      
                                        if(Res==0x0d)USART2_RX_STA|=0x4000;
                                        else
                                                {
                                                USART2_RX_BUF[USART2_RX_STA&0X3FFF]=Res ;
                                                USART2_RX_STA++;
                                                if(USART2_RX_STA>(USART2_REC_LEN-1))USART2_RX_STA=0;//接收數(shù)據(jù)錯(cuò)誤,重新開始接收         
                                                }                 
                                        }
                                }                    
                         }
}

USART2_RX_BUF[]的數(shù)據(jù)格式如圖所示,紅框標(biāo)注為有效數(shù)據(jù),紅框內(nèi)數(shù)據(jù)前8位是壓力值,后8位是濃度值,數(shù)據(jù)類型為浮點(diǎn)型

我想1、將有效數(shù)據(jù)截取出來
2、將浮點(diǎn)數(shù)據(jù)轉(zhuǎn)為正常的數(shù)值
3、可從串口輸出

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:301191 發(fā)表于 2022-8-3 03:52 | 只看該作者
頂一下
回復(fù)

使用道具 舉報(bào)

板凳
ID:94031 發(fā)表于 2022-8-3 06:24 | 只看該作者
數(shù)據(jù)內(nèi)容里是3個(gè)數(shù):
42 c8 5c 29 對應(yīng)壓力值:   100.18  (浮點(diǎn)數(shù));
00 10         對應(yīng)模塊狀態(tài):0x0010 (16進(jìn)制數(shù));
41 44 cc cd 對應(yīng)濃度值:   12.3     (浮點(diǎn)數(shù));
回復(fù)

使用道具 舉報(bào)

地板
ID:123289 發(fā)表于 2022-8-3 09:25 | 只看該作者
1、研讀、了解通訊協(xié)議,按協(xié)議分解數(shù)據(jù)。
2、弄通浮點(diǎn)數(shù)的組數(shù)方式。
這樣你就會象板櫈一樣明白了。
回復(fù)

使用道具 舉報(bào)

5#
ID:1041056 發(fā)表于 2022-8-3 10:37 | 只看該作者
yzwzfyz 發(fā)表于 2022-8-3 09:25
1、研讀、了解通訊協(xié)議,按協(xié)議分解數(shù)據(jù)。
2、弄通浮點(diǎn)數(shù)的組數(shù)方式。
這樣你就會象板櫈一樣明白了。

轉(zhuǎn)浮點(diǎn)是先將8位16進(jìn)制轉(zhuǎn)成32位的二進(jìn)制數(shù),再對二進(jìn)制進(jìn)行計(jì)算,我現(xiàn)在完成了轉(zhuǎn)二進(jìn)制,但是二進(jìn)制數(shù)在單片機(jī)里也是十六進(jìn)制表示的,又不會算了
回復(fù)

使用道具 舉報(bào)

6#
ID:195496 發(fā)表于 2022-8-3 10:50 | 只看該作者
這個(gè)不難,要自已把接收數(shù)據(jù)程序改一下,中斷接收采用超時(shí)方法進(jìn)行,接收到有效數(shù)據(jù)后,置位一個(gè)標(biāo)志位,在主程序中查詢,進(jìn)行數(shù)據(jù)解析,不要所有工作都在串口中斷程序中進(jìn)行。
回復(fù)

使用道具 舉報(bào)

7#
ID:1034262 發(fā)表于 2022-8-3 11:45 | 只看該作者
協(xié)議不完善吧?沒有轉(zhuǎn)義字符?如果數(shù)據(jù)域中出現(xiàn)冒號或回車換行相同的數(shù)據(jù),怎么辦?
這是字符同步通訊,我會設(shè)置3個(gè)特殊字符:命令開始字符、結(jié)束字符、轉(zhuǎn)義字符。數(shù)據(jù)域中出現(xiàn)等于這3個(gè)控制字符的數(shù)據(jù)時(shí),使用轉(zhuǎn)義字符轉(zhuǎn)換一下。
回復(fù)

使用道具 舉報(bào)

8#
ID:883242 發(fā)表于 2022-8-3 13:06 | 只看該作者
coody_sz 發(fā)表于 2022-8-3 11:45
協(xié)議不完善吧?沒有轉(zhuǎn)義字符?如果數(shù)據(jù)域中出現(xiàn)冒號或回車換行相同的數(shù)據(jù),怎么辦?
這是字符同步通訊,我 ...

扯淡,這種協(xié)議從0x0~0xff任何字符都可能出現(xiàn),如果設(shè)冒號回車換行這些轉(zhuǎn)義字符就亂套了。

很簡單,用超時(shí),比如MODBUS/RTU規(guī)定超過3.5個(gè)字節(jié)的總線空閑就是幀頭標(biāo)志。
回復(fù)

使用道具 舉報(bào)

9#
ID:161164 發(fā)表于 2022-8-3 13:14 | 只看該作者
首先你要確保USART2_RX_BUF[0]是':'
然后就簡單了

float *YaLi;
float *LongDu;

YaLi = (float*)&USART2_RX_BUF[4]);
LongDu = (float*)&USART2_RX_BUF[10]);

printf("YaLi = %0.2f, LongDu = %0.2f\r\n",*YaLi,*LongDu);
回復(fù)

使用道具 舉報(bào)

10#
ID:401564 發(fā)表于 2022-8-3 17:41 | 只看該作者
這個(gè)像是Modbus通訊
1,當(dāng)串口接收到第1個(gè)數(shù)據(jù)時(shí),啟動定時(shí)器,并把數(shù)據(jù)保存到緩沖池中
2,接收到結(jié)束符,并且一定時(shí)間之后,如果再沒接收到新的數(shù)據(jù),就認(rèn)為這是一個(gè)完整的數(shù)據(jù)幀
3,把緩沖池的數(shù)據(jù)復(fù)制到另一個(gè)緩沖池中,在主程序?qū)α硪粋(gè)緩沖池的數(shù)據(jù)進(jìn)行處理,因?yàn)橛锌赡苣阍谔幚淼臅r(shí)候,來了新的數(shù)據(jù),緩沖池的數(shù)據(jù)結(jié)構(gòu)就不一樣了,讀取出來的就不一定是原始的數(shù)據(jù)了

我一般用的是結(jié)構(gòu)struct                                           //串口Buffer結(jié)構(gòu)
{
unsigned char buf_uart[32];                //留32個(gè)地址來存放串口的數(shù)據(jù)
unsigned char cnt_Byte;        //接收到的字節(jié)數(shù)量
}Buffer0,Buffer1;        //兩個(gè)結(jié)構(gòu)變量,讓串口接收和保存不相互影響

接收到一個(gè)完整的數(shù)據(jù)幀之后,就直接

Buffer1=Buffer0;//把串口緩存的數(shù)據(jù)復(fù)制過來
memset(&Buffer0,0,sizeof(Buffer0));//清除串口接收緩沖
STM32有足夠的能力處理串口這點(diǎn)小數(shù)據(jù)的

讀取數(shù)據(jù)出來不就是很簡單的事情嗎?就是直接讀取數(shù)組的數(shù)據(jù)而已,9#已經(jīng)給出方法了
回復(fù)

使用道具 舉報(bào)

11#
ID:401564 發(fā)表于 2022-8-3 17:51 | 只看該作者
coody_sz 發(fā)表于 2022-8-3 11:45
協(xié)議不完善吧?沒有轉(zhuǎn)義字符?如果數(shù)據(jù)域中出現(xiàn)冒號或回車換行相同的數(shù)據(jù),怎么辦?
這是字符同步通訊,我 ...

這個(gè)數(shù)據(jù)看著像modbus
兩個(gè)簡單的起始符和結(jié)束符意義并不大,接收到的數(shù)據(jù)中隨時(shí)有可能就出現(xiàn)了,搞不好數(shù)據(jù)還沒有接收完就結(jié)束了
回復(fù)

使用道具 舉報(bào)

12#
ID:883242 發(fā)表于 2022-8-3 17:53 | 只看該作者
Y_G_G 發(fā)表于 2022-8-3 17:41
這個(gè)像是Modbus通訊
1,當(dāng)串口接收到第1個(gè)數(shù)據(jù)時(shí),啟動定時(shí)器,并把數(shù)據(jù)保存到緩沖池中
2,接收到結(jié)束符,并且 ...

根本就不是什么MODBUS,要么用超時(shí)來做幀頭標(biāo)記,中間可以是0x0~0xff任意數(shù)字,這是MODBUS/RTU的實(shí)現(xiàn)方法。要么用特殊字符比如:做幀頭,\r\n做幀尾標(biāo)記,中間只能出現(xiàn)'0'~'9'、‘A’~‘Z’這類可打印的ASCII字符,絕對不可以在數(shù)據(jù)幀中間出現(xiàn): \r \n這幾個(gè)幀標(biāo)志,這是MODBUS/ASC的做法。

這個(gè)協(xié)議的制定者顯然是個(gè)不懂裝懂的半瓶醋,才會搞出這種有邏輯漏洞的東西。
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表