1 UART通信配置步骤
串口初始化 HAL_UART_Init()
串口底层初始化 HAL_UART_MspInit()
开启串口异步接收中断 HAL_UART_Receive_IT()
设置优先级使能中断 HAL_NVIC_EnableIRQ(); HAL_NVIC_SetPriority()
编写中断服务函数 HAL_UART_IRQHandler()
串口数据发送 HAL_UART_Transmit()
HAL_StatusTypeDef 表示函数调用的返回状态
typedef enum
{
HAL_OK = 0x00U, //函数执行成功
HAL_ERROR = 0x01U, //函数执行过程中出现错误
HAL_BUSY = 0x02U, //函数正在执行中
HAL_TIMEOUT = 0x03U //函数执行超时
} HAL_StatusTypeDef;
1.1 HAL_UART_Init()
函数定义 HAL_StatusTypeDef HAL_UART_Init (UART_HandleTypeDef *huart)
函数描述 根据UART_InitTypeDef中指定的参数初始化UART模式,并创建关联句柄。
参数 huart:指向UART_HandleTypeDef结构体的指针,该结构体包含指定UART
模块的配置信息。
返回值 HAL status
UART_HandleTypeDef g_uart1_handle; //创建UART句柄
//UART 初始化设置
g_uart1_handle.Instance = USART1; //串行通信接口
g_uart1_handle.Init.BaudRate = 115200; //波特率
g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B; //字长为8位数据格式
g_uart1_handle.Init.StopBits = UART_STOPBITS_1; //一个停止位
g_uart1_handle.Init.Parity = UART_PARITY_NONE; //无奇偶校验位
g_uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; //无硬件流控
g_uart1_handle.Init.Mode = UART_MODE_TX_RX; //收发模式
HAL_UART_Init(&g_uart1_handle); //HAL_UART_Init()会使能UART1
1.2 HAL_UART_MspInit()
函数定义 void HAL_UART_MspInit (UART_HandleTypeDef * huart)
函数描述 UART MSP 初始化
参数 huart:指向UART_HandleTypeDef结构体的指针,该结构体包含指定UART
模块的配置信息。
串口回调函数,被HAL_UART_Init()自动调用,弱定义需要重写
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef gpio_init_struct;
if (huart->Instance == USART_UX) /* 如果是串口1,进行串口1 MSP初始化 */
{
/* 使能USART1和对应IO时钟 */
__HAL_RCC_GPIOA_CLK_ENABLE(); /* 使能串口TX脚时钟 */
__HAL_RCC_GPIOA_CLK_ENABLE(); /* 使能串口RX脚时钟 */
__HAL_RCC_USART1_CLK_ENABLE(); /* 使能串口时钟 */
/* 初始化IO */
gpio_init_struct.Pin = GPIO_PIN_9; /* 串口发送引脚号 */
gpio_init_struct.Mode = GPIO_MODE_AF_PP; /* 复用推挽输出 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* IO速度设置为高速 */
HAL_GPIO_Init(GPIOA, &gpio_init_struct);
gpio_init_struct.Pin = GPIO_PIN_10; /* 串口RX脚 模式设置 */
gpio_init_struct.Mode = GPIO_MODE_AF_INPUT; /* 串口RX脚 必须设置成输入模式 */
HAL_GPIO_Init(GPIOA, &gpio_init_struct);
/* 使能USART1中断,设置优先级 */
HAL_NVIC_EnableIRQ(USART1_IRQn); /* 使能USART1中断通道 */
HAL_NVIC_SetPriority(USART1_IRQn, 3, 3); /* 组2,最低优先级:抢占优先级3,子优先级3 */
}
}
1.3 HAL_UART_Receive_IT()
函数定义 HAL_StatusTypeDef HAL_UART_Receive_IT (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size)
函数描述 以非阻塞模式接收一定数量的数据
参数 huart:指向UART_HandleTypeDef结构体的指针,该结构体包含指定UART
模块的配置信息。
pData:指向数据缓存区的指针
Size:要传输的数据量
返回值 HAL status
uint8_t g_rx_buffer[RXBUFFERSIZE];
/* 该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量 */
HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
1.4 HAL_UART_Transmit()
函数定义 HAL_StatusTypeDef HAL_UART_Transmit (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size, uint32_t Timeout)
函数描述 以阻塞模式发送一定量数据
参数 huart:指向UART_HandleTypeDef结构体的指针,该结构体包含指定UART
模块的配置信息。
pData:指向数据缓存区的指针
Size:要传输的数据量
Timeout:超时时间
返回值 HAL status
/* 接收缓冲, 最大USART_REC_LEN个字节. */
uint8_t g_usart_rx_buf[USART_REC_LEN];
HAL_UART_Transmit(&g_uart1_handle,(uint8_t*)g_usart_rx_buf, len, 1000);
1.5 HAL_UART_RxCpltCallback()
函数定义 void HAL_UART_RxCpltCallback (UART_HandleTypeDef * huart)
函数描述 Rx传输完成回调函数
参数 huart:指向UART_HandleTypeDef结构体的指针,该结构体包含指定UART
模块的配置信息。
当使用HAL库进行异步中断方式的UART接收操作时,当接收完成时会触发此事件
HAL库会自动调用 HAL_UART_RxCpltCallback
函数,你需要重写函数以便执行特定的操作
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART_UX) /* 如果是串口1 */
{
if ((g_usart_rx_sta & 0x8000) == 0) /* 接收未完成 */
{
if (g_usart_rx_sta & 0x4000) /* 接收到了0x0d(即回车键) */
{
if (g_rx_buffer[0] != 0x0a) /* 接收到的不是0x0a(即不是换行键) */
{
g_usart_rx_sta = 0; /* 接收错误,重新开始 */
}
else /* 接收到的是0x0a(即换行键) */
{
g_usart_rx_sta |= 0x8000; /* 接收完成了 */
}
}
else /* 还没收到0X0d(即回车键) */
{
if (g_rx_buffer[0] == 0x0d)
g_usart_rx_sta |= 0x4000;
else
{
g_usart_rx_buf[g_usart_rx_sta & 0X3FFF] = g_rx_buffer[0];
g_usart_rx_sta++;
if (g_usart_rx_sta > (USART_REC_LEN - 1))
{
g_usart_rx_sta = 0; /* 接收数据错误,重新开始接收 */
}
}
}
}
HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
}
}
参考资料:
1. Description of STM32F1xx HAL drivers.pdf
2.【【正点原子】手把手教你学STM32 HAL库开发全集【真人出镜】STM32入门教学视频教程 单片机 嵌入式】 https://www.bilibili.com/video/BV1bv4y1R7dp