一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

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

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

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

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

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

掃碼添加小助手

加入工程師交流群

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

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

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

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

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

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

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

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

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

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

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

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

根據(jù)以上的環(huán)形緩沖區(qū)設(shè)計(jì)思路,先定義緩存對(duì)應(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ù)個(gè)數(shù),UART_BUF_SIZE_IS_2POW宏定義用于設(shè)置收發(fā)緩存的長(zhǎng)度是否是2的冪,如果緩存長(zhǎng)度是2的冪,則緩存索引和長(zhǎng)度使用無(wú)符號(hào)數(shù),否則使用有符號(hào)數(shù)。TxBuf和RxBuf指針用于指向?qū)?yīng)的發(fā)送和接收的緩存數(shù)組。

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

// 以下環(huán)形緩沖區(qū)的設(shè)計(jì)思路參考以下鏈接:
// 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ū)思路的具體實(shí)現(xiàn)。當(dāng)緩沖區(qū)的數(shù)據(jù)長(zhǎng)度是2的冪的時(shí)候,可以省去求余的運(yùn)算,可以提高代碼的執(zhí)行速度。所以如果要求代碼的執(zhí)行時(shí)間盡量短,可以考慮將緩沖區(qū)的長(zhǎng)度設(shè)置成2的冪。

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

    關(guān)注

    6067

    文章

    44989

    瀏覽量

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

    關(guān)注

    0

    文章

    36

    瀏覽量

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

    關(guān)注

    117

    文章

    3826

    瀏覽量

    82967
  • uart
    +關(guān)注

    關(guān)注

    22

    文章

    1276

    瀏覽量

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

    關(guān)注

    34

    文章

    1639

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    STM32串口數(shù)據(jù)接收 --環(huán)形緩沖區(qū)環(huán)形緩沖區(qū)簡(jiǎn)介??在單片機(jī)中串口通信是我們使用最頻繁的,使用串口通信就會(huì)用到串口的數(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進(jìn)階之串口環(huán)形緩沖區(qū)實(shí)現(xiàn)

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

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

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