chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

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

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

環(huán)形緩沖區(qū)的實現(xiàn)思路

CHANBAEK ? 來源:固件工人 ? 作者:固件工人 ? 2023-01-17 15:07 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1.1 環(huán)形緩沖區(qū)的實現(xiàn)思路

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

核心思路摘抄如下。規(guī)定以下所有方案,在緩沖區(qū)滿時不可再寫入數(shù)據(jù),緩沖區(qū)空時不能讀數(shù)據(jù)。

常規(guī)數(shù)組環(huán)形緩沖區(qū)思路:

設(shè)緩沖區(qū)大小為N,隊頭out,隊尾in,out、in均是下標表示。

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

改進版數(shù)組環(huán)形緩沖區(qū)思路:

同樣假設(shè)緩沖區(qū)大小為N,隊頭out,隊尾in,out、in為數(shù)組下標,但數(shù)據(jù)類型為unsigned int。

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

1.2 環(huán)形緩沖區(qū)的代碼實現(xiàn)

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

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

根據(jù)以上的環(huán)形緩沖區(qū)設(shè)計思路,先定義緩存對應(yīng)的結(jié)構(gòu)體類型如下。

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;

以上結(jié)構(gòu)體中,UART_RECORD_LOST_NUM宏定義用于設(shè)置是否記錄丟失的數(shù)據(jù)個數(shù),UART_BUF_SIZE_IS_2POW宏定義用于設(shè)置收發(fā)緩存的長度是否是2的冪,如果緩存長度是2的冪,則緩存索引和長度使用無符號數(shù),否則使用有符號數(shù)。TxBuf和RxBuf指針用于指向?qū)?yīng)的發(fā)送和接收的緩存數(shù)組。

本例程的UART串口發(fā)送和接收都是用串口中斷來實現(xiàn)的,串口中斷處理函數(shù)的代碼實現(xiàn)如下,只需要在對應(yīng)的串口中斷入口函數(shù)中調(diào)用該函數(shù)進行串口數(shù)據(jù)的收發(fā)處理即可。

// 以下環(huán)形緩沖區(qū)的設(shè)計思路參考以下鏈接:
// 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);
    }
  }
}

以上代碼就是上面提到的環(huán)形緩沖區(qū)思路的具體實現(xiàn)。當緩沖區(qū)的數(shù)據(jù)長度是2的冪的時候,可以省去求余的運算,可以提高代碼的執(zhí)行速度。所以如果要求代碼的執(zhí)行時間盡量短,可以考慮將緩沖區(qū)的長度設(shè)置成2的冪。

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

    關(guān)注

    6074

    文章

    45453

    瀏覽量

    667025
  • 緩沖區(qū)
    +關(guān)注

    關(guān)注

    0

    文章

    36

    瀏覽量

    9483
  • 程序
    +關(guān)注

    關(guān)注

    117

    文章

    3838

    瀏覽量

    85063
  • uart
    +關(guān)注

    關(guān)注

    22

    文章

    1308

    瀏覽量

    106379
  • 串口通信
    +關(guān)注

    關(guān)注

    34

    文章

    1661

    瀏覽量

    57811
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    基于C語言實現(xiàn)環(huán)形緩沖區(qū)/循環(huán)隊列

    這里分享一個自己用純C實現(xiàn)環(huán)形緩沖區(qū)。
    的頭像 發(fā)表于 04-11 10:39 ?4731次閱讀
    基于C語言<b class='flag-5'>實現(xiàn)</b><b class='flag-5'>環(huán)形</b><b class='flag-5'>緩沖區(qū)</b>/循環(huán)隊列

    STM32進階之串口環(huán)形緩沖區(qū)實現(xiàn)

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

    MCU進階之串口環(huán)形緩沖區(qū)實現(xiàn)

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

    STM32串口環(huán)形緩沖區(qū)實現(xiàn)

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

    環(huán)形緩沖區(qū)的設(shè)計分享!

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

    環(huán)形緩沖區(qū)簡介

    STM32串口數(shù)據(jù)接收 --環(huán)形緩沖區(qū)環(huán)形緩沖區(qū)簡介??在單片機中串口通信是我們使用最頻繁的,使用串口通信就會用到串口的數(shù)據(jù)接收與發(fā)送,環(huán)形
    發(fā)表于 08-17 06:56

    怎么實現(xiàn)串口環(huán)形緩沖區(qū)?

    怎么實現(xiàn)串口環(huán)形緩沖區(qū)
    發(fā)表于 12-06 06:01

    請問串口的DMA接收緩沖區(qū)是不是環(huán)形緩沖區(qū)

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

    rtt的環(huán)形緩沖區(qū)讀完就丟棄了?

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

    環(huán)形緩沖區(qū)讀寫操作的分析與實現(xiàn)

    環(huán)形緩沖區(qū)是嵌入式系統(tǒng)中一種重要的常用數(shù)據(jù)結(jié)構(gòu)。在多任務(wù)環(huán)境下實現(xiàn)時,如果有多個讀寫任務(wù),一般需要用信號量來保護多個任務(wù)共享的環(huán)形緩沖區(qū)。但
    發(fā)表于 04-15 11:35 ?40次下載

    環(huán)形緩沖區(qū)實現(xiàn)原理

    在通信程序中,經(jīng)常使用環(huán)形緩沖區(qū)作為數(shù)據(jù)結(jié)構(gòu)來存放通信中發(fā)送和接收的數(shù)據(jù)。環(huán)形緩沖區(qū)是一個先進先出的循環(huán)緩沖區(qū),可以向通信程序提供對
    的頭像 發(fā)表于 03-22 10:03 ?8423次閱讀
    <b class='flag-5'>環(huán)形</b><b class='flag-5'>緩沖區(qū)</b>的<b class='flag-5'>實現(xiàn)</b>原理

    緩沖區(qū)是啥意思 STM32串口數(shù)據(jù)接收之環(huán)形緩沖區(qū)

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

    STM32串口數(shù)據(jù)接收 --環(huán)形緩沖區(qū)

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

    STM32進階之串口環(huán)形緩沖區(qū)實現(xiàn)

    STM32進階之串口環(huán)形緩沖區(qū)實現(xiàn)
    的頭像 發(fā)表于 09-19 09:20 ?3398次閱讀
    STM32進階之串口<b class='flag-5'>環(huán)形</b><b class='flag-5'>緩沖區(qū)</b><b class='flag-5'>實現(xiàn)</b>

    C++環(huán)形緩沖區(qū)設(shè)計與實現(xiàn)

    的存儲空間。環(huán)形緩沖區(qū)的特點是其終點和起點是相連的,形成一個環(huán)狀結(jié)構(gòu)。這種數(shù)據(jù)結(jié)構(gòu)在處理流數(shù)據(jù)和實現(xiàn)數(shù)據(jù)緩存等場景中具有廣泛的應(yīng)用。 環(huán)形緩沖區(qū)
    的頭像 發(fā)表于 11-09 11:21 ?3910次閱讀
    C++<b class='flag-5'>環(huán)形</b><b class='flag-5'>緩沖區(qū)</b>設(shè)計與<b class='flag-5'>實現(xiàn)</b>