精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

UART接收數據和解析的常見方式

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

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

今天就來圍繞串口,簡單分享幾點內容:

串口接收方式

處理接收數據

通信協議解析

串口接收方式

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

輪詢(查詢)接收寄存器

中斷接收數據

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

中斷,平時沒有數據接收時,CPU干自己的事。當有接收數據時,UART串口控制器會響應中斷,通知CPU有事干了。

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

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

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

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

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

處理接收數據

中斷有數據來了,大家怎么處理接收到的數據?

我見過有些小項目,直接在中斷函數里面做一些應用的情況。比如:串口中斷接收一個傳感器發過來的數據,顯示數據并做一些響應的動作。

中斷函數,代碼能少盡少,耗時能少盡少,不能處理太多耗時的復雜的邏輯、應用等。

中斷有數據來了,一般是通過FIFO方式處理。

1.簡單的數組接收、應用解析并處理

比如:

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)
  {
    //拷貝接收到的數據
????gRxCnt?=?0;
????//解析接收數據并處理
  }
}

2.中斷函數接收一幀完整數據再處理

比如:

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


  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;
    }


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


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

中斷函數解析完一幀數據,可以通過標志位通知應用(裸機時),也可以通過消息隊列、郵箱等方式發送到應用(RTOS時)。

3.RTOS隊列、郵箱接收

比如:

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);//下面把這個函數分離出來了
  }
}


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


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

中斷來一字節數據,就通過消息隊列發送一個字節數據,如果沒有及時出來這個數據,也是存儲在隊列中。

通信協議解析

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

但是,如果項目相對較大、復雜一點,協議也先對復雜一點,上面第2種在函數內部出來方式就不可取。

1.裸機環境

裸機的情況下,建議用第一種:中斷數組緩存數據(FIFO),應用解析通信協議。

2.RTOS環境

RTOS情況下,建議用第三種方式:消息隊列、郵箱等方式接收數據,然后發送(通知)應用解析協議。

當然,以上說的都只是常見的方式,具體還需要結合你項目實際情況。

同時,其它類似I2C、CAN等通信,如有協議解析,也是類似。

比如之前給大家分享的MavLink,我就用CAN實現過:

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


  CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
                                                 //拷貝長度、 數據
  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]);
}

最后,以上內容,僅提供思路,代碼不一定適合項目。

審核編輯 :李倩

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5325

    瀏覽量

    120053
  • uart
    +關注

    關注

    22

    文章

    1228

    瀏覽量

    101200
  • 嵌入式開發
    +關注

    關注

    18

    文章

    1022

    瀏覽量

    47518

原文標題:UART接收數據和解析的常見方式

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    介紹內部EEPROM數據讀取和解析

    EEPROM數據讀取和解析上一篇我們簡單介紹了熱成像傳感器德國海曼的HTPA 32x32d,本文主要進一步介紹內部EEPROM數據讀取和解析。存儲結構一覽在說海曼這個傳感器之前,我們先
    發表于 12-07 12:14

    stm32 uart1如何通過DMA方式發送和接收數據

    stm32 uart1如何通過DMA方式發送和接收數據
    發表于 12-08 07:05

    如何去實現Stm32 Uart用DMA的方式接收數據

    DMA有何用途?如何去實現Stm32 Uart用DMA的方式接收數據呢?
    發表于 12-14 07:37

    如何使用查詢方式通過UART接收數據

    使用查詢方式通過UART接收數據實驗目的本節實驗目的為實現串口發送和接收。這一節計劃采取查詢的方式
    發表于 02-17 06:26

    常見數據發送接收處理方式

    文章目錄目的發送緩存數據接收解析總結目的發送緩存數據接收解析總結
    發表于 02-17 07:34

    uart pdma方式接收不定長數據如何解決?

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

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

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

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

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

    STC單片機串口接收一幀數據全為0的原因和解決辦法

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

    K210應用5-使用查詢方式通過UART接收數據

    使用查詢方式通過UART接收數據實驗目的本節實驗目的為實現串口發送和接收。這一節計劃采取查詢的方式
    發表于 12-20 19:37 ?10次下載
    K210應用5-使用查詢<b class='flag-5'>方式</b>通過<b class='flag-5'>UART</b><b class='flag-5'>接收</b><b class='flag-5'>數據</b>

    MCU批量生產下載程序的幾種常見方

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

    使用UART IDLE中斷接收不定長數據

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

    無功補償的原理、作用及常見方式

    無功補償的原理、作用及常見方式? 無功補償是電力系統中的一項重要技術措施,用于改善電力質量和提高能源利用效率。本文將詳細介紹無功補償的原理、作用以及常見的補償方式。 一、無功補償的原理 無功功率
    的頭像 發表于 01-19 14:19 ?8360次閱讀

    常見UART收發方式

    這種方式適合大多數單片機,只要有中斷就行。使用UART Write發送數據時,數據并不是直接寫入到UART發送器,而是放進了一個環形緩沖區中
    的頭像 發表于 02-19 16:23 ?849次閱讀

    如何采用“狀態機”解析UART數據

    如果一個系統接收上述“不定長度”的協議幀,將會有一個挑戰--如何高效接收解析。 為簡化系統設計,我們強烈建議您采用“狀態機”來解析UART
    的頭像 發表于 03-25 14:29 ?633次閱讀
    如何采用“狀態機”<b class='flag-5'>解析</b><b class='flag-5'>UART</b><b class='flag-5'>數據</b>幀