stm32正点原子、野火笔记-时钟

目录

一、stm32F103时钟树

1、stm32F103时钟系统图:

1.1stm32五个时钟源

1.2A~E讲解:

2、stm32F103时钟系统配置-HAL库

2.1HAL 库的 SystemInit 函数-代码略

2.2在工程 SYSTEM 分组下面定义的 sys.c文件中的时钟初始化函数 Stm32_Clock_Init:

2.3结构体 RCC_OscInitTypeDef 的定义:

3、STM32F1 时钟使能和配置

4、端口复用和重映射

4.1端口复用

 4.2串口1复用功能的一般步骤


一、stm32F103时钟树

1、stm32F103时钟系统图:

1.1stm32五个时钟源

STM32 中,有五个时钟源,为 HSI HSE LSI LSE PLL 。从时钟频率来分可以分为
高速时钟源和低速时钟源,HIS、HSE 以及 PLL 是高速时钟,LSI 和 LSE 是低速时钟。
从来源可分为外部时钟源和内部时钟源,外部时钟源就是从外部通过接晶振的方式获取时
钟源,其中 HSE LSE 是外部时钟源,其他的是内部时钟源。
标记:H-high S-speed I-inter E-external L-low 
HSI 是高速内部时钟, RC 振荡器,频率为 8MHz
HSE 是高速外部时钟,可接石英 / 陶瓷谐振器,或者接外部时钟源,频率范围 4MHz~16MHz
正点原子的开发板接的是 8M 的晶振。
LSI 是低速内部时钟, RC 振荡器,频率为 40kHz 。独立看门狗的时钟源只能是 LSI ,同
LSI 还可以作为 RTC 的时钟源。
LSE 是低速外部时钟,接频率为 32.768kHz 的石英晶体。这个主要是 RTC 的时钟源。
PLL 为锁相环倍频输出,其时钟输入源可选择为 HSI/2 HSE 或者 HSE/2 。倍频可选择为
2~16 倍,但是其输出频率最大不得超过 72MHz

1.2A~E讲解:

A. MCO 是 STM32 的一个时钟输出 IO(PA8) ,它可以选择一个时钟信号输出,可以
选择为 PLL 输出的 2 分频、 HSI HSE 、或者系统时钟。这个时钟可以用来给外
部其他系统提供时钟源。
B. 这里是 RTC 时钟源,从图上可以看出, RTC 的时钟源可以选择 LSI LSE ,以及
HSE 128 分频。
C. 从图中可以看出 C USB 的时钟是来自 PLL 时钟源。 STM32 中有一个全速功能
USB 模块,其串行接口引擎需要一个频率为 48MHz 的时钟源。该时钟源只能
PLL 输出端获取,可以选择为 1.5 分频或者 1 分频,也就是,当需要使用 USB
模块时, PLL 必须使能,并且时钟频率配置为 48MHz 72MHz
D. D 处就是 STM32 的系统时钟 SYSCLK ,它是供 STM32 中绝大部分部件工作的时
钟源。系统时钟可选择为 PLL 输出、 HSI 或者 HSE 。系统时钟最大频率为 72MHz
当然你也可以超频,不过一般情况为了系统稳定性是没有必要冒风险去超频的。
E. 这里的 E 处是指其他所有外设了。从时钟图上可以看出,其他所有外设的时钟最
终来源都是 SYSCLK SYSCLK 通过 AHB 分频器分频后送给各模块使用。这些模块包
括:
①、 AHB 总线、内核、内存和 DMA 使用的 HCLK 时钟。
②、通过 8 分频后送给 Cortex 的系统定时器时钟,也就是 systick 了。
③、直接送给 Cortex 的空闲运行时钟 FCLK
④、送给 APB1 分频器。 APB1 分频器输出一路供 APB1 外设使用 (PCLK1 ,最大
频率 36MHz) ,另一路送给定时器 (Timer)2 3 4 倍频器使用。
⑤、送给 APB2 分频器。 APB2 分频器分频输出一路供 APB2 外设使用 (PCLK2
最大频率 72MHz) ,另一路送给定时器 (Timer)1 倍频器使用。
需要理解的是 APB1 APB2 的区别, APB1 上面连接的是低速外设,包括电源接口、
备份接口、 CAN USB I2C1 I2C2 UART2 UART3 等等, APB2 上面连接的是高速外设包
UART1 SPI1 Timer1 ADC1 ADC2 、所有普通 IO (PA~PE) 、第二功能 IO 口等。居宁
老师的《稀里糊涂玩 STM32 》资料里面教大家的记忆方法是 2>1 APB2 下面所挂的外设的时钟要比 APB1 的高。
简要概括:可以使用三种不同的时钟源来驱动系统时钟 (SYSCLK)
● HSI 振荡器时钟
● HSE 振荡器时钟
● 主 PLL (PLL) 时钟
器件具有以下两个次级时钟源:
● 32 kHz 低速内部 RC (LSI RC),该 RC 用于驱动独立看门狗,也可选择提供给 RTC 用于停机/待机模式下的自动唤醒。
● 32.768 kHz 低速外部晶振(LSE 晶振),用于驱动 RTC 时钟 (RTCCLK) 。对于每个时钟源来说,在未使用时都可单独打开或者关闭,以降低功耗。

2、stm32F103时钟系统配置-HAL库

2.1HAL 库的 SystemInit 函数-代码略

SystemInit 主要做了如下三个方面工作:
1 ) 复位 RCC 时钟配置为默认复位值(默认开始了 HIS
2 ) 外部存储器配置
3 ) 中断向量表地址配置
HAL 库的 SystemInit 函数并没有像标准库的 SystemInit 函数一样进行时钟的初始化配置。 HAL
库的 SystemInit 函数除了打开 HSI 之外,没有任何时钟相关配置,所以使用 HAL 库我们必须编
写自己的时钟配置函数。

2.2在工程 SYSTEM 分组下面定义的 sys.c文件中的时钟初始化函数 Stm32_Clock_Init:

作用是进行时钟系统配置,除了配置 PLL 相关参数确定 SYSCLK 值之外,还配置了 AHB,APB1 APB2 的分频系数,也就是确定了 HCLK,PCLK1 和 PCLK2 的时钟值。

//时钟系统配置函数
//PLL:选择的倍频数,RCC_PLL_MUL2~RCC_PLL_MUL16
//返回值:0,成功;1,失败
void Stm32_Clock_Init(u32 PLL)
{
 HAL_StatusTypeDef ret = HAL_OK;
 RCC_OscInitTypeDef RCC_OscInitStructure; 
 RCC_ClkInitTypeDef RCC_ClkInitStructure;
 //的配置内容:
 RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_HSE; //时钟源为 HSE
 RCC_OscInitStructure.HSEState=RCC_HSE_ON; //打开 HSE
 RCC_OscInitStructure.HSEPredivValue=RCC_HSE_PREDIV_DIV1; //HSE 预分频
 RCC_OscInitStructure.PLL.PLLState=RCC_PLL_ON; //打开 PLL
 RCC_OscInitStructure.PLL.PLLSource=RCC_PLLSOURCE_HSE;
//PLL 时钟源选择 HSE
 RCC_OscInitStructure.PLL.PLLMUL=PLL; //主 PLL 倍频因子
 ret=HAL_RCC_OscConfig(&RCC_OscInitStructure);//初始化 

 if(ret!=HAL_OK) while(1);

 //选中 PLL 作为系统时钟源并且配置 HCLK,PCLK1 和 PCLK2
 RCC_ClkInitStructure.ClockType=(RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|
                                 RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2);
//设置系统时钟时钟源为 PLL
 RCC_ClkInitStructure.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStructure.AHBCLKDivider=RCC_SYSCLK_DIV1; //AHB 分频系数为 1
 RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV2; //APB1 分频系数为 2
 RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV1; //APB2 分频系数为 1
 ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_2);
//同时设置 FLASH 延时周期为 2WS,也就是 3 个 CPU 周期。
 if(ret!=HAL_OK) while(1);
}
主函数中调用 Stm32_Clock_Init(RCC_PLL_MUL9) 时候设置的入口参数值,我们可以计算出,PLL 时钟为 PLLCLK=HSE*9 =8MHz*9=72MHz ,同时我们选择系统时钟源为 PLL , 所 以 系 统 时 钟 SYSCLK=72MHz AHB 分频系数为 1 ,故其频率为 HCLK=SYSCLK/1=72MHz。 APB1 分频系数为 2 ,故其频率为 PCLK1=HCLK/2=36MHz APB2 分频系数为 1 ,故其频率为 PCLK2=HCLK/1=72/1=72MHz 。最后我们总结一下通过调用函Stm32_Clock_Init(RCC_PLL_MUL9)之后的关键时钟频率值:
SYSCLK(系统时钟)                           =72MHz
PLL 主时钟                                        =72MHz
AHB 总线时钟( HCLK=SYSCLK/1 )  =72MHz
APB1 总线时钟( PCLK1=HCLK/2 ) =36MHz
APB2 总线时钟( PCLK2=HCLK/1 ) =72MHz

2.3结构体 RCC_OscInitTypeDef 的定义:

typedef struct
{
 uint32_t OscillatorType; //需要选择配置的振荡器类型 
 uint32_t HSEState; //HSE 状态 
 uint32_t HSEPredivValue; // Prediv1 值
 uint32_t LSEState; //LSE 状态 
 uint32_t HSIState; //HIS 状态
 uint32_t HSICalibrationValue; //HIS 校准值
 uint32_t LSIState; //LSI 状态 
 RCC_PLLInitTypeDef PLL; //PLL 配置
}RCC_OscInitTypeDef;
前面几个参数主要是用来选择配置的振荡器类型。比如我们要开启 HSE , 那么我们会设置 OscillatorType 的值为 RCC_OSCILLATORTYPE_HSE ,然后设置 HSEState 的值为 RCC_HSE_ON 开启 HSE。
成员变量是 PLL ,它是结构体 RCC_PLLInitTypeDef 类型。它的作用是配置 PLL 相关参数,我们来看看它的定义:
typedef struct
{
 uint32_t PLLState; //PLL 状态
 uint32_t PLLSource; //PLL 时钟源
 uint32_t PLLMUL; //PLL VCO 输入时钟的乘法因子
}RCC_PLLInitTypeDef;
该结构体主要用来设置 PLL 时钟源以及相关分频倍频参数。

3、STM32F1 时钟使能和配置

外设时钟使能在 HAL 库中都是通过宏定义标识符来实现的。首先,我们来看看 GPIOA 的外设时钟使能宏定义标识符:
#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \
 __IO uint32_t tmpreg; \
 SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);\
 tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);\
 UNUSED(tmpreg); \
 } while(0U))

//设置寄存器 RCC_APB2ENR 的相关位为 1,哪个位,是由宏定义标识RCC_APB2ENR_IOPAEN 的值决定.

#define RCC_APB2ENR_IOPAEN ((uint32_t)0x00000001)
//设置寄存器 RCC->APB2ENR 寄存器的位 2 1
APB2ENR 寄存器的位 2 描述如下:
位 2 IOPAEN:IO 端口 A 时钟使能
 由软件置 1 和清零
 0:禁止 IO 端口 A 时钟
 1:使能 IO 端口 A 时钟
使用方法为:
__HAL_RCC_GPIOA_CLK_ENABLE();//使能 GPIOA 时钟
几个常用使能外设时钟的宏定义标识符使用方法:
__HAL_RCC_DMA1_CLK_ENABLE();//使能 DMA1 时钟
__HAL_RCC_USART2_CLK_ENABLE();//使能串口 2 时钟
__HAL_RCC_TIM1_CLK_ENABLE();//使能 TIM1 时钟
几个常用的禁止外设时钟的宏定义标识符使用方法:
__HAL_RCC_DMA1_CLK_DISABLE();//禁止 DMA1 时钟
__HAL_RCC_USART2_CLK_DISABLE();//禁止串口 2 时钟
__HAL_RCC_TIM1_CLK_DISABLE();//禁止 TIM1 时钟

4、端口复用和重映射

4.1端口复用

比如说 STM32F103ZET6 有 5 个串口,我们可以查手册知道,串口 1 的引脚对应的 IO 为 PA9,PA10.PA9,PA10 默认功能是 GPIO,所以当 PA9,PA10 引脚作为串口 1 的 TX,RX 引脚使用的时候,那就是端口复用:

4.2串口1复用功能的一般步骤

以串口 1 为例来讲解配置 GPOPA.9,GPIOA.10 口为串口 1 复用功能的一般步骤:
1)先打开对应的 IO 时钟和复用功能外设时钟
——HAL_RCC_GPIOA_CLK_ENABLE(); //使能 GPIOA 时钟
__HAL_RCC_USART1_CLK_ENABLE(); //使能 USART1 时钟
__HAL_RCC_AFIO_CLK_ENABLE(); //使能辅助功能 IO 时钟

2)在 GIPOx_MODER 寄存器中将所需 IO(对于串口 1 是 PA9,PA10)配置为复用功能

3)对 IO 口的其他参数,例如上拉/下拉以及输出速度等进行配置。

上面三步,在我们 HAL 库中是通过 HAL_GPIO_Init 函数来实现的,参考代码如下:
GPIO_InitTypeDef GPIO_Initure;
GPIO_Initure.Pin=GPIO_PIN_9; //PA9
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化 PA9
通过上面的配置,PA9 复用为串口 1 的发送引脚。
  • 16
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值