3.在st生成的usart.c中,进行重定向(重要!)
/* USER CODE BEGIN 0 */
typedef struct __FILE FILE;
uint8_t uart_rx_buffer[128] = {0};
uint8_t uart_rx_dma_buffer[128] = {0};
/* USER CODE END 0 */
int fputc(int ch, FILE * str)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 10);
return ch;
}4.在usart.c中(cubemx生成的),usart的初始化api函数,在初始化完成的最后,进行dma的初始化和使能(重要!)
/* USER CODE BEGIN USART1_Init 2 */
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart_rx_dma_buffer, sizeof(uart_rx_dma_buffer));
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx ,DMA_IT_HT);
/* USER CODE END USART1_Init 2 */5.在usart_user.c中进行定义环形缓冲区,后需要在main.c中进行环形缓冲区初始化,此步之前记得要把文件中的ringbuffer.c和ringbuffer.h放到自己的库文件中:
// 定义环形缓冲区和接收缓冲区
ringbuffer_t usart_rb;
uint8_t usart_read_buffer[BUUFER_SIZE];
//在main.c中,初始化调用
ringbuffer_init(&usart_rb);
6.在usart_user.c中,进行dma回调函数构写*(重要!)*,如下:
/**
*@brief UART DMA接收完成回调函数
*将接收到的数据写入环形缓冲区,并清空DMA缓冲区
*@param huart 句柄
*@param size 接收的数据大小
*@retval None
**/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
// printf("dma data:%s\r\n", uart_rx_dma_buffer);
// 如果环形缓冲区未满
if(!ringbuffer_is_full(&usart_rb))
{
// 将DMA缓冲区中的数据写入环形缓冲区
ringbuffer_write(&usart_rb, uart_rx_dma_buffer , Size);
}
// 清空DMA缓冲区
memset(uart_rx_dma_buffer, 0, sizeof(uart_rx_dma_buffer));
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart_rx_dma_buffer, BUUFER_SIZE);
}7.uart任务函数构写,在此处进行构写解析数据
/**
* @brief 处理UART接收缓存区中的数据。
* 本函数在每隔100ms时接收新的数据,将空缓冲区清理。
* @param None
* @retval None
*/
void uart_proc(void)
{
// 如果环形缓冲区为空,直接返回
if (ringbuffer_is_empty(&uart_rb)) return;
// 从环形缓冲区取出数据并解析(需要自己构写)
ringbuffer_read(&uart_rb, uart_read_buffer, uart_rb.itemCount);
//此处已经将环形缓冲区的数据取出到uart_read_buffer;
printf('ringbuffer data: %s', uart_read_buffer);
// 清空读取缓冲区
memset(uart_read_buffer, 0, sizeof(uart_read_buffer));
}