前言
在嵌入式系統(tǒng)開發(fā)中,經(jīng)常需要處理數(shù)據(jù)的緩存和傳輸,而環(huán)形緩沖區(qū)是一種常見且有效的數(shù)據(jù)結(jié)構(gòu),特別適用于處理實時數(shù)據(jù)流或者在有限的內(nèi)存資源下高效地管理數(shù)據(jù)。在STM32微控制器的開發(fā)中,使用CubeMX工具可以方便地配置和生成環(huán)形緩沖區(qū)的代碼,從而加速開發(fā)過程并提高代碼的可維護性。本文將介紹STM32 CubeMX中環(huán)形緩沖區(qū)的使用方法以及其在嵌入式系統(tǒng)開發(fā)中的重要性。
一、環(huán)形緩沖區(qū)是什么
當(dāng)我們處理數(shù)據(jù)時,有時候需要一個地方來臨時存儲它們,就好像我們用盤子裝菜一樣。但是,內(nèi)存有限,如果盤子裝滿了就得從頭開始放菜,這樣效率不高。環(huán)形緩沖區(qū)就像是一個環(huán)形的菜盤,當(dāng)盤子滿了,就會從一端開始取走菜,同時從另一端繼續(xù)放新的菜,這樣就能不停地裝菜,而且效率很高。
現(xiàn)在,讓我們畫一個簡單的圖來演示一下:
[ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ]
^ ^
| |
取走 放入
這里,我們有一個有8個位置的環(huán)形緩沖區(qū),用方括號表示每個位置。現(xiàn)在,我們從左邊取走了一個數(shù)據(jù),然后從右邊放入了一個新的數(shù)據(jù)。這樣,緩沖區(qū)就像一個環(huán),數(shù)據(jù)可以不停地在其中循環(huán)。
這種數(shù)據(jù)結(jié)構(gòu)適合一方讀buf,一方寫buf的情節(jié)
二、實現(xiàn)環(huán)形緩沖區(qū)
實現(xiàn)分析
我們需要定義存儲區(qū)buf
char buf[100];
我們還需要定義讀位置為0,寫位置為0
后面我們通過這兩個變量來操作讀和寫
int r,w = 0;
那么怎么寫入數(shù)據(jù)和讀數(shù)據(jù)呢?
讀:
首先肯定要有數(shù)據(jù)我們才能讀吧,那么怎么判斷有沒有數(shù)據(jù)呢?
當(dāng)我們的r = w
時,他是空的,如果是空,我們肯定不能讀,如果是有數(shù)據(jù),直接返回對應(yīng)下標(biāo)即可
寫:
首先我們要知道,如果buf滿了,肯定是不能把原來的數(shù)據(jù)給干掉的,那么我們怎么判斷他有沒有滿呢,如果直接使用r = w
來判斷,那就和判斷空是一樣的了,我們可以使用w+1 = r
來判斷,因為如果沒滿,我寫一個進去,他肯定不等于r,如果滿了我寫一個進去他等于r就是滿了,我們使用w+1
來模擬寫入后的w狀態(tài)即可
如果讀和寫超過了這個buf的原始大小,因為他是環(huán)形緩沖區(qū),所以需要把下標(biāo)取余個buf的size
2.1 環(huán)形緩沖區(qū)初始化
首先聲明一個結(jié)構(gòu)體,這個結(jié)構(gòu)體存儲著緩沖區(qū)buf,讀r和寫w
typedef struct
{
int *buf;
int len;
int r;
int w;
}CircleBuf,*p_CircleBuf;
接下來聲明一個函數(shù)進行init操作
void CircleBufInit(p_CircleBuf pbuf,int* buf ,int len)
{
pbuf->r = pbuf->w = 0;
pbuf->buf = buf;
pbuf->len = len;
}
對于這個函數(shù),你可以從外部傳入buf進行緩沖區(qū)的初始化,也可以使用malloc進行內(nèi)存的分配初始化
2.2 寫buf
我們需要實現(xiàn)下面這個函數(shù)來進行寫buf
void CircleBufWrite(p_CircleBuf pCircleBuf, int val);
首先我們需要先定義一個變量存儲w的下一個下標(biāo),并且如果下一個下標(biāo)超出len,需要變成0,實現(xiàn)環(huán)形
int nextW = pCircleBuf->w + 1;
nextW %= pCircleBuf->len;
接下來,我們需要去判斷nextW是否等于r,如果不等于,代碼沒有滿
if (pCircleBuf->r != nextW)
如果沒有滿,我們需要把對應(yīng)的w下標(biāo)賦值成val
然后w下標(biāo)++,再對w進行取余l(xiāng)en,如果下標(biāo)超出len,需要變成0,實現(xiàn)環(huán)形
pCircleBuf->buf[pCircleBuf->w] = val;
pCircleBuf->w++;
pCircleBuf->w %= pCircleBuf->len;
2.3 讀buf
我們需要實現(xiàn)下面這個函數(shù)來進行讀buf
void CircleBufRead(p_CircleBuf pCircleBuf, int* val);
首先我們先要判斷r !=w
才能進行讀操作
if (pCircleBuf->r != pCircleBuf->w)
如果不等于
我們可以把r對應(yīng)的下標(biāo)給val
然后r讀下標(biāo)++
因為可能存在讀完的情況所以我們需要進行取余操作
*val = pCircleBuf->buf[pCircleBuf->r];
pCircleBuf->r++;
pCircleBuf->r %= pCircleBuf->len;
如果等于,我們可以把val的值變成NULL
else
{
val = NULL;
}
2.4 測試
我們可以先寫入一部分?jǐn)?shù)據(jù),然后,我們可以使用CircleBufRead讀出來,讀出來之后立馬進行寫,我們可以通過下面這種方法進行緩沖區(qū)的測試:文章來源:http://www.zghlxwxcb.cn/news/detail-849267.html
CircleBuf cBuf;
int buf[100] = { 0 };
CircleBufInit(&cBuf,&buf,100);
for (int i = 0; i < 100; i++)
{
CircleBufWrite(&cBuf, i);
}
int i = 100;
while (1)
{
int temp = -1;
CircleBufRead(&cBuf, &temp);
printf("%d ", temp);
CircleBufWrite(&cBuf, i);
i++;
Sleep(10);
}
三、代碼總況
//Circle.c
#include "circleBuf.h"
#include <memory.h>
void CircleBufInit(p_CircleBuf pbuf,int* buf ,int len)
{
pbuf->r = pbuf->w = 0;
pbuf->buf = buf;
pbuf->len = len;
}
void CircleBufRead(p_CircleBuf pCircleBuf, int* val)
{
if (pCircleBuf->r != pCircleBuf->w)
{
*val = pCircleBuf->buf[pCircleBuf->r];
pCircleBuf->r++;
pCircleBuf->r %= pCircleBuf->len;
}
else
{
val = NULL;
}
}
void CircleBufWrite(p_CircleBuf pCircleBuf, int val)
{
int nextW = pCircleBuf->w + 1;
nextW %= pCircleBuf->len;
if (pCircleBuf->r != nextW)
{
pCircleBuf->buf[pCircleBuf->w] = val;
pCircleBuf->w++;
pCircleBuf->w %= pCircleBuf->len;
}
}
//Circle.h
#pragma once
typedef struct
{
int *buf;
int len;
int r;
int w;
}CircleBuf,*p_CircleBuf;
void CircleBufInit(p_CircleBuf pbuf, int*buf ,int len);
void CircleBufRead(p_CircleBuf pCircleBuf, int* val);
void CircleBufWrite(p_CircleBuf pCircleBuf, int val);
//main.c
#include <stdio.h>
#include <stdlib.h>
#include "circleBuf.h"
#include <Windows.h>
int main()
{
CircleBuf cBuf;
int buf[100] = { 0 };
CircleBufInit(&cBuf,&buf,100);
for (int i = 0; i < 100; i++)
{
CircleBufWrite(&cBuf, i);
}
int i = 100;
while (1)
{
int temp = -1;
CircleBufRead(&cBuf, &temp);
printf("%d ", temp);
CircleBufWrite(&cBuf, i);
i++;
Sleep(10);
}
system("pause>0");
return 0;
}
總結(jié)
環(huán)形緩沖區(qū)是嵌入式系統(tǒng)開發(fā)中常用的數(shù)據(jù)結(jié)構(gòu)之一,具有高效、可靠的特性。通過STM32 CubeMX工具,我們可以輕松地配置和生成環(huán)形緩沖區(qū)的代碼,從而簡化開發(fā)流程并提高代碼的可維護性。掌握環(huán)形緩沖區(qū)的原理和使用方法,對于STM32微控制器的開發(fā)者來說是必不可少的技能。希望本文能夠幫助讀者更好地理解和應(yīng)用環(huán)形緩沖區(qū),從而更加高效地開發(fā)嵌入式系統(tǒng)。文章來源地址http://www.zghlxwxcb.cn/news/detail-849267.html
到了這里,關(guān)于【STM32 CubeMX】學(xué)STM必會的數(shù)據(jù)結(jié)構(gòu)——環(huán)形緩沖區(qū)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!