CubeMX 配置
配置串口
配置DMA
配置中断
其他配置默认即可。
特别注意
DMA的初始化一定要在串口初始化之前调用,否则会导致dma初始化失败。
MX_DMA_Init();
MX_USART1_UART_Init();
初始化顺序可通过工程设置调整:
代码修改
DMA接收
usart.c
定义dma接收数组:
uint8_t uart1RxBuf[USART1_RX_BUFFER_SIZE];
volatile uint8_t UART1_RX_len;
volatile uint8_t UART1_RX_end_flag = 0;
修改MX_USART1_UART_Init,在初始化之后加入:
/* USER CODE BEGIN USART1_Init 2 */
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart1RxBuf, USART1_RX_BUFFER_SIZE);
/* USER CODE END USART1_Init 2 */
usart.h
添加宏及声明:
#define USART1_RX_BUFFER_SIZE 1024
extern uint8_t uart1RxBuf[];
extern volatile uint8_t UART1_RX_len;
extern volatile uint8_t UART1_RX_end_flag;
stm32f4xx_it.c
在/* USER CODE BEGIN EV */
位置增加:
/**
* @brief This function handles UARTx Rx event.
*/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart->Instance == USART1)
{
UART1_RX_len = Size;
// 这里处理接收到的数据
UART1_RX_end_flag = 1;
}
}
以复写 stm32f4xx_hal_uart.c 中如下弱函数(也可以通过注册回调函数的方式实现):
在串口中断中调用:
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart1RxBuf, USART1_RX_BUFFER_SIZE);
/* USER CODE END USART1_IRQn 1 */
}
DMA发送
为了便于调用,可封装一下DMA发送函数:
HAL_StatusTypeDef USART1_Transmit_DMA(const uint8_t *pData, uint16_t Size)
{
return HAL_UART_Transmit_DMA(&huart1, pData, Size);
}