
上次实验,我们学习了 STM32 内部系统滴答定时器,该滴答定时器产生的延时非常精确。在本次实验中,我们将自定义 RCC 系统时钟,通过改变其倍频与分频实现延时时间变化,实现 LED 灯闪烁效果。通过本次实验,你将了解 RCC 系统时钟的使用。本次实验的目标: 1、了解 STM32 的系统构架。 2、了解 STM32 的时钟构架。 3、了解 RCC 时钟的配置步骤。 STM32 的系统构架 STM32 的时钟比较复杂,它可以选择多种时钟源,也可以选择不一样的时钟频率,而且在系统总线上面,每条系统的时钟选择都是有差异的。所以想要清楚的了解 STM32 的时钟分配,我们先来了解一下 STM32 的系统构架是什么样的。 从图中我们知道,RCC 时钟输出时钟出来,然后经过 AHB 系统总线,分别分配给其他外设时钟,而不一样的外设,是先挂在不一样的桥上的。比如: ADC1、ADC2、 SPI1、GPIO 等都是挂在 APB2 上面,而有些是挂在 APB1 上面,所以,虽然它们都是从 RCC 获取的时钟,但是它们的频率有时候是不一样的。 ![]() STM32 的时钟树 STM32 单片机上电之后,系统默认是用的时钟是单片机内部的高速晶振时钟,而这个晶振容易受到温度的影响,所以晶振跳动的时候不是有一定的影响,所以一般开发使用的时候都是使用外部晶振,而且单片机刚启动的时候,它的时钟频率是 8MHZ,而 STM32 时钟的最高频率是 72MHZ,所以单片机一般开机之后运行的程序是切换时钟来源,并设置时钟频率。其实在使用库函数的时候,其实在库函数启动文件里面,是帮助我们把时钟频率设置到 72MHZ 了。 库函数调用系统时钟该成72M #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (definedSTM32F10X_HD_VL) /* #define SYSCLK_FREQ_HSE HSE_VALUE */ #define SYSCLK_FREQ_24MHz 24000000 #else #define SYSCLK_FREQ_72MHz 72000000 然后在下面的程序中,根据这个 SYSCLK_FREQ_72MHz 定义,它默认设置成72MHZ 接下来我们来看一下 RCC 时钟树 ![]() 从时钟树图我们可以看出,STM32 的时钟一共有可以有 4 个晶振源: 1) 内部自带的高速时钟:HIS。单片机启动之后默认使用的时钟来源。 2) 外部高速时钟:HSE。大多数时钟时钟的是 8MHZ 的晶振。 3) 外部低速时钟:LSE。主要用来给单片机内部的 RTC 提供时钟。 4) 内部的低速时钟:LSI。主要用来给单片机内部的 RTC 和看门狗提供时钟。 而 STM32 的系统时钟源,有 3 个时钟来源: 1) 直接来自内部的高速时钟 HIS。 2) 直接来自外部的高速时钟 HSE。 3) 将 HIS 或者 HSE 进行处理,倍频之后的 PLL 时钟。 STM32 配置 RCC 时钟的过程 1) 复位 RCC 时钟。 2) 打开 HSE 外部高速时钟。 3) 检测 HSE 外部高速时钟是否开启成功。 4) 设置 FLASH 的读写。 5) 设置 AHB 总线的分频,还有 APB1 和 APB2 的分频。注意,AHB 和 APB2 最 大频率是 72MHZ,APB1 的最大频率是才 36MHZ。 6) 设置 HSE 外部高速时钟作为 PLL 时钟的时钟输入 7) 设置 PLL 时钟的倍频的倍数。 8) 打开 PLL 时钟的使能。 9) 等待 PLL 时钟开启成功。 10) 将系统时钟源设置为 PLL 时钟。 11) 等待时钟源切换成功 。 RCC相关库函数介绍 1.RCC_DeInit() 复位函数是将 RCC 时钟复位为内部高速时钟作为输入,让我们能够进行时钟设置操作。2.RCC_HSEConfig() 函数 设置 HSE 外部高速时钟的函数,可以开启、关闭、和旁路 3.RCC_WaitForHSEStartUp() 函数 4 .RCC_HCLKConfig() 函数 5 .RCC_PCLK2Config() 6 .RCC_PCLK1Config() 函数 8 、RCC_PLLCmd() 函数 9 、RCC_GetFlagStatus() 函数 这个函数可以用来获取各种状态标志,以检测设置是否成功。 10 、 RCC_SYSCLKConfig() 函数 11 、 RCC_GetSYSCLKSource() RCC 时钟设置函数 void RCC_HSE_Configuration() //自定义系统时间(可以修改时钟) { RCC_DeInit(); //将外设 RCC 寄存器重设为缺省值 RCC_HSEConfig(RCC_HSE_ON);//设置外部高速晶振(HSE) if(RCC_WaitForHSEStartUp()==SUCCESS) //等待 HSE 起振 { RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置 AHB 时钟(HCLK) RCC_PCLK1Config(RCC_HCLK_Div2);//设置低速 AHB 时钟(PCLK1) RCC_PCLK2Config(RCC_HCLK_Div1);//设置高速 AHB 时钟(PCLK2) RCC_PLLConfig(RCC_PLLSource_HSE_Div2,RCC_PLLMul_9);//设置 PLL 时钟源及倍频系 数 RCC_PLLCmd(ENABLE); //使能或者失能 PLL while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);//检查指定的 RCC 标志位设置 与否,PLL 就绪 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//设置系统时钟(SYSCLK) while(RCC_GetSYSCLKSource()!=0x08);//返回用作系统时钟的时钟源,0x08:PLL 作为 系统时钟 } } 这个函数的作用是:设置单片机的时钟来源为 HSE 外部高速时钟,并根据输入频率参数设置相应的频率。 要注意的是设置的输入频率参数一定要是 8 的倍数,并且是从 4 倍到 9 倍的频率数值。 int main() { led_Init(); //LED 端口初始化 RCC_HSE_Configuration();// 自定义系统时间,可修改分频 while(1) { GPIO_SetBits(GPIOB,LED); delay_ms(500);//精确延时为 0.5s GPIO_ResetBits(GPIOB,LED); delay_ms(500);//精确延时为 0.5s } } 这次的系统实验就到这里了。 |
消灭0回复![]() |