基本流程图
由此图可知:
采用HAL库,中断方式接收串口,只有当RxXferCount == 0 时,也就是调用这个函数,接收指定量的数据大小完成时,才会调用回调函数HAL_UART_RxCpltCallback()。
而且,RxXferCount == 0 后,也会使得中断退出,此时需要从新设置 HAL_UART_Receive_IT() 开启中断。
这里还需要注意下面两个函数的区别,HAL_UART_Receive_IT()HAL_UART_Receive()
分别为为非阻塞模式下接受数据,和阻塞模式下接受数据。
初始化 UART
void uart_init()
{
UART_HandleTypeDef usart1_handler;
//UART 初始化设置
usart1_handler.Instance=USART1; //USART1
usart1_handler.Init.BaudRate=115200; //波特率
usart1_handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
usart1_handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
usart1_handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
usart1_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
usart1_handler.Init.Mode=UART_MODE_TX_RX; //收发模式
HAL_UART_Init(&usart1_handler); //HAL_UART_Init()会使能UART1
}
无需解释,只是 UART 的初始配置。
UART1 端口配置初始化
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_Initure;
if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
{
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
__HAL_RCC_USART1_CLK_ENABLE(); //使能USART1时钟
GPIO_Initure.Pin=GPIO_PIN_9; //PA9
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
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
GPIO_Initure.Pin=GPIO_PIN_10; //PA10
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA10
HAL_NVIC_SetPriority(USART1_IRQn,3,3); //设置中断优先级
HAL_NVIC_EnableIRQ(USART1_IRQn); //使能中断
}
}
上一段代码最后一行 HAL_UART_Init() 会自动调用这个端口初始化函数。因为 UART1 依赖于PA9 和 PA10 所以需要初始化这两个 GPIO 的配置,在最后两行中,为UART1 设置了中断优先级并使能。
中断响应函数
void USART1_IRQHandler (void) 函数是串口1的中断响应函数,当串口1 发生了相应的中断后,就会跳到该函数执行。
void USART1_IRQHandler(void){
HAL_UART_IRQHandler(&usart1_handler);
HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata)); //开启中断
}
值得注意的是,每次相应中断后,就会关闭之后的相应。
需要调用 HAL_UART_Receive_IT() 从新注册这个相应中断。
中断相应回调函数
当 huart->RxXferCount 等于0时,HAL 就会帮我们调用 HAL_UART_RxCpltCallback 此函数才是真正的实现逻辑的地方。在下列函数中,会在读缓存区中取一个字符,并且通过串口回传给电脑。文章来源:https://www.toymoban.com/news/detail-615239.html
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
u8 rec;
if(huart->Instance == USART1){
rec = *((huart->pRxBuffPtr)-1);
HAL_UART_Transmit(&usart1_handler,&rec,1,1000);
}
}
代码与执行结果
#include "sys.h"
#include "delay.h"
//初始化IO 串口1
//bound:波特率
UART_HandleTypeDef usart1_handler;
u8 rdata[1];
void uart_init()
{
//UART 初始化设置
usart1_handler.Instance=USART1; //USART1
usart1_handler.Init.BaudRate=115200; //波特率
usart1_handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
usart1_handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
usart1_handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
usart1_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
usart1_handler.Init.Mode=UART_MODE_TX_RX; //收发模式
HAL_UART_Init(&usart1_handler); //HAL_UART_Init()会使能UART1
}
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_Initure;
if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
{
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
__HAL_RCC_USART1_CLK_ENABLE(); //使能USART1时钟
GPIO_Initure.Pin=GPIO_PIN_9; //PA9
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
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
GPIO_Initure.Pin=GPIO_PIN_10; //PA10
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA10
HAL_NVIC_SetPriority(USART1_IRQn,3,3); //设置中断优先级
HAL_NVIC_EnableIRQ(USART1_IRQn); //使能中断
}
}
void USART1_IRQHandler(void){
HAL_UART_IRQHandler(&usart1_handler);
HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata)); //开启中断
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ //huart->RxXferCount 等于0 也就是读满rdata就执行这个回调函数
u8 rec;
if(huart->Instance == USART1){
rec = *((huart->pRxBuffPtr)-1);
HAL_UART_Transmit(&usart1_handler,&rec,1,1000);
}
}
int main(void)
{
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
delay_init(180);
uart_init();
HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata)); //开启中断
while(1){ //必须卡在死循环中,程序执行完毕就不能相应中断了
delay_ms(3000);
}
}
文章来源地址https://www.toymoban.com/news/detail-615239.html
到了这里,关于stm32 笔记 UART读取及HAL库应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!