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 */
    ...
}

如上,我们设置 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)

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值