板子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