【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库某方面确实坑。

 

实现代码:两种都是数组实现缓存空间,几乎没什么区别。

【STM32】STM32CubeIDE HAL库Ring-buffer例程_第1张图片

起始:队尾指向同一个地方,插入数据(尾插法),尾指针动,读数据(头读法),顺序遍历。

注意: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

 

你可能感兴趣的:(STM32控制系统开发)