• STM32H7 USART 时钟初始化


    使用芯片 STM32H750XB,板子使用的是 安富莱的 stm32-V7 开发板

    时钟配置

    整体功能把握

    USART 的时钟源可以来自于 usart_ker_ck 和 usart_pclk:
    在这里插入图片描述
    usart_ker_ck 和 usart_pclk 的来源由下图可知:
    在这里插入图片描述
    以 USART1 为例,我们需要控制 USART16SEL 来选择第一级输入的时钟源。然后再由 USART1EN 和 USART1LPEN 来控制第二级的输出。

    实际上,控制第二级的最多可有五个变量:PERxEN、PERxLPEN、PERxAMEN、CPU_state 和 D3_state。
    在这里插入图片描述
    PERxEN、PERxLPEN 和 PERxAMEN 是控制位用于控制时钟输出,CPU_state 是 CPU 的状态位,D3_state 是域的状态位,它们组合起来一起控制某个外设的时钟是否有效。

    还是以 USART1 为例,我们分析《STM32H750XB参考手册》中的内容:

    • RCC_APB2ENR 寄存器中有一个控制 USART1 的 PERxEN 位,被命名为 USART1EN在这里插入图片描述

    • RCC_APB2LPENR 寄存器中有一个控制 USART1 的 PERxLPEN 位,被命名为 USART1LPEN
      这里我们就能看出 RCC_APB2LPENR 和 RCC_APB2ENR 的区别了,前者控制着 CPU 在睡眠模式下,后者控制这个 USART1 外设是否使能。

    • PERxAMEN 这个控制变量对于 USART1 这个外设来说是没有的,其属于低功耗的外设使用,是位于 D3 域的外设才有。其功能和 RCC_APB2ENR、RCC_APB2LPENR 差不多,当 D3 处于 CStop 模式时,控制该外设是否正常工作。

    • 了解了上面三个控制位,CPU_state 和 D3_state 的作用就很明显了。

    第一级的时钟来源与配置可以参考

    使用 CubeMX 配置 RCC 时钟_Bin Watson的博客-CSDN博客

    实战配置

    有了上面的了解我们大致知道怎么配置一个 USART 外设的时钟了:

    1. (配置第一级输入的时钟源)我们需要根据使用的时钟配置 USARTxSEL,以 USART1 为例就是配置 USAT16SEL,选择使用的时钟;
    2. (配置第二级输入控制)设置 PERxLPEN 和 PERxAMEN 两个控制位,控制 USART 在何种情况下会休眠;
    3. 设置 PERxEN 启动 USART;
    static void InitHardUart(void)
    {
    	GPIO_InitTypeDef  GPIO_InitStruct;
    	RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
    	
    	/* 
           下面这个配置可以注释掉,预留下来是为了方便以后选择其它时钟使用 
           默认情况下,USART1和USART6选择的PCLK2,时钟100MHz。
           USART2,USART3,UART4,UART5,UART6,UART7和UART8选择的时钟是PLCK1,时钟100MHz。
        */
    	RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART16;			/* 第一级配置 */
    	RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2; /* 第二级配置 */
    	HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
        
    #if UART1_FIFO_EN == 1		/* 串口1 */
    	/* 使能 GPIO TX/RX 时钟 */
    	USART1_TX_GPIO_CLK_ENABLE();
    	USART1_RX_GPIO_CLK_ENABLE();
    	
    	/* 使能 USARTx 时钟 */
    	USART1_CLK_ENABLE();	/* 启动 USART1 */
        ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    如上,我们设置 USAT16SEL 让其使用 D2PCLK2 作为输入时钟。没有设置 PERxLPEN 则说明使用默认的跟随 CPU 休眠。

    第 21 行 USART1_CLK_ENABLE() 设置了 PERxEN 位:

    #define USART1_CLK_ENABLE()              __HAL_RCC_USART1_CLK_ENABLE()
    
    #define __HAL_RCC_USART1_CLK_ENABLE()   do { \
                                            	__IO uint32_t tmpreg; \
                                            	SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\
                                            	/* Delay after an RCC peripheral clock enabling */ \
                                            	tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\
                                            	UNUSED(tmpreg); \
                                           } while(0)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    USART 发送与接收的实现可以参考 使用RS485芯片进行串口通讯 这篇文章,大体上是实现是相同的,不同的点在于不通过 RS485 进行收发的话,我们只需要直接控制 USART 的收发,而不需要使用回调来控制 RS485 的工作模式。

  • 相关阅读:
    基于量子计算的md5密码哈希破解方法
    layui--table里使用switch
    防火墙的相关知识
    Spring Boot 开发 -- swagger3.0 集成
    RV1126编译ROS Kinetic环境
    基于PYQT5的截图翻译工具
    springboot请求映射原理
    vscode中git的使用,以及与webstorm中git的使用对比
    FPGA高端项目:图像采集+GTX+UDP架构,高速接口以太网视频传输,提供2套工程源码加QT上位机源码和技术支持
    图片加水印怎么加?这篇文章告诉你
  • 原文地址:https://blog.csdn.net/Bin_Watson/article/details/127609130