在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)之串口數(shù)據(jù)處理

            單片機(jī)之串口數(shù)據(jù)處理

            作者: 時(shí)間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
            隨著硬件系統(tǒng)的模塊化發(fā)展,很多電子產(chǎn)品都做出模塊并采用串口進(jìn)行數(shù)據(jù)通信。例如:GPRS模塊、GPS模塊、語(yǔ)音模塊、熱敏微型打印機(jī)、串口攝像頭等等。在與這些模塊進(jìn)行數(shù)據(jù)通信都離不開串口,而對(duì)于串口的操作,由于串口本身沒有標(biāo)準(zhǔn)的通信協(xié)議,所以很難做到非常統(tǒng)一的操作過程。一般來說,不同的模塊其有著特殊的通信協(xié)議,我們只能根據(jù)其協(xié)議進(jìn)行數(shù)據(jù)解碼。

            雖然說串口沒有標(biāo)準(zhǔn)協(xié)議,但是我們卻可以把它們的相似部分提取出來,做成模塊化的程序,方便代碼的移植和理解。下面我們簡(jiǎn)單談到串口數(shù)據(jù)的處理方法。。。。。
            串口數(shù)據(jù)處理流程:


            一般來說,串口數(shù)據(jù)的接收都是采用中斷方式,中斷中只復(fù)制把串口發(fā)送的數(shù)據(jù)放入數(shù)據(jù)緩沖區(qū)中。而發(fā)送一般都是采用查詢方式比較方便。不管是與什么設(shè)備通信,這一點(diǎn)完全是一致的。所以,我們完全可以把這部分代碼獨(dú)立起來。

            定義數(shù)據(jù)結(jié)構(gòu)如下:
            1. typedef struct
            2. {
            3. u16 WtCnt; // 寫指針
            4. u16 RdCnt;// 讀指針
            5. u16 BufLen;緩沖尺寸
            6. u8*RwBuf;// 讀寫緩沖
            7. } DF_RCV;
            復(fù)制代碼
            對(duì)于這個(gè)結(jié)構(gòu)來說非常簡(jiǎn)單,參數(shù)1是用于結(jié)束數(shù)據(jù)計(jì)數(shù),參數(shù)2為處理數(shù)據(jù)計(jì)數(shù),參數(shù)3為緩沖的大小,參數(shù)4為緩沖區(qū)指針,這里用指針是為了保證這個(gè)結(jié)構(gòu)的獨(dú)立,否則無法滿足各種需求。
            實(shí)現(xiàn)函數(shù):

            1. 初始化函數(shù)

            本函數(shù)用于對(duì)串口結(jié)構(gòu)體中的各種數(shù)據(jù)進(jìn)行初始化。
            1. /**************************************************************************************
            2. * FunctionName : DFInit()
            3. * Description : 初始化
            4. * EntryParameter : None
            5. * ReturnValue : None
            6. **************************************************************************************/
            7. void DFInit(DF_RCV *pRcv)
            8. {
            9. u16 i;
            10. pRcv->WtCnt = 0x0000;
            11. pRcv->RdCnt = 0x0000;
            12. for (i=0; iBufLen; i++)
            13. {
            14. pRcv->RwBuf[i] = 0x00;
            15. }
            16. }
            復(fù)制代碼
            2. 接收一字節(jié)數(shù)據(jù)

            本函數(shù)用于把串口中斷接收的數(shù)據(jù)放入數(shù)據(jù)緩沖區(qū)中,并且接收計(jì)數(shù)器加1.
            1. /**************************************************************************************
            2. * FunctionName : DFWriteByte()
            3. * Description : 數(shù)據(jù)接收(接收中斷調(diào)用)
            4. * EntryParameter : None
            5. * ReturnValue : None
            6. **************************************************************************************/
            7. void DFWriteByte(u8 dat, DF_RCV *pRcv)
            8. {
            9. pRcv->RwBuf[pRcv->WtCnt] = dat; // 數(shù)據(jù)存入
            10. if (++(pRcv->WtCnt) >= pRcv->BufLen) // 緩沖判斷
            11. {
            12. pRcv->WtCnt = 0;
            13. }
            14. }
            復(fù)制代碼
            3. 讀取一字節(jié)數(shù)據(jù)

            本函數(shù)用于從接收緩沖區(qū)中讀取未處理的一字節(jié)數(shù)據(jù),讀計(jì)數(shù)器加1.
            1. /**************************************************************************************
            2. * FunctionName : DFReadByte()
            3. * Description : 從接受緩沖中讀取一字節(jié)數(shù)據(jù)
            4. * EntryParameter : None
            5. * ReturnValue : 返回讀取數(shù)據(jù)
            6. **************************************************************************************/
            7. u8 DFReadByte(DF_RCV *pRcv)
            8. {
            9. u8 val = 0x00;
            10. val = pRcv->RwBuf[pRcv->RdCnt]; // 讀取一字節(jié)
            11. if (++(pRcv->RdCnt) >= pRcv->BufLen)
            12. {
            13. pRcv->RdCnt = 0; // 清零
            14. }
            15. return val; // 返回?cái)?shù)據(jù)
            16. }
            復(fù)制代碼
            4. 獲取緩沖區(qū)中未處理數(shù)據(jù)的長(zhǎng)度

            本函數(shù)用于讀取串口緩沖區(qū)中還未處理的數(shù)據(jù)的大小。
            1. /**************************************************************************************
            2. * FunctionName : DFGetLen()
            3. * Description : 獲取緩沖區(qū)中未讀數(shù)據(jù)長(zhǎng)度
            4. * EntryParameter : None
            5. * ReturnValue : 返回?cái)?shù)據(jù)長(zhǎng)度
            6. **************************************************************************************/
            7. u16 DFGetLen(DF_RCV *pRcv)
            8. {
            9. return ((pRcv->WtCnt >= pRcv->RdCnt) ? ((pRcv->WtCnt - pRcv->RdCnt)) :
            10. ((pRcv->WtCnt + pRcv->BufLen) - pRcv->RdCnt));
            11. }
            復(fù)制代碼
            有了以上幾個(gè)函數(shù),串口的處理就非常簡(jiǎn)單了。這幾個(gè)函數(shù)可以應(yīng)用到任何串口中,也可以應(yīng)用到任務(wù)微處理器上,一致非常簡(jiǎn)單,應(yīng)用也非常方便。下面我們說說實(shí)際的應(yīng)用。
            這部分代碼為應(yīng)用代碼

            為了保證數(shù)據(jù)的相對(duì)獨(dú)立和模塊化,下面代碼將寫入應(yīng)用代碼中,和上面的程序不能放在相同的文件中。

            1. 數(shù)據(jù)定義

            首先需要定義一個(gè)緩沖區(qū),這個(gè)緩沖區(qū)的大小根據(jù)實(shí)際應(yīng)用定義,其大小一般為數(shù)據(jù)幀的最大值的2倍。之后需要定義一個(gè)DF_RCV數(shù)據(jù),在這個(gè)數(shù)據(jù)中需要初始化這個(gè)結(jié)構(gòu)圖的參數(shù)。特別需要注意,緩沖的大小,和緩沖區(qū)指針賦值。
            1. u8 AU_Buf[AU_BUF_ZISE] = {0};
            2. DF_RCV AU_Rvc = {0, 0,AU_BUF_ZISE,AU_Buf};
            復(fù)制代碼
            2. 編寫數(shù)據(jù)接收函數(shù)

            本函數(shù)把串口數(shù)據(jù)放入緩沖區(qū)中,此函數(shù)必須在串口中斷中調(diào)用。
            1. /**************************************************************************************
            2. * FunctionName : AURcvDat()
            3. * Description : 串口數(shù)據(jù)接收(串口中斷服務(wù)調(diào)用)
            4. * EntryParameter : None
            5. * ReturnValue : None
            6. **************************************************************************************/
            7. void AURcvDat(u8 dat)
            8. {
            9. DFWriteByte(dat, &AU_Rvc);
            10. }
            復(fù)制代碼
            3. 數(shù)據(jù)處理函數(shù)

            本函數(shù)判斷緩沖區(qū)中是否有數(shù)據(jù),如果有,逐個(gè)讀取并處理。
            1. /**************************************************************************************
            2. * FunctionName : AUTaskCtrl()
            3. * Description : 通信數(shù)據(jù)處理
            4. * EntryParameter : None
            5. * ReturnValue : None
            6. **************************************************************************************/
            7. void AUTaskCtrl(void)
            8. {
            9. u8tmpDat;
            10. u16 i, len = 0;
            11. static u8 sendMark = 0;
            12. len = DFGetLen(&AU_Rvc); // 獲取未讀數(shù)據(jù)長(zhǎng)度
            13. for (i=0; i < len; i++)
            14. {
            15. tmpDat = DFReadByte(&AU_Rvc); // 讀一字節(jié)數(shù)據(jù)
            16. AU_PrcRcvDat(tmpDat);
            17. }
            18. }
            復(fù)制代碼
            函數(shù)AU_PrcRcvDat(tmpDat)是數(shù)據(jù)處理函數(shù),首先是數(shù)據(jù)幀判斷,如果是一幀數(shù)據(jù),就進(jìn)行相應(yīng)操作,并把操作結(jié)果返回。了解了這個(gè)過程,串口的編程就變得非常簡(jiǎn)單。而且我們?cè)谧x程序時(shí),只要看懂一個(gè)串口處理過程,其他串口的程序就自然懂了,非常方便吧。


            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉