• stm32 笔记 UART读取及HAL库应用


     基本流程图

     由此图可知:
    采用HAL库,中断方式接收串口,只有当RxXferCount == 0 时,也就是调用这个函数,接收指定量的数据大小完成时,才会调用回调函数HAL_UART_RxCpltCallback()。

    而且,RxXferCount == 0 后,也会使得中断退出,此时需要从新设置 HAL_UART_Receive_IT() 开启中断。

    这里还需要注意下面两个函数的区别,HAL_UART_Receive_IT()HAL_UART_Receive()
    分别为为非阻塞模式下接受数据,和阻塞模式下接受数据。

    初始化 UART

    1. void uart_init()
    2. {
    3. UART_HandleTypeDef usart1_handler;
    4. //UART 初始化设置
    5. usart1_handler.Instance=USART1; //USART1
    6. usart1_handler.Init.BaudRate=115200; //波特率
    7. usart1_handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
    8. usart1_handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
    9. usart1_handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
    10. usart1_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
    11. usart1_handler.Init.Mode=UART_MODE_TX_RX; //收发模式
    12. HAL_UART_Init(&usart1_handler); //HAL_UART_Init()会使能UART1
    13. }

     无需解释,只是 UART 的初始配置。

    UART1 端口配置初始化

    1. void HAL_UART_MspInit(UART_HandleTypeDef *huart)
    2. {
    3. //GPIO端口设置
    4. GPIO_InitTypeDef GPIO_Initure;
    5. if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
    6. {
    7. __HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
    8. __HAL_RCC_USART1_CLK_ENABLE(); //使能USART1时钟
    9. GPIO_Initure.Pin=GPIO_PIN_9; //PA9
    10. GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
    11. GPIO_Initure.Pull=GPIO_PULLUP; //上拉
    12. GPIO_Initure.Speed=GPIO_SPEED_FAST; //高速
    13. GPIO_Initure.Alternate=GPIO_AF7_USART1; //复用为USART1
    14. HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA9
    15. GPIO_Initure.Pin=GPIO_PIN_10; //PA10
    16. HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA10
    17. HAL_NVIC_SetPriority(USART1_IRQn,3,3); //设置中断优先级
    18. HAL_NVIC_EnableIRQ(USART1_IRQn); //使能中断
    19. }
    20. }

     上一段代码最后一行 HAL_UART_Init() 会自动调用这个端口初始化函数。因为 UART1 依赖于PA9 和 PA10 所以需要初始化这两个 GPIO 的配置,在最后两行中,为UART1 设置了中断优先级并使能。

    中断响应函数

    void  USART1_IRQHandler (void) 函数是串口1的中断响应函数,当串口1 发生了相应的中断后,就会跳到该函数执行。

    1. void USART1_IRQHandler(void){
    2. HAL_UART_IRQHandler(&usart1_handler);
    3. HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata)); //开启中断
    4. }

    值得注意的是,每次相应中断后,就会关闭之后的相应。

    需要调用 HAL_UART_Receive_IT() 从新注册这个相应中断。

    中断相应回调函数

    当 huart->RxXferCount 等于0时,HAL 就会帮我们调用 HAL_UART_RxCpltCallback 此函数才是真正的实现逻辑的地方。在下列函数中,会在读缓存区中取一个字符,并且通过串口回传给电脑。

    1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
    2. u8 rec;
    3. if(huart->Instance == USART1){
    4. rec = *((huart->pRxBuffPtr)-1);
    5. HAL_UART_Transmit(&usart1_handler,&rec,1,1000);
    6. }
    7. }

    代码与执行结果

    1. #include "sys.h"
    2. #include "delay.h"
    3. //初始化IO 串口1
    4. //bound:波特率
    5. UART_HandleTypeDef usart1_handler;
    6. u8 rdata[1];
    7. void uart_init()
    8. {
    9. //UART 初始化设置
    10. usart1_handler.Instance=USART1; //USART1
    11. usart1_handler.Init.BaudRate=115200; //波特率
    12. usart1_handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
    13. usart1_handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
    14. usart1_handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
    15. usart1_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
    16. usart1_handler.Init.Mode=UART_MODE_TX_RX; //收发模式
    17. HAL_UART_Init(&usart1_handler); //HAL_UART_Init()会使能UART1
    18. }
    19. void HAL_UART_MspInit(UART_HandleTypeDef *huart)
    20. {
    21. //GPIO端口设置
    22. GPIO_InitTypeDef GPIO_Initure;
    23. if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
    24. {
    25. __HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
    26. __HAL_RCC_USART1_CLK_ENABLE(); //使能USART1时钟
    27. GPIO_Initure.Pin=GPIO_PIN_9; //PA9
    28. GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
    29. GPIO_Initure.Pull=GPIO_PULLUP; //上拉
    30. GPIO_Initure.Speed=GPIO_SPEED_FAST; //高速
    31. GPIO_Initure.Alternate=GPIO_AF7_USART1; //复用为USART1
    32. HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA9
    33. GPIO_Initure.Pin=GPIO_PIN_10; //PA10
    34. HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA10
    35. HAL_NVIC_SetPriority(USART1_IRQn,3,3); //设置中断优先级
    36. HAL_NVIC_EnableIRQ(USART1_IRQn); //使能中断
    37. }
    38. }
    39. void USART1_IRQHandler(void){
    40. HAL_UART_IRQHandler(&usart1_handler);
    41. HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata)); //开启中断
    42. }
    43. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ //huart->RxXferCount 等于0 也就是读满rdata就执行这个回调函数
    44. u8 rec;
    45. if(huart->Instance == USART1){
    46. rec = *((huart->pRxBuffPtr)-1);
    47. HAL_UART_Transmit(&usart1_handler,&rec,1,1000);
    48. }
    49. }
    50. int main(void)
    51. {
    52. HAL_Init(); //初始化HAL库
    53. Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
    54. delay_init(180);
    55. uart_init();
    56. HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata)); //开启中断
    57. while(1){ //必须卡在死循环中,程序执行完毕就不能相应中断了
    58. delay_ms(3000);
    59. }
    60. }

  • 相关阅读:
    uniApp实现热更新
    java计算机毕业设计新能源汽车租赁管理系统源程序+mysql+系统+lw文档+远程调试
    事务管理
    JSON字符串之JS中JSON.parse()
    2-95 基于matlab的模板定位
    idea中使用git【图文详解】
    《解构领域驱动设计》读书笔记
    java基于springboot的学生公寓管理系统
    SwiftUI Swift内功之Swift 5.8 适合Early Adopters
    【零基础学QT】第二章 工程文件内容分析
  • 原文地址:https://blog.csdn.net/nullccc/article/details/128090499