色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

UART接收數(shù)據(jù)和解析的常見方式

strongerHuang ? 來源:strongerHuang ? 2023-04-19 14:31 ? 次閱讀

UART串口是嵌入式開發(fā)常見的一種通信方式,但還是有不少人不知道怎么使用串口。

今天就來圍繞串口,簡單分享幾點(diǎn)內(nèi)容:

串口接收方式

處理接收數(shù)據(jù)

通信協(xié)議解析

串口接收方式

串口接收(通信另一端)的數(shù)據(jù),常見的方式:

輪詢(查詢)接收寄存器

中斷接收數(shù)據(jù)

輪詢,就是間隔一定時(shí)間(一般ms,甚至us)去查詢一下接收寄存器是否有數(shù)據(jù),如果有數(shù)據(jù),就處理接收到的數(shù)據(jù)。

中斷,平時(shí)沒有數(shù)據(jù)接收時(shí),CPU干自己的事。當(dāng)有接收數(shù)據(jù)時(shí),UART串口控制器會響應(yīng)中斷,通知CPU有事干了。

輪詢方式,大家想過有哪些弊端嗎?

效率低:CPU大部分時(shí)間都是去做查詢的工作;

響應(yīng)不實(shí)時(shí):如果短時(shí)間內(nèi)有多個(gè)接收數(shù)據(jù),CPU正在處理一件相對耗時(shí)的事情(比如:發(fā)送一個(gè)數(shù)據(jù)包),沒來得及查詢接收到的數(shù)據(jù),此時(shí),數(shù)據(jù)就可能丟失。(特別是早些年串口沒有FIFO功能的時(shí)候)

所以,不管是UART串口,還是I2C、 SPI、 CAN等串行通信,用的最多,最常見的還是中斷接收,很少有用輪詢的方式。

我之前維護(hù)一個(gè)老代碼(坑),CLI串口用輪詢方式,出現(xiàn)丟數(shù)據(jù)、溢出錯(cuò)誤等眾多問題,讓我還加了好幾個(gè)班。。。

處理接收數(shù)據(jù)

中斷有數(shù)據(jù)來了,大家怎么處理接收到的數(shù)據(jù)?

我見過有些小項(xiàng)目,直接在中斷函數(shù)里面做一些應(yīng)用的情況。比如:串口中斷接收一個(gè)傳感器發(fā)過來的數(shù)據(jù),顯示數(shù)據(jù)并做一些響應(yīng)的動作。

中斷函數(shù),代碼能少盡少,耗時(shí)能少盡少,不能處理太多耗時(shí)的復(fù)雜的邏輯、應(yīng)用等。

中斷有數(shù)據(jù)來了,一般是通過FIFO方式處理。

1.簡單的數(shù)組接收、應(yīng)用解析并處理

比如:

static uint8_t gRxCnt = 0;
static uint8_t gRxBuf[10];


void USART1_IRQHandler(void)
{
  //...
  gDgus_RxBuf[gRxCnt] = (uint8_t)USART_ReceiveData(USART1);
  gRxCnt++;
  //...
  
}


void App(void)
{
  //...
  if(0 < gRxCnt)
  {
    //拷貝接收到的數(shù)據(jù)
????gRxCnt?=?0;
????//解析接收數(shù)據(jù)并處理
  }
}

2.中斷函數(shù)接收一幀完整數(shù)據(jù)再處理

比如:

void USART1_IRQHandler(void)
{
  static uint8_t RxCnt = 0;                      //計(jì)數(shù)值
  static uint8_t RxNum = 0;                      //數(shù)量


  if((USART1->SR & USART_FLAG_RXNE) == USART_FLAG_RXNE)
  {
    gDgus_RxBuf[RxCnt] = (uint8_t)USART_ReceiveData(USART1);
    RxCnt++;


    /* 判斷幀頭 */
    if(gDgus_RxBuf[0] != DGUS_FRAME_HEAD1)       //接收到幀頭1
    {
      RxCnt = 0;
      return;
    }
    if((2 == RxCnt) && (gDgus_RxBuf[1] != DGUS_FRAME_HEAD2))
    {
      RxCnt = 0;
      return;
    }


    /* 確定一幀數(shù)據(jù)長度 */
    if(RxCnt == 3)
    {
      RxNum = gDgus_RxBuf[2] + 3;
    }


    /* 接收完一幀數(shù)據(jù) */
    if((6 <= RxCnt) && (RxNum <= RxCnt))
    {
      RxCnt = 0;
      OSMboxPost(EventMBox_Touch, gDgus_RxBuf);  //發(fā)送消息郵箱(執(zhí)行觸控操作)
    }
  }
}

中斷函數(shù)解析完一幀數(shù)據(jù),可以通過標(biāo)志位通知應(yīng)用(裸機(jī)時(shí)),也可以通過消息隊(duì)列、郵箱等方式發(fā)送到應(yīng)用(RTOS時(shí))。

3.RTOS隊(duì)列、郵箱接收

比如:

void DEBUG_COM_IRQHandler(void)
{
  static uint8_t Data;


  if(USART_GetITStatus(DEBUG_COM, USART_IT_RXNE) != RESET)
  {
    Data = USART_ReceiveData(DEBUG_COM);
CLI_RcvDateFromISR(Data);//下面把這個(gè)函數(shù)分離出來了
  }
}


void CLI_RcvDateFromISR(uint8_t RcvData)
{
  static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;


  if(xCLIRcvQueue != NULL)
  {
    xQueueSendFromISR(xCLIRcvQueue, &RcvData, &xHigherPriorityTaskWoken);
  }
}

中斷來一字節(jié)數(shù)據(jù),就通過消息隊(duì)列發(fā)送一個(gè)字節(jié)數(shù)據(jù),如果沒有及時(shí)出來這個(gè)數(shù)據(jù),也是存儲在隊(duì)列中。

通信協(xié)議解析

像上面第2種,簡單通信協(xié)議,項(xiàng)目相對較小的情況下,可以直接在中斷函數(shù)里面處理。

但是,如果項(xiàng)目相對較大、復(fù)雜一點(diǎn),協(xié)議也先對復(fù)雜一點(diǎn),上面第2種在函數(shù)內(nèi)部出來方式就不可取。

1.裸機(jī)環(huán)境

裸機(jī)的情況下,建議用第一種:中斷數(shù)組緩存數(shù)據(jù)(FIFO),應(yīng)用解析通信協(xié)議。

2.RTOS環(huán)境

RTOS情況下,建議用第三種方式:消息隊(duì)列、郵箱等方式接收數(shù)據(jù),然后發(fā)送(通知)應(yīng)用解析協(xié)議。

當(dāng)然,以上說的都只是常見的方式,具體還需要結(jié)合你項(xiàng)目實(shí)際情況。

同時(shí),其它類似I2C、CAN等通信,如有協(xié)議解析,也是類似。

比如之前給大家分享的MavLink,我就用CAN實(shí)現(xiàn)過:

void CAN_RX_IRQHandler(void)
{
  static CanRxMsg RxMessage;
  static MAVRCV_QUEUE_TypeDef MAVRcvQueue_Union;


  CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
                                                 //拷貝長度、 數(shù)據(jù)
  MAVRcvQueue_Union.MAVRcvStruct.MAVLink_Len = RxMessage.DLC;
  memcpy(&MAVRcvQueue_Union.MAVRcvStruct.MAVLink_Buf[0], &RxMessage.Data[0], RxMessage.DLC);


  MAVLink_RcvDateFromISR(&MAVRcvQueue_Union.MAVLinkRcv_Queue[0]);
}

最后,以上內(nèi)容,僅提供思路,代碼不一定適合項(xiàng)目。

審核編輯 :李倩

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5343

    瀏覽量

    120426
  • uart
    +關(guān)注

    關(guān)注

    22

    文章

    1237

    瀏覽量

    101426
  • 嵌入式開發(fā)
    +關(guān)注

    關(guān)注

    18

    文章

    1030

    瀏覽量

    47591

原文標(biāo)題:UART接收數(shù)據(jù)和解析的常見方式

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    介紹內(nèi)部EEPROM數(shù)據(jù)讀取和解析

    EEPROM數(shù)據(jù)讀取和解析上一篇我們簡單介紹了熱成像傳感器德國海曼的HTPA 32x32d,本文主要進(jìn)一步介紹內(nèi)部EEPROM數(shù)據(jù)讀取和解析。存儲結(jié)構(gòu)一覽在說海曼這個(gè)傳感器之前,我們先
    發(fā)表于 12-07 12:14

    stm32 uart1如何通過DMA方式發(fā)送和接收數(shù)據(jù)

    stm32 uart1如何通過DMA方式發(fā)送和接收數(shù)據(jù)
    發(fā)表于 12-08 07:05

    如何去實(shí)現(xiàn)Stm32 Uart用DMA的方式接收數(shù)據(jù)

    DMA有何用途?如何去實(shí)現(xiàn)Stm32 Uart用DMA的方式接收數(shù)據(jù)呢?
    發(fā)表于 12-14 07:37

    如何使用查詢方式通過UART接收數(shù)據(jù)

    使用查詢方式通過UART接收數(shù)據(jù)實(shí)驗(yàn)?zāi)康谋竟?jié)實(shí)驗(yàn)?zāi)康臑閷?shí)現(xiàn)串口發(fā)送和接收。這一節(jié)計(jì)劃采取查詢的方式
    發(fā)表于 02-17 06:26

    常見數(shù)據(jù)發(fā)送接收處理方式

    文章目錄目的發(fā)送緩存數(shù)據(jù)接收解析總結(jié)目的發(fā)送緩存數(shù)據(jù)接收解析總結(jié)
    發(fā)表于 02-17 07:34

    uart pdma方式接收不定長數(shù)據(jù)如何解決?

    目前測試過用uart接收超時(shí)中斷在pdma方式接收時(shí)不起作用,那么有其他方式來解決接收不定長
    發(fā)表于 08-23 08:25

    請問如何接收和解析單片機(jī)串口的數(shù)據(jù),怎么防止丟失和斷貞?

    請問大家如何接收和解析單片機(jī)串口的數(shù)據(jù),怎么防止丟失和斷貞呢?
    發(fā)表于 11-08 07:57

    光耦隔離的4種常見方法對比

    光耦隔離的4種常見方法對比
    發(fā)表于 05-31 11:06 ?13.2w次閱讀
    光耦隔離的4種<b class='flag-5'>常見方</b>法對比

    STC單片機(jī)串口接收一幀數(shù)據(jù)全為0的原因和解決辦法

    STC單片機(jī)串口接收一幀數(shù)據(jù)全為0的原因和解決辦法typedef unsigned char BYTE;void UART_RX_DATA_JX(void){ volatile BYT
    發(fā)表于 12-03 19:06 ?16次下載
    STC單片機(jī)串口<b class='flag-5'>接收</b>一幀<b class='flag-5'>數(shù)據(jù)</b>全為0的原因<b class='flag-5'>和解</b>決辦法

    K210應(yīng)用5-使用查詢方式通過UART接收數(shù)據(jù)

    使用查詢方式通過UART接收數(shù)據(jù)實(shí)驗(yàn)?zāi)康谋竟?jié)實(shí)驗(yàn)?zāi)康臑閷?shí)現(xiàn)串口發(fā)送和接收。這一節(jié)計(jì)劃采取查詢的方式
    發(fā)表于 12-20 19:37 ?10次下載
    K210應(yīng)用5-使用查詢<b class='flag-5'>方式</b>通過<b class='flag-5'>UART</b><b class='flag-5'>接收</b><b class='flag-5'>數(shù)據(jù)</b>

    MCU批量生產(chǎn)下載程序的幾種常見方

    MCU批量生產(chǎn)下載程序的幾種常見方
    的頭像 發(fā)表于 10-24 17:22 ?1636次閱讀
    MCU批量生產(chǎn)下載程序的幾種<b class='flag-5'>常見方</b>法

    使用UART IDLE中斷接收不定長數(shù)據(jù)

    使用UART IDLE中斷接收不定長數(shù)據(jù)
    的頭像 發(fā)表于 09-18 15:41 ?1137次閱讀
    使用<b class='flag-5'>UART</b> IDLE中斷<b class='flag-5'>接收</b>不定長<b class='flag-5'>數(shù)據(jù)</b>

    無功補(bǔ)償?shù)脑怼⒆饔眉?b class='flag-5'>常見方式

    無功補(bǔ)償?shù)脑怼⒆饔眉?b class='flag-5'>常見方式? 無功補(bǔ)償是電力系統(tǒng)中的一項(xiàng)重要技術(shù)措施,用于改善電力質(zhì)量和提高能源利用效率。本文將詳細(xì)介紹無功補(bǔ)償?shù)脑怼⒆饔靡约?b class='flag-5'>常見的補(bǔ)償方式。 一、無功補(bǔ)償?shù)脑?無功功率
    的頭像 發(fā)表于 01-19 14:19 ?9190次閱讀

    常見UART收發(fā)方式

    這種方式適合大多數(shù)單片機(jī),只要有中斷就行。使用UART Write發(fā)送數(shù)據(jù)時(shí),數(shù)據(jù)并不是直接寫入到UART發(fā)送器,而是放進(jìn)了一個(gè)環(huán)形緩沖區(qū)中
    的頭像 發(fā)表于 02-19 16:23 ?911次閱讀

    如何采用“狀態(tài)機(jī)”解析UART數(shù)據(jù)

    如果一個(gè)系統(tǒng)接收上述“不定長度”的協(xié)議幀,將會有一個(gè)挑戰(zhàn)--如何高效接收解析。 為簡化系統(tǒng)設(shè)計(jì),我們強(qiáng)烈建議您采用“狀態(tài)機(jī)”來解析UART
    的頭像 發(fā)表于 03-25 14:29 ?703次閱讀
    如何采用“狀態(tài)機(jī)”<b class='flag-5'>解析</b><b class='flag-5'>UART</b><b class='flag-5'>數(shù)據(jù)</b>幀
    主站蜘蛛池模板: 亚洲视频在线观看视频| 色婷婷综合激情中文在线| 欧美狂野乱码一二三四区| 亚洲不卡视频在线| 国产AV亚洲一区精午夜麻豆| 翘臀后进美女白嫩屁股视频| 99久久国产视频| 男人插曲视频大全免费网站| 91蜜桃视频| 征服丝袜旗袍人妻| 边摸边吃奶边做激情叫床视| 美女不要啊| 91综合久久久久婷婷| 美女坐脸vk| 99久久精品免费精品国产 | 一二三四在线观看高清电视剧| 国内精品免费视频精选在线观看 | 日本高清免费看| 与邻居换娶妻子2在线观看| 极品少妇高潮啪啪AV无码| 亚洲一卡二卡三卡四卡2021麻豆| 久久国产精品二区99| 日日摸夜添夜夜夜添高潮| 最新 国产 精品 精品 视频 | chaopeng 在线视频| 日本激情网址| 国产成人在线免费| 亚洲免费在线| 毛片999| MELODY在线播放无删减| 天海翼精品久久中文字幕| 国产野外无码理论片在线观看| 日本女人下面毛茸茸| 国产91专区| 亚洲午夜电影| 欧美特级特黄AAAAA片| 国产精品久久久久久久伊一| 伊人久久大香线蕉综合电影网| 欧美肥胖女人bbwbbw视频| 99久久国产露脸精品麻豆| 日韩中文亚洲欧美视频二|