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

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

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

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

嵌入式技術(shù) ? 來源:嵌入式技術(shù) ? 作者:嵌入式技術(shù) ? 2022-05-31 11:27 ? 次閱讀

環(huán)形緩沖區(qū)簡介
單片機(jī)中串口通信是我們使用最頻繁的,使用串口通信就會用到串口的數(shù)據(jù)接收與發(fā)送,環(huán)形緩沖區(qū)方式接收數(shù)據(jù)可以更好的保證數(shù)據(jù)丟幀率第。
在通信程序中,經(jīng)常使用環(huán)形緩沖器作為數(shù)據(jù)結(jié)構(gòu)來存放通信中發(fā)送和接收的數(shù)據(jù)。環(huán)形緩沖區(qū)是一個先進(jìn)先出的循環(huán)緩沖區(qū),可以向通信程序提供對緩沖區(qū)的互斥訪問。
環(huán)形緩沖區(qū)的一個有用特性是:當(dāng)一個數(shù)據(jù)元素被用掉后,其余數(shù)據(jù)元素不需要移動其存儲位置。相反,一個非圓形緩沖區(qū)(例如一個普通的隊列)在用掉一個數(shù)據(jù)元素后,其余數(shù)據(jù)元素需要向前搬移。換句話說,環(huán)形緩沖區(qū)適合實現(xiàn)先進(jìn)先出緩沖區(qū),而非環(huán)形緩沖區(qū)適合后進(jìn)先出緩沖區(qū)。

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDQ1MzY5NA==,size_16,color_FFFFFF,t_70#pic_center

STM32環(huán)形緩沖區(qū)示例

串口配置示例

#include "usart.h"
/********************串口初始化函數(shù)封裝*********************
****硬件接口:USART1_TX -- PA9(發(fā)送)
**						USART1-RX --PA10(接收)
**						USART2_TX -- PA2(發(fā)送)
**						USART2-RX --PA3(接收)
**						USART3_TX -- PB10(發(fā)送)
**						USART3_RX -- PB11(接收)
形參:USART_TypeDef *USARTx -- 要配置的哪個串口
**			u32 baud  --波特率
**			u32 sysclk --時鐘頻率(USART1 --72MHZ ,USAT2\USART3 --36MHZ)
**
***********************************************************/
void Usartx_Init(USART_TypeDef *USARTx,u32 baud,u32 sysclk)
{
	if(USART1 == USARTx)
	{
			/*1.開時鐘*/
		RCC->APB2ENR|=1<<2;//PA時鐘
		RCC->APB2ENR|=1<<14;//串口時鐘
		RCC->APB2RSTR|=1<<14;//串口復(fù)位
		RCC->APB2RSTR&=~(1<<14);//取消復(fù)位
		/*2.配置GPIO口*/
		GPIOA->CRH&=0xFFFFF00F;
		GPIOA->CRH|=0x000008B0;//上下拉輸入,復(fù)用推挽輸出	
		#ifdef USART1_IQR
			USART1->CR1|=1<<5;//開啟串口接收中斷
			STM32_NVIC_SetPriority(USART1_IRQn,0,1);//設(shè)置優(yōu)先級
		#endif
	}
	else if(USART2 == USARTx)
	{
		/*1.開時鐘*/
		RCC->APB2ENR|=1<<2;//PA時鐘
		RCC->APB1ENR|=1<<17;//USART2時鐘
		RCC->APB1RSTR|=1<<17;//開復(fù)位時鐘
		RCC->APB1RSTR&=~(1<<17);//取消復(fù)位
		/*2.配置GPIO口*/
		GPIOA->CRL&=0xFFFF00FF;//清除原來寄存器中的值
		GPIOA->CRL|=0x00008B00;		
		#ifdef USART2_IRQ
			USART2->CR1|=1<<5;//串口2接收中斷
			STM32_NVIC_SetPriority(USART2_IRQn,1,2);//設(shè)置優(yōu)先級
		#endif
	}
	else if(USART3 == USARTx)
	{
		/*1.開時鐘*/
		RCC->APB2ENR|=1<<3;//PB時鐘
		RCC->APB1ENR|=1<<18;//USART3時鐘
		RCC->APB1RSTR|=1<<18;//開復(fù)位時鐘
		RCC->APB1RSTR&=~(1<<18);//取消復(fù)位
		/*2.配置GPIO口*/
		GPIOB->CRH&=0xFFFF00FF;
		GPIOB->CRH|=0x00008B00;	
		#ifdef USART3_IRQ
			USART3->CR1|=1<<5;//開啟接收中斷
			STM32_NVIC_SetPriority(USART3_IRQn,0,0);//設(shè)置優(yōu)先級
		#endif
	}
	else return;
	/*3.配置串口核心寄存器*/
	USARTx->BRR=sysclk*1000000/baud;//設(shè)置波特率
	USARTx->CR1|=1<<2;//接收使能
	USARTx->CR1|=1<<3;//發(fā)送使能
	USARTx->CR1|=1<<13;//使能串口3
}
/************************串口發(fā)送字符************************/
void Usartx_SendString(USART_TypeDef *USARTx,u8 *str,u8 len)
{
	while(len--)
	{
		USARTx->DR=*str;
		while((USARTx->SR&1<<7)==0){}//等待數(shù)據(jù)發(fā)送完成
		str++;
	}
}
/***************printf重定向**************/
int fputc(int c,FILE *stream)
{
	USART1->DR=c;
	while(!(USART1->SR&1<<7)){}
	return c;
}

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

/********************串口接收數(shù)據(jù)結(jié)構(gòu)體********************/
#define USART1_LEN 200 //緩沖區(qū)大小
typedef struct 
{
	char buff[USART1_LEN];//緩沖區(qū)
    u8 usart1_rx_len;//保存的數(shù)據(jù)長度
    u8 usart1_flag;//數(shù)據(jù)接收完成標(biāo)志
	u8 w;//寫
	u8 r;//讀
}USART1_RX;
USART1_RX USART1_rx={{0},0,0,0,0};//串口接收數(shù)據(jù)緩沖區(qū)初始化
void USART1_IRQHandler(void)
{
	u8 c;
	if(USART1->SR&1<<5)
	{
        c=USART1->DR;
        //當(dāng)寫入的數(shù)據(jù)長度==緩沖區(qū)長度,表示緩沖區(qū)滿
        if(USART1_rx.usart1_rx_lenCNT=0;//清空計數(shù)器值   
			TIM2->CR1|=1<<0;
        }
        else USART1_rx.usart1_flag=1;//緩沖區(qū)滿	
	}
	USART1->SR=0;//清除標(biāo)志位
}
)>

讀取緩沖區(qū)數(shù)據(jù)

/**********************從緩沖區(qū)讀取數(shù)據(jù)******************
**
**形參:u8 *tx_data -- 讀取數(shù)據(jù)保存地址
**
*********************************************************/
u8 Usart1_Annular_txdata(u8 *tx_data)
{   
    u8 len=0;
    //緩沖區(qū)為空 或者 USART1_rx.usart1_flag 數(shù)據(jù)接收完成標(biāo)志(為了兼容字符串接收處理)
    if(USART1_rx.usart1_rx_len==0 || USART1_rx.usart1_flag==0)return 0;
    while(USART1_rx.usart1_rx_len)
    {
        *tx_data=USART1_rx.buff[USART1_rx.r];//讀取緩沖區(qū)數(shù)據(jù)
        USART1_rx.r= (USART1_rx.r+1)%USART1_LEN;
        USART1_rx.usart1_rx_len--;//緩沖區(qū)長度-1
        tx_data++;
        len++;
    }
    USART1_rx.usart1_flag=0;//清除標(biāo)志位
    *tx_data='\0';//接收到的字符保存為字符串
    return len;//返回讀取到的字符個數(shù)
}

主函數(shù)

#include "stm32f10x.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
u8 buff[200];
int main()
{
    u8 stat=0;
	Led_Init();//LED初始化
	Usartx_Init(USART1,115200,72);
	TIMx_Init(TIM2,72,20000);//通過定時器2輔助串口接收數(shù)據(jù),20ms
	printf("串口初始化完成\r\n");
	/*輪詢*/
	while(1)
	{
        stat=Usart1_Annular_txdata(buff);
        if(stat)
        {
            Usartx_SendString(USART1,buff,stat);
        }
	}
}
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDQ1MzY5NA==,size_16,color_FFFFFF,t_70#pic_center

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

    關(guān)注

    6037

    文章

    44558

    瀏覽量

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

    關(guān)注

    0

    文章

    33

    瀏覽量

    9110
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10900

    瀏覽量

    356008
收藏 人收藏

    評論

    相關(guān)推薦

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

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

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

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

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

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

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

    什么是STM32環(huán)形緩沖區(qū)?
    發(fā)表于 11-18 07:52

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

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

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

    STM32環(huán)形緩沖區(qū)怎么實現(xiàn)?
    發(fā)表于 12-07 07:25

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

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

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

    環(huán)形緩沖區(qū)是嵌入式系統(tǒng)中一種重要的常用數(shù)據(jù)結(jié)構(gòu)。在多任務(wù)環(huán)境下實現(xiàn)時,如果有多個讀寫任務(wù),一般需要用信號量來保護(hù)多個任務(wù)共享的環(huán)形緩沖區(qū)。但是如果只存在1 個讀
    發(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ū)是一個先進(jìn)先出的循環(huán)緩沖區(qū),可以向通信程序提供對
    的頭像 發(fā)表于 03-22 10:03 ?7541次閱讀
    <b class='flag-5'>環(huán)形</b><b class='flag-5'>緩沖區(qū)</b>的實現(xiàn)原理

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

    完成。 缺點: ①緩沖數(shù)據(jù)組數(shù)一定,且有多變量,代碼結(jié)構(gòu)不太清晰。 ②接收數(shù)據(jù)長度可能大于數(shù)組大小,也可能小于數(shù)組大小。不靈活,需要接收數(shù)據(jù)很長時容易出錯,且內(nèi)存利用率低。 解決這個問題的好辦法是:環(huán)形緩沖區(qū)。
    的頭像 發(fā)表于 07-22 15:33 ?1.1w次閱讀

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

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

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

    單片機(jī)程序開發(fā)一般都會用到UART串口通信,通過通信來實現(xiàn)上位機(jī)和單片機(jī)程序的數(shù)據(jù)交互。通信中為了實現(xiàn)正常的收發(fā),一般都會有對應(yīng)的發(fā)送和接收緩存來暫存通信數(shù)據(jù)。這里使用環(huán)形緩沖區(qū)的方式來設(shè)計數(shù)據(jù)收發(fā)的緩存,即緩沖區(qū)溢出后,從
    的頭像 發(fā)表于 01-17 15:07 ?1639次閱讀

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

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

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

    一、環(huán)形緩沖區(qū)基礎(chǔ)理論解析(Basic Theory of Circular Buffer) 1.1 環(huán)形緩沖區(qū)的定義與作用(Definition and Function of Ci
    的頭像 發(fā)表于 11-09 11:21 ?2056次閱讀
    C++<b class='flag-5'>環(huán)形</b><b class='flag-5'>緩沖區(qū)</b>設(shè)計與實現(xiàn)

    Stm32采用環(huán)形緩沖區(qū)接收rk3588的數(shù)據(jù)代碼

    Stm32采用環(huán)形緩沖區(qū)接收rk3588的數(shù)據(jù)代碼
    的頭像 發(fā)表于 05-15 10:10 ?594次閱讀