<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 單片機之串口數據處理

單片機之串口數據處理

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

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


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

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

1. 初始化函數

本函數用于對串口結構體中的各種數據進(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. }
復制代碼
2. 接收一字節數據

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

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

本函數用于讀取串口緩沖區中還未處理的數據的大小。
  1. /**************************************************************************************
  2. * FunctionName : DFGetLen()
  3. * Description : 獲取緩沖區中未讀數據長(cháng)度
  4. * EntryParameter : None
  5. * ReturnValue : 返回數據長(chá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. }
復制代碼
有了以上幾個(gè)函數,串口的處理就非常簡(jiǎn)單了。這幾個(gè)函數可以應用到任何串口中,也可以應用到任務(wù)微處理器上,一致非常簡(jiǎn)單,應用也非常方便。下面我們說(shuō)說(shuō)實(shí)際的應用。
這部分代碼為應用代碼

為了保證數據的相對獨立和模塊化,下面代碼將寫(xiě)入應用代碼中,和上面的程序不能放在相同的文件中。

1. 數據定義

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

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

本函數判斷緩沖區中是否有數據,如果有,逐個(gè)讀取并處理。
  1. /**************************************************************************************
  2. * FunctionName : AUTaskCtrl()
  3. * Description : 通信數據處理
  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); // 獲取未讀數據長(cháng)度
  13. for (i=0; i < len; i++)
  14. {
  15. tmpDat = DFReadByte(&AU_Rvc); // 讀一字節數據
  16. AU_PrcRcvDat(tmpDat);
  17. }
  18. }
復制代碼
函數AU_PrcRcvDat(tmpDat)是數據處理函數,首先是數據幀判斷,如果是一幀數據,就進(jìn)行相應操作,并把操作結果返回。了解了這個(gè)過(guò)程,串口的編程就變得非常簡(jiǎn)單。而且我們在讀程序時(shí),只要看懂一個(gè)串口處理過(guò)程,其他串口的程序就自然懂了,非常方便吧。


關(guān)鍵詞: 單片機串口數據處

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>