• STM32 HAL库USART的接收数据方法实现


    目录

    概述

    1 使用STM32Cube生成项目

    1.1 软件版本信息

    1.2 配置串口相关参数

    1.3 生成工程

    2 问题描述

    3 解决问题

    3.1 修改代码

    3.2 编写新的回调函数

    4 测试


    概述

    本文主要介绍STM32 HAL库USART的接收数据方法实现,笔者使用的HAL库为STM32Cube_FW_F1_V1.8.5,使用的MCU为STM32F103RC6,使用STM32Cube生成和串口相关的代码,发现其并不能实现接收数据功能,本文写作的目的就是记录解决这个问题的方法。

    1 使用STM32Cube生成项目

    1.1 软件版本信息

    软件名称版本信息
    STM32CubeSTM32CubeMX 6.11
    STM32 HALSTM32Cube_FW_F1_V1.8.5

    1.2 配置串口相关参数

    1)工作模式

    选择串口1,使用异步传输数据模式

    2)配置串口相关参数

     3)串口的IO信息

    4) 使能串口接收中断

     

    1.3 生成工程

    配置完成参数,生成项目。

    2 问题描述

    配置完成项目后,编译项目,然后下载代码到板卡中。运行代码后,

    1)ORE被置位

    2)快速运行代码,但其并没有进入到串口中断中

    3)CR1寄存器中的参数值中的RXNEIE吗,没有被置位

    3 解决问题

    3.1 修改代码

    在usart.c文件中,在MX_USART1_UART_Init函数添加如下语句,其目的是打开USART1的接收中断:

      SET_BIT(huart1.Instance->CR1, USART_CR1_RXNEIE);

    Control register 1 (USART_CR1)

    Address offset: 0x0C
    Reset value: 0x0000

    Bit 5 RXNEIE: RXNE interrupt enable
    此位由软件设置和清除。

    0:中断被禁止

    1: 当USART_SR寄存器中的ORE=1或RxNE=1时,会产生USART中断
     

    3.2 编写新的回调函数

    此回调函数不是HAL库中提供的,而是需要程序员自己编写,其主要实现如下功能,该函数编写在usart.c文件中实现:

    1. uint8_t testbuff[32];
    2. uint8_t recCnt;
    3. void UART_RxCpltCallback(UART_HandleTypeDef *huart)
    4. {
    5. uint32_t isrflags = READ_REG(huart->Instance->SR);
    6. uint32_t cr1its = READ_REG(huart->Instance->CR1);
    7. if( huart->Instance==USART1 )
    8. {
    9. /* UART in mode Receiver -------------------------------------------------*/
    10. if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
    11. {
    12. testbuff[recCnt++] = huart->Instance->DR;
    13. if( recCnt>= 32)
    14. recCnt = 0;
    15. }
    16. SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE);
    17. CLEAR_BIT(huart->Instance->SR, USART_SR_ORE);
    18. }
    19. }

    Status register (USART_SR)
    Address offset: 0x00
    Reset value: 0x00C0

    Bit 3 ORE: Overrun error
    当移位寄存器中当前接收的字为准备在RXNE=1时被转移到RDR寄存器中。如果在USART_CR1寄存器中RXNEIE=1。它由软件序列清除(读取USART_SR寄存器,后面跟着对USART_DR寄存器的读取)。

    在stm32f1xx_it.c中的USART1_IRQHandler()函数中调用该回调函数

    源码如下:

    1. /**
    2. * @brief This function handles USART1 global interrupt.
    3. */
    4. void USART1_IRQHandler(void)
    5. {
    6. /* USER CODE BEGIN USART1_IRQn 0 */
    7. /* USER CODE END USART1_IRQn 0 */
    8. UART_RxCpltCallback( &huart1 );
    9. HAL_UART_IRQHandler(&huart1);
    10. /* USER CODE BEGIN USART1_IRQn 1 */
    11. /* USER CODE END USART1_IRQn 1 */
    12. }

    4 测试

    1)完成以上代码之后,就可以编译项目,然后下载到板卡中测试该功能。在USART1_IRQHandler函数中添加断点。

     2)使用串口调试助手发送数据至板卡

    3)查看结果

     使用ST-Link调试,debug的数据

    CR1寄存器中的参数值:RXNEIE=1

     SR寄存器中的参数值,RXNE和ORE已经被清除

  • 相关阅读:
    Linux内存从0到1学习笔记(9.10 内存优化调试之panic_on_oom介绍 --- 更新中
    Cholesterol胆固醇丨艾美捷Cholesterol胆固醇化学性质
    微信小程序开发:接入阿里云人像动漫化api接口
    【ELK】日志分析系统概述及部署(ELFK部署实验)
    C++ 函数对象(Function Object)是什么?C++重载小括号()是什么作用?
    openGauss学习笔记-60 openGauss 数据库管理-逻辑存储结构
    TiDB 6.0 新特性
    简单工厂模式
    Kafka的消息存储机制
    IO流:字符输入流Reader的超详细用法及底层原理
  • 原文地址:https://blog.csdn.net/mftang/article/details/139236867