【STM32】STM32CubeIDE HAL庫Ring-buffer例程

板子G474RE。

STM32HAL庫Ring-buffer使用。

//注意:HAL庫中,中斷每執行一次,就關閉,所以需要重新開啓中斷。第一次開啓在main函數中。

HAL_UART_Receive_IT(&hlpuart1,LPUART1_temp,1);

/*注意:隊列中數據並沒完全刪除,僅是被覆蓋。HAL_UART_Transmit只能定長輸出數據
         * buffer.num是輸出數據的定長,所以重新初始化
         * 隊列結構,重新準備接收新數據

*/
//printf 重定義

/* 阻塞判斷串口是否發送完成 */
	 while((LPUART1->ISR & 0X40) == 0);

	 /* 串口發送完成,將字符發送*/
	 LPUART1->TDR = (uint8_t) ch;

踩坑一下午,看了很多文章。網上大部分都是固件庫,HAL庫某方面確實坑。

 

實現代碼:兩種都是數組實現緩存空間,幾乎沒什麼區別。

起始:隊尾指向同一個地方,插入數據(尾插法),尾指針動,讀數據(頭讀法),順序遍歷。

注意:Ring-buffer,例如第一次插入5個數據,初始化後,再插入3個,數據前三個被覆蓋,後面繼續保留。造成空間浪費, 因爲HAL庫的原因(HAL_UART_Transmit函數只能定長髮送數據)並沒找到解決辦法。

/*
 * _usart.c
 *
 *  Created on: Jun 18, 2020
 *      Author: guolunlun
 */
#include "user/_usart.h"


//extern uint8_t LPUART1_Rx_Buf[1024];
//extern uint8_t LPUART1_Rx_cnt;
//extern uint8_t LPUART1_Rx_flg;
//extern uint8_t LPUART1_temp[1];
//其它文件中引用
uint8_t LPUART1_Rx_Buf[1024] = {0}; //LPUART1存儲接收數據
uint8_t LPUART1_Rx_flg = 0;                   //LPUART1接收完成標誌
uint8_t LPUART1_Rx_cnt = 0;                   //LPUART1接受數據計數器
uint8_t LPUART1_temp[1] = {0};       //LPUART1接收數據緩存


#define RING
//#define ARRAY
//ring_buffer 定義緩衝區總長
#define  MAX_Array  200

//定義一個ring_buffer結構體
typedef struct

{
	uint16_t head;//緩衝區頭部位置

    uint16_t tail;//緩衝區尾部位置

    uint8_t ringBuf[MAX_Array];//緩衝區數組
    uint16_t num;//緩衝區數組中數據個數

}ringBuffer_t;

/**************************系統回調函數********************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//LPUART1串口
	if(huart->Instance==LPUART1)
	  {
#ifdef RING
		Ring_Buffer_Write(LPUART1_temp[0]);
#endif
#ifdef ARRAY
		//規定發送只有ACSII,接收的數據存起來,直到遇到換行或空格
		LPUART1_Rx_Buf[LPUART1_Rx_cnt] = LPUART1_temp[0];
		LPUART1_Rx_cnt++;
#endif
	    if(0x0a == LPUART1_temp[0]||LPUART1_temp[0]==0x20)
	    {//換行或空格符,結束
	    	LPUART1_Rx_flg = 1;//標誌位置1
	    }

	    HAL_UART_Receive_IT(&hlpuart1,LPUART1_temp,1);
	    //中斷每執行一次,就關閉,所以重新開啓中斷
	    //在main函數中,記得開啓
	  }

}


//定義一個ring_buffer結構體對象
ringBuffer_t buffer;


void buffer_init(void){
	buffer.head=0;
	buffer.tail=0;
	buffer.num=0;
	//ring_buffer結構初始化
}
void _usart_test(void){

	if(LPUART1_Rx_flg)
	        {

#ifdef RING
	       Ring_Buffer_Read();

#endif
#ifdef ARRAY

	       	   	 HAL_UART_Transmit(&hlpuart1,LPUART1_Rx_Buf,LPUART1_Rx_cnt,0xff);
	          //終端回顯發送接收到的數據

	        	memset(LPUART1_Rx_Buf,0x00,sizeof(LPUART1_Rx_Buf));//清空數組

	          	LPUART1_Rx_cnt = 0;//計數置零

#endif
	          	LPUART1_Rx_flg = 0;//標誌位置零
	        }
}
/***************************/


uint8_t Ring_Buffer_Write(uint8_t data){

	if(buffer.num>=MAX_Array){
		return 1;
	}//判斷是否溢出
	buffer.ringBuf[buffer.tail]=data;//從尾部增加數據,把數據存儲在循環隊列中
	buffer.tail=(buffer.tail+1)%MAX_Array;//尾部節點數據偏移
	buffer.num++;//記錄循環隊列中數據個數

	return 0;
}
uint8_t Ring_Buffer_Read(void){

	if(buffer.num==0){
		return 1;//隊列是否爲空
	}

	else{
		//輸出隊列中數據
		HAL_UART_Transmit(&hlpuart1,buffer.ringBuf,buffer.num,0xff);
		//printf("%d\n",buffer.num);
		printf("ARRAY test\n");
		buffer_init();//初始化隊列結構
		/*注意:隊列中數據並沒完全刪除,僅是被覆蓋。HAL_UART_Transmit只能定長輸出數據
		 * buffer.num是輸出數據的定長,所以重新初始化
		 * 隊列結構,重新準備接收新數據*/

		return 0;
	}
}

工程代碼:

鏈接:https://pan.baidu.com/s/1c5WuIUx4O3OFR-YvQdHjaw 
提取碼:sgop

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章