板子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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)