注意:
- 本文只对基于 HAL 的串口数据接收部分代码进行记录。
- 本文以 STM32F103RCT6 的 USART2 为例,管脚是 TX->PA2, RX->PA3。
#define UART_RECV_BUF_SIZE_TEMPORARY (64) // 临时缓存区大小
typedef struct
{
unsigned intuart_recv_len_temporary;
// 临时缓存区接收到的数据长度
unsigned intuart_recv_len_formal;
// 正式缓存区接收到的数据长度
unsigned char uart_recv_buf_temporary[UART_RECV_BUF_SIZE_TEMPORARY];
// 临时缓存区
unsigned char uart_recv_buf_formal[UART_RECV_BUF_SIZE_TEMPORARY * 2];
// 正式缓存区
}ts_uart_recv;
第二部分:自定义的全局函数:
/**
* This function enable uart interrupt and reset uart receive buff.
* @param uart_handle
* @param uart_recv
*/
void init_uart_interrupt(UART_HandleTypeDef* uart_handle, ts_uart_recv* uart_recv)
{
memset(uart_recv, 0, sizeof(ts_uart_recv));
// Reset serial receiving memory.__HAL_UART_ENABLE_IT(uart_handle, UART_IT_RXNE);
// Enable UART_IT_RXNE.
__HAL_UART_ENABLE_IT(uart_handle, UART_IT_IDLE);
// Enable UART_IT_IDLE.
__HAL_UART_CLEAR_IDLEFLAG(uart_handle);
// Reset UART_FLAG_IDLE.
}
/**
* This function will be called in the interrupt function.
* @param uart_handle
* @param uart_recv
*/
void uart_interrupt_recv_callback(UART_HandleTypeDef* uart_handle, ts_uart_recv* uart_recv)
{
if(__HAL_UART_GET_FLAG(uart_handle, UART_FLAG_RXNE) != RESET)
{
unsigned char ch =uart_handle->Instance->DR;
// Read a byte.if(uart_recv->uart_recv_len_temporary < sizeof(uart_recv->uart_recv_buf_temporary))
{
uart_recv->uart_recv_buf_temporary[(uart_recv->uart_recv_len_temporary)++] = ch;
// Store data in temporary cache.
}__HAL_UART_CLEAR_FLAG(uart_handle,UART_FLAG_RXNE);
// Reset UART_FLAG_RXNE.
}
if(__HAL_UART_GET_FLAG(uart_handle, UART_FLAG_IDLE) != RESET)
{
if (uart_recv->uart_recv_len_formal < sizeof(uart_recv->uart_recv_buf_formal))
{
memcpy(&uart_recv->uart_recv_buf_formal[uart_recv->uart_recv_len_formal],
uart_recv->uart_recv_buf_temporary,
uart_recv->uart_recv_len_temporary);
// Save data from temporary cache to the end of formal cache.
uart_recv->uart_recv_len_formal += uart_recv->uart_recv_len_temporary;
// Calculate data length in formal cache.
}memset(uart_recv->uart_recv_buf_temporary, 0, uart_recv->uart_recv_len_temporary);
// Reset temporary cache space.
uart_recv->uart_recv_len_temporary = 0;
// Reset data length of temporary cache space./* Reset UART_FLAG_IDLE */
unsigned long temp;
temp = uart_handle->Instance->SR;
// Must
temp = uart_handle->Instance->DR;
// Must
__HAL_UART_CLEAR_IDLEFLAG(uart_handle);
}
}
第三部分:硬件初始化以及静态变量定义
static UART_HandleTypeDef huart2;
// uart2 handle.
static ts_uart_recv uart_recv_2;
// uart2 receive cache.
/**
* This function is to configure UART2 hardware.
*/
void init_uart_2(void)
{
/* Enable clock*/
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Configure GPIO */
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Configure NVIC */
HAL_NVIC_SetPriority(USART2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* Configure UART */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
/* Enable uart interrupt */
init_uart_interrupt(&huart2, &uart_recv_2);
}
第四部分:中断服务函数配置
/**
* This function is uart2 interrupt server function.
*/
void USART2_IRQHandler(void)
{
uart_interrupt_recv_callback(&huart2, &uart_recv_2);
HAL_UART_IRQHandler(&huart2);
}
【STM32 笔记 01 篇(基于 HAL 的串口数据接收)】
推荐阅读
- stm32|基于STM32和freeRTOS智能门锁设计方案
- 日常分享|共享充电宝方案原理,具体部件组成以及主控MUC参数
- #|ARM裸机开发(汇编LED灯实验(I.MX6UL芯片))
- STM32|STM32的四种IO输出模式
- STM32 远程升级(ISP / IAP)
- stm32|stm32f103can总线过滤器配置
- STM32CubeMX配置SDIO模式(非DMA方式)
- STM32|如何建一个STM32F030标准库工程模板
- STM32 时钟RCC相关配置参考stm32f10x_rcc.h
- STM32 NVIC