串口数据收发(中断)初始化步骤:
第一步:调用HAL_UART_Init函数初始化串口参数,函数传入结构参数如下:
typedef struct
{
USART_TypeDef *Instance; // 传入串口的基地址
UART_InitTypeDef Init; // 传入串口初始化参数,波特率、奇偶校验等
uint8_t *pTxBuffPtr; // 传入串口发送缓冲区地址
uint16_t TxXferSize; // 传入串口发送缓冲区大小
__IO uint16_t TxXferCount; // 传入串口发送缓冲区数据个数
uint8_t *pRxBuffPtr; // 传入串口发送缓冲区地址
uint16_t RxXferSize; // 传入串口接收缓冲区大小
__IO uint16_t RxXferCount; // 传入串口接收缓冲区数据个数
DMA_HandleTypeDef *hdmatx; // 当串口使用DMA传输时,传入发送引脚TX的DMA初始化配置参数
DMA_HandleTypeDef *hdmarx; // 当串口使用DMA传输时,传入接收引脚RX的DMA初始化配置参数
HAL_LockTypeDef Lock; // 锁定对象
__IO HAL_UART_StateTypeDef gState; // 当前串口Tx引脚状态信息
__IO HAL_UART_StateTypeDef RxState; // 当前串口Rx引脚状态信息
__IO uint32_t ErrorCode; // 串口错误代码
}UART_HandleTypeDef;
第二步:重定义HAL_UART_MspInit函数初始化,初始化串口硬件参数,并配置中断优先级、使能中断。
第三步:实现数据收发。
HAL库中,供串口中断数据收发的函数分别如下:
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
函数实现功能如下:
①:函数中传入3个参数,分别为串口初始化结构体参数UART_HandleTypeDef、接收数据缓冲区地址pData、接收数据缓冲区宽度Size。
②:函数首先判断Rx进程是否处于正常运行状态,如果不是则退出函数,返回错误。
③:初始化串口结构体UART_HandleTypeDef,将函数传入参数,分别赋值给结构体变量,并初始化错误代码变量“Errorcode”和Rx进程的状态。
④:使能串口错误中断(包括:帧错误、噪声错误、溢出错误)
⑤:使能串口校验错误和接收寄存器非空中断。
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
/* Check that a Rx process is not already ongoing */
if(huart->RxState == HAL_UART_STATE_READY)
{
if((pData == NULL ) || (Size == 0))
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(huart);
huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;
huart->RxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX;
/* Process Unlocked */
__HAL_UNLOCK(huart);
/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* Enable the UART Parity Error and Data Register not empty Interrupts */
SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
函数实现功能如下:
①:函数中传入3个参数,分别为串口初始化结构体参数UART_HandleTypeDef、发送数据缓冲区地址pData、发送数据缓冲区宽度Size。
②:函数首先判断Tx进程是否处于正常运行状态,如果不是则退出函数,返回错误。
③:初始化串口结构体UART_HandleTypeDef,将函数传入参数,分别赋值给结构体变量,并初始化错误代码变量“Errorcode”和Tx进程的状态。
④:使能串口发送寄存器为空中断。
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
/* Check that a Tx process is not already ongoing */
if(huart->gState == HAL_UART_STATE_READY)
{
if((pData == NULL ) || (Size == 0))
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(huart);
huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;
/* Process Unlocked */
__HAL_UNLOCK(huart);
/* Enable the UART Transmit data register empty Interrupt */
SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
串口中断数据收发bsp_uart.c完整程序如下:
#include "bsp_uart.h"
UART_HandleTypeDef UART1_Handler; //UART 句柄
uint8_t buffer; // 串口接收数据
// 初始化串口函数
void UART_Init(void)
{
UART1_Handler.Instance = USART1; // 串口1
UART1_Handler.Init.BaudRate = 115200; // 波特率
UART1_Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 无硬件流控
UART1_Handler.Init.Mode = UART_MODE_TX_RX; // 收发模式
UART1_Handler.Init.Parity = UART_PARITY_NONE; // 无奇偶校验
UART1_Handler.Init.StopBits = UART_STOPBITS_1; // 一个停止位
UART1_Handler.Init.WordLength = UART_WORDLENGTH_8B; // 字长为8位格式
HAL_UART_Init(&UART1_Handler); // 初始化串口
// 开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲区以及接收缓冲区接收最大数据量
HAL_UART_Receive_IT(&UART1_Handler, &buffer, RXBUFFERSIZE);
}
// 初始化低级硬件
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIO引脚
__HAL_RCC_USART1_CLK_ENABLE(); // 使能串口
GPIO_Initure.Mode = GPIO_MODE_AF_PP; // 复用推挽模式
GPIO_Initure.Pin = GPIO_PIN_9|GPIO_PIN_10; // PA9、PA10
GPIO_Initure.Pull = GPIO_PULLUP; //上拉
GPIO_Initure.Speed = GPIO_SPEED_FAST; //高速
GPIO_Initure.Alternate = GPIO_AF7_USART1; // 复用为 USART1
HAL_GPIO_Init(GPIOA, &GPIO_Initure); // 初始化 PA9、PA10
HAL_NVIC_SetPriority(USART1_IRQn, 2, 1); // 设置串口中断优先级
HAL_NVIC_EnableIRQ(USART1_IRQn); // 使能串口中断
}
}
// 串口中断服务函数
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&UART1_Handler); // 清空中断标志,取消中断使能,并间接调用回调函数
}
// 串口接收回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UART_Transmit(&buffer, RXBUFFERSIZE); // 将接收到的数据发送出去
HAL_UART_Receive_IT(&UART1_Handler, &buffer, 1); // 由于接收一次数据,中断使能会被清除,所以这行代码必须添加
}
void UART_Transmit(uint8_t *pData, uint16_t Size)
{
HAL_UART_Transmit(&UART1_Handler, pData, Size, HAL_MAX_DELAY);
}
void UART_Receive(uint8_t *pData, uint16_t Size)
{
HAL_UART_Receive(&UART1_Handler, pData, Size, HAL_MAX_DELAY);
}