女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

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

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

3天內不再提示

環形緩沖區的實現思路

CHANBAEK ? 來源:固件工人 ? 作者:固件工人 ? 2023-01-17 15:07 ? 次閱讀

1.1 環形緩沖區的實現思路

單片機程序開發一般都會用到UART串口通信,通過通信來實現上位機和單片機程序的數據交互。通信中為了實現正常的收發,一般都會有對應的發送和接收緩存來暫存通信數據。這里使用環形緩沖區的方式來設計數據收發的緩存,即緩沖區溢出后,從緩沖區數組的起始索引處重新進行數據的存儲,這樣可以比較高效地使用緩沖區。

核心思路摘抄如下。規定以下所有方案,在緩沖區滿時不可再寫入數據,緩沖區空時不能讀數據。

常規數組環形緩沖區思路:

設緩沖區大小為N,隊頭out,隊尾in,out、in均是下標表示。

  • 初始時,in = out = 0
  • 隊頭隊尾的更新用取模操作,out = (out + 1) % N,in = (in + 1) % N
  • out == in表示緩沖區空,(in + 1) % N == out表示緩沖區滿
  • 入隊que[in] = value; in = (in + 1) % N;
  • 出隊ret = que[out]; out = (out + 1) % N;
  • 數據長度 len = (in - out + N) % N

改進版數組環形緩沖區思路:

同樣假設緩沖區大小為N,隊頭out,隊尾in,out、in為數組下標,但數據類型為unsigned int。

  • 初始時,in = out = 0
  • 上調緩沖區大小N為2的冪,假設為M
  • 隊頭隊尾更新不再取模,直接++out,++in
  • out == in表示緩沖區空,(in - out) == M表示緩沖區滿
  • 入隊que[in & (M - 1)] = value; ++in;
  • 出隊ret = que[out & (M - 1)] ; ++out;
  • in - out表示數據長度

1.2 環形緩沖區的代碼實現

本文對應的工程代碼鏈接如下。該工程基于eclipse IDE開發,編譯器使用arm-none-eabi-gcc,使用的硬件是STM32F429I-DISCO開發板。

https://download.csdn.net/download/goodrenze/85163032

根據以上的環形緩沖區設計思路,先定義緩存對應的結構體類型如下。

typedef struct _UartBuf_t
{
#if UART_RECORD_LOST_NUM
    uint32_t TxLostNum;
#endif
    uint8_t* TxBuf;
#if UART_BUF_SIZE_IS_2POW
    uint16_t TxIn;
    uint16_t TxOut;
    uint16_t TxSize;
#else
    int16_t TxIn;
    int16_t TxOut;
    int16_t TxSize;
#endif


#if UART_RECORD_LOST_NUM
    uint32_t RxLostNum;
#endif
    uint8_t* RxBuf;
#if UART_BUF_SIZE_IS_2POW
    uint16_t RxIn;
    uint16_t RxOut;
    uint16_t RxSize;
#else
    int16_t RxIn;
    int16_t RxOut;
    int16_t RxSize;
#endif
}UartBuf_t;

以上結構體中,UART_RECORD_LOST_NUM宏定義用于設置是否記錄丟失的數據個數,UART_BUF_SIZE_IS_2POW宏定義用于設置收發緩存的長度是否是2的冪,如果緩存長度是2的冪,則緩存索引和長度使用無符號數,否則使用有符號數。TxBuf和RxBuf指針用于指向對應的發送和接收的緩存數組。

本例程的UART串口發送和接收都是用串口中斷來實現的,串口中斷處理函數的代碼實現如下,只需要在對應的串口中斷入口函數中調用該函數進行串口數據的收發處理即可。

// 以下環形緩沖區的設計思路參考以下鏈接:
// https://www.cnblogs.com/zengzy/p/5139582.html
void UartIrqService(USART_TypeDef* UartX, UartBuf_t* Buf)
{
  uint32_t SR = UartX->SR;
  uint32_t CR1 = UartX->CR1;
  uint32_t CR3 = UartX->CR3;


  UNUSED(CR3);


  while(SR & USART_SR_RXNE)
  {
#if UART_RECORD_LOST_NUM
    if(SR & USART_SR_ORE)
    {
      Buf->RxLostNum++;
    }
#endif


#if UART_BUF_SIZE_IS_2POW
    if ((Buf->RxIn - Buf->RxOut) != Buf->RxSize)
    {
      Buf->RxBuf[Buf->RxIn & (Buf->RxSize - 1)] = (uint8_t)(UartX->DR & (uint8_t)0x00FF);
      Buf->RxIn++;
    }
#else
    if (((Buf->RxIn + 1) % Buf->RxSize) != Buf->RxOut)
    {
      Buf->RxBuf[Buf->RxIn++] = (uint8_t)(UartX->DR & (uint8_t)0x00FF);
      Buf->RxIn %= Buf->RxSize;
    }
#endif
    else
    {
      Buf->RxBuf[Buf->RxIn] = (uint8_t)(UartX->DR & (uint8_t)0x00FF);
#if UART_RECORD_LOST_NUM
      Buf->RxLostNum++;
#endif
    }


    SR = UartX->SR;
  }


  if((SR & USART_SR_TXE) && (CR1 & USART_CR1_TXEIE))
  {
    if(Buf->TxIn != Buf->TxOut)
    {
#if UART_BUF_SIZE_IS_2POW
      UartX->DR = (uint8_t)(Buf->TxBuf[Buf->TxOut & (Buf->TxSize - 1)] & (uint8_t)0x00FF);
      Buf->TxOut++;
#else
      UartX->DR = (uint8_t)(Buf->TxBuf[Buf->TxOut++] & (uint8_t)0x00FF);
      Buf->TxOut %= Buf->TxSize;
#endif
    }
    else
    {
      CLEAR_BIT(UartX->CR1, USART_CR1_TXEIE);
    }
  }
}

以上代碼就是上面提到的環形緩沖區思路的具體實現。當緩沖區的數據長度是2的冪的時候,可以省去求余的運算,可以提高代碼的執行速度。所以如果要求代碼的執行時間盡量短,可以考慮將緩沖區的長度設置成2的冪。

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

    關注

    6063

    文章

    44915

    瀏覽量

    646912
  • 緩沖區
    +關注

    關注

    0

    文章

    36

    瀏覽量

    9316
  • 程序
    +關注

    關注

    117

    文章

    3823

    瀏覽量

    82403
  • uart
    +關注

    關注

    22

    文章

    1267

    瀏覽量

    103245
  • 串口通信
    +關注

    關注

    34

    文章

    1635

    瀏覽量

    56537
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    基于C語言實現環形緩沖區/循環隊列

    這里分享一個自己用純C實現環形緩沖區
    的頭像 發表于 04-11 10:39 ?3859次閱讀
    基于C語言<b class='flag-5'>實現</b><b class='flag-5'>環形</b><b class='flag-5'>緩沖區</b>/循環隊列

    STM32進階之串口環形緩沖區實現

    完了數據,‘0’地址空間的數據進行釋放掉,列隊頭指向下一個可以處理數據的地址‘1’。從而實現整個環形緩沖區的數據讀寫。看圖,隊列頭就是指向已經存儲的數據,并且這個數據是待處理的。下一個CPU處理的數據
    發表于 06-08 14:03

    MCU進階之串口環形緩沖區實現

    是列隊頭的數據,處理完了數據,‘0’地址空間的數據進行釋放掉,列隊頭指向下一個可以處理數據的地址‘1’。從而實現整個環形緩沖區的數據讀寫。看圖,隊列頭就是指向已經存儲的數據,并且這個數據是待處理的。下一個
    發表于 08-17 13:11

    STM32串口環形緩沖區實現

    是列隊頭的數據,處理完了數據,‘0’地址空間的數據進行釋放掉,列隊頭指向下一個可以處理數據的地址‘1’。從而實現整個環形緩沖區的數據讀寫。看圖,隊列頭就是指向已經存儲的數據,并且這個數據是待處理
    發表于 10-16 11:40

    環形緩沖區的設計分享!

    去訪問該緩沖區的最后一個內存位置的的后一位置時回到環形緩沖區的起點。類似一個環一樣。這樣形容就很好理解了,當然有辦法實現了。我在這里采用了2種方式
    發表于 10-28 23:29

    環形緩沖區簡介

    STM32串口數據接收 --環形緩沖區環形緩沖區簡介??在單片機中串口通信是我們使用最頻繁的,使用串口通信就會用到串口的數據接收與發送,環形
    發表于 08-17 06:56

    怎么實現串口環形緩沖區

    怎么實現串口環形緩沖區
    發表于 12-06 06:01

    請問串口的DMA接收緩沖區是不是環形緩沖區

    大家好!請問串口的DMA接收緩沖區是不是環形緩沖區?通過閱讀串口部分的代碼,我了解到這樣幾點:1、串口的DMA接收時循環接收,當緩沖區滿了會重新從頭開始覆蓋掉之前的數據,和
    發表于 08-30 14:27

    rtt的環形緩沖區讀完就丟棄了?

    ;rtt的環形緩沖區讀完就丟棄了,而且是不能讀取任意的位置,現在想到的方法就是: 搞一個數組當緩沖區,不斷增加數據,記住緩沖區頭和尾部對應的序號,滿了就全部往前移動,但這種方法在
    發表于 04-17 14:39

    環形緩沖區讀寫操作的分析與實現

    環形緩沖區是嵌入式系統中一種重要的常用數據結構。在多任務環境下實現時,如果有多個讀寫任務,一般需要用信號量來保護多個任務共享的環形緩沖區。但
    發表于 04-15 11:35 ?40次下載

    環形緩沖區實現原理

    在通信程序中,經常使用環形緩沖區作為數據結構來存放通信中發送和接收的數據。環形緩沖區是一個先進先出的循環緩沖區,可以向通信程序提供對
    的頭像 發表于 03-22 10:03 ?7811次閱讀
    <b class='flag-5'>環形</b><b class='flag-5'>緩沖區</b>的<b class='flag-5'>實現</b>原理

    緩沖區是啥意思 STM32串口數據接收之環形緩沖區

    緩沖區顧名思義是緩沖數據用的。實現緩沖區最簡單的辦法時,定義多個數組,接收一包數據到數組A,就把接收數據的地址換成數組B,每個數據有個標記字節用于表示這個數組是否收到數據,收到數據是否
    的頭像 發表于 07-22 15:33 ?1.1w次閱讀

    STM32串口數據接收 --環形緩沖區

    STM32串口數據接收 --環形緩沖區環形緩沖區簡介??在單片機中串口通信是我們使用最頻繁的,使用串口通信就會用到串口的數據接收與發送,環形
    發表于 12-28 19:24 ?31次下載
    STM32串口數據接收 --<b class='flag-5'>環形</b><b class='flag-5'>緩沖區</b>

    STM32進階之串口環形緩沖區實現

    STM32進階之串口環形緩沖區實現
    的頭像 發表于 09-19 09:20 ?2796次閱讀
    STM32進階之串口<b class='flag-5'>環形</b><b class='flag-5'>緩沖區</b><b class='flag-5'>實現</b>

    C++環形緩沖區設計與實現

    的存儲空間。環形緩沖區的特點是其終點和起點是相連的,形成一個環狀結構。這種數據結構在處理流數據和實現數據緩存等場景中具有廣泛的應用。 環形緩沖區
    的頭像 發表于 11-09 11:21 ?2905次閱讀
    C++<b class='flag-5'>環形</b><b class='flag-5'>緩沖區</b>設計與<b class='flag-5'>實現</b>