<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 手機與無(wú)線(xiàn)通信 > 市場(chǎng)分析 > 嵌入式通信穩如老狗?試試這個(gè)環(huán)形FIFO緩沖區設計!

嵌入式通信穩如老狗?試試這個(gè)環(huán)形FIFO緩沖區設計!

作者: 時(shí)間:2025-06-04 來(lái)源:半導體產(chǎn)業(yè)縱橫 收藏

本文引用地址:http://dyxdggzs.com/article/202506/471079.htm

在嵌入式系統中,串口(UART)、SPI 等通信接口常常面臨高速數據傳輸的挑戰,尤其在中斷頻繁或處理器負載較高的情況下,容易出現數據丟失。為了解決這一問(wèn)題,環(huán)形緩沖區(Ring Buffer)成為了一個(gè)高效且可靠的解決方案。

什么是環(huán)形緩沖區?

環(huán)形緩沖區,也稱(chēng)為循環(huán)緩沖區,是一種固定大小的 FIFO(先進(jìn)先出)數據結構。它使用兩個(gè)指針:一個(gè)用于寫(xiě)入數據(寫(xiě)指針),另一個(gè)用于讀取數據(讀指針)。當指針達到緩沖區末尾時(shí),它們會(huì )回繞到緩沖區的起始位置,從而形成一個(gè)“環(huán)”。

這種結構特別適用于嵌入式系統中需要連續讀取和寫(xiě)入數據的場(chǎng)景,如串口通信、傳感器數據采集等。

環(huán)形緩沖區的實(shí)現

以下是一個(gè)使用 C 語(yǔ)言實(shí)現的簡(jiǎn)單環(huán)形緩沖區示例:

#define BUFFER_SIZE 128typedef struct {
   uint8_t buffer[BUFFER_SIZE];    volatile uint16_t head;    volatile uint16_t tail;
} RingBuffer;void RingBuffer_Init(RingBuffer *rb) {
   rb->head = 0;
   rb->tail = 0;
}bool RingBuffer_IsEmpty(RingBuffer *rb) {    return rb->head == rb->tail;
}bool RingBuffer_IsFull(RingBuffer *rb) {    return ((rb->head + 1) % BUFFER_SIZE) == rb->tail;
}bool RingBuffer_Put(RingBuffer *rb, uint8_t data) {    if (RingBuffer_IsFull(rb)) {        return false; // 緩沖區已滿(mǎn)
   }
   rb->buffer[rb->head] = data;
   rb->head = (rb->head + 1) % BUFFER_SIZE;    return true;
}bool RingBuffer_Get(RingBuffer *rb, uint8_t *data) {    if (RingBuffer_IsEmpty(rb)) {        return false; // 緩沖區為空
   }
   *data = rb->buffer[rb->tail];
   rb->tail = (rb->tail + 1) % BUFFER_SIZE;    return true;
}

在上述代碼中,RingBuffer_Put 函數用于向緩沖區寫(xiě)入數據,RingBuffer_Get 函數用于從緩沖區讀取數據。通過(guò)使用取模運算,指針在達到緩沖區末尾時(shí)會(huì )回繞到起始位置,實(shí)現循環(huán)操作。

應用于 UART 接收中斷

在串口通信中,接收數據通常通過(guò)中斷方式進(jìn)行處理。每當接收到一個(gè)字節的數據時(shí),接收中斷服務(wù)程序(ISR)會(huì )被觸發(fā)。為了防止在高頻率接收數據時(shí)丟失數據,可以在 ISR 中將接收到的數據存入環(huán)形緩沖區。

RingBuffer rxBuffer;void USART_RX_IRQHandler(void) {    uint8_t data = USART_ReadData(); // 讀取接收到的數據
   RingBuffer_Put(&rxBuffer, data); // 將數據存入環(huán)形緩沖區}

在主循環(huán)或其他任務(wù)中,可以定期檢查環(huán)形緩沖區,并處理其中的數據:

void ProcessReceivedData(void) {    uint8_t data;    while (RingBuffer_Get(&rxBuffer, &data)) {        // 處理接收到的數據
   }
}

這種方式可以有效地緩解中斷處理壓力,防止數據丟失。

應用于 SPI 通信

在 SPI 通信中,尤其是主設備從多個(gè)從設備接收數據的情況下,數據可能會(huì )以較高的速率到達。使用環(huán)形緩沖區可以暫存接收到的數據,等待主循環(huán)或其他任務(wù)進(jìn)行處理。

RingBuffer spiRxBuffer;void SPI_RX_IRQHandler(void) {    uint8_t data = SPI_ReadData(); // 讀取接收到的數據
   RingBuffer_Put(&spiRxBuffer, data); // 將數據存入環(huán)形緩沖區}

在主循環(huán)中處理接收到的數據:

void ProcessSPIData(void) {    uint8_t data;    while (RingBuffer_Get(&spiRxBuffer, &data)) {        // 處理 SPI 接收到的數據
   }
}

這種方式可以提高 SPI 通信的可靠性,防止數據丟失。

優(yōu)化建議

  1. 緩沖區大?。焊鶕?shí)際應用的數據速率和處理能力,合理設置緩沖區的大小。

  2. 中斷優(yōu)先級:確保接收中斷的優(yōu)先級足夠高,以及時(shí)響應數據接收。

  3. 線(xiàn)程安全:在多線(xiàn)程或多任務(wù)系統中,訪(fǎng)問(wèn)環(huán)形緩沖區時(shí)需要考慮線(xiàn)程安全,可能需要使用互斥鎖或禁用中斷等方式。

  4. 溢出處理:在緩沖區滿(mǎn)的情況下,可以選擇覆蓋舊數據、丟棄新數據或設置標志位通知主程序處理。

通過(guò)合理地設計和實(shí)現環(huán)形緩沖區,可以顯著(zhù)提高嵌入式系統中串口、SPI 等通信接口的數據處理能力,減少數據丟失的風(fēng)險,提高系統的穩定性和可靠性。



關(guān)鍵詞: 環(huán)形FIFO緩沖區

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>