STM32F4_时钟系统精讲

目录

1. 什么是系统时钟

2. 时钟树

2.1 LSI

2.2 LSE

2.3 HSI 

2.4 HSE

2.5 PLLCLK

2.6 SYSCLK

2.7 HCLK

2.8 PCLK1

2.9 PCLK2

2.10 RTC/AWU

3 SysTick定时器

3.1 为什么会有Systick定时器?

3.2 SysTick定时器的作用 

3.3 SysTick定时器的寄存器

4. IO引脚复用和映射

5. NVIC中断优先级

5.1 中断寄存器

5.2 NVIC中断优先级设置函数

5.3 中断优先级设置步骤


        嵌入式入坑者,与君共勉,大家一起加油!

        💬推荐一款模拟面试、刷题神器,从基础到大厂面试题👉点击跳转刷题网站进行注册学习 

1. 什么是系统时钟

        时钟系统就像人的心脏一样,在单片机系统中起着脉搏的作用;时钟是由电路产生的具有周期性的脉冲信号,要想使用单片机的外设必须开启相应的时钟,也就是给时钟使能。我们知道,操作一个外设的本质是操作其对应的寄存器,而寄存器由D触发器构成,必须通过时钟才能改写触发器的值,所以想要操作外设必须使能相应的时钟;对于CPU来说,时钟的频率越高,其时钟值越小,这里可以理解时钟是一个信号的周期,时钟=1/f,频率越高,时钟越小,也就是单位时间内 CPU 能够做到更多的事,也就是我们常说的CPU运行快;

        STM32F4xx的时钟系统主要是给不同外设提供时钟,不同外设所需的时钟频率不同,如果像51单片机一样共用一个系统时钟,会造成资源浪费,给CPU运行带来负担,况且有些外设也接受不了这么大的频率;所以默认状态下,所有时钟是关闭的,操作哪个外设,就首先对哪个外设对应的时钟进行使能;

        STM32 共有5个时钟源:HSE(高速外部时钟)HSI(高速内部时钟)LSE(低速外部时钟)LSI(低速内部时钟)PLL(锁相环倍频输出)

2. 时钟树

按照从上到下,从左到右的顺序,我们依次来看时钟树的结构:使用任何外设之前一定要先使能对应的时钟,否则无法使用对应的外设;

        首先,LSI 低速内部时钟供到独立看门狗使用,32KHz,同时接到RTCSEL上,图中梯形形状代表着选择作用,也就是RTC可以选择LSE低速外部时钟使能,也可以选择LSI,在这里,通常选择LSE,因为LSE外接晶振,精度较高;LSE直接供RTC使用,LSE还可以经过1-5的分频后供MCO1使用;HSI 可以经过1-5 的分频后供 MCO1使用,HSI 也可以供给系统时钟 SYSCLK 选择使用,HSI 还可以通过分频后,在经过倍频,经过PLLP或者PLLQ后通过PLL输出;HSE通过1-5分频后可以供MCO2使用,HSE也可以供给系统时钟选择使用;PLL锁存倍频输出可以直接供外设使用;PLLI2S称为专用PLL;系统时钟可以是HSI、HSE、PLLCLK供应,其可以供应以太网PTP时钟;也可以通过AHB总线协议到AHB总线、内核、存储器和DMA,或者到Cortex系统定时器;

2.1 LSI

① LSI:low speed Internal Clock signal,低速内部(硬件焊接时不用外部加晶振,内部集成晶振 ag. CH340C)时钟。RC振荡器,频率32KHz左右。供看门狗(IWDG)和自动唤醒单元(AWU)使用。LSI RC更多的是担当一个低功耗时钟源的角色,可以在停机或者待机模式下保持运行。

使用:LSI RC是通过RCC时钟控制和状态寄存器RCC_CSR中的 LSION 位打开或关闭;RCC时钟控制和状态寄存器RCC_CSR中的 LSIDAY 标志指示低速内部振荡器是否稳定,硬件将此位置1,此时钟才可以使用;LSI RC更多的是担当一个低功耗时钟源的角色,可以在停机或者待机模式下保持运行。

 

 为独立看门狗或者RTC提供时钟;(上图)

 RCC时钟控制和状态寄存器RCC_CSR;(下图)

  

2.2 LSE

LSE:low Speed External Clock signal,低速外部(外部焊接时加上晶振和滤波电容)时钟。接32.768KHz的石英晶体,主要作为RTC的时钟源来提供时钟/日历或其他定时功能,具有功率低且精度高的优点。 其使用方法和 LSI 不尽相同。 

使用:LSE 晶振是通过RCC备份域控制寄存器RCC_BDCR中的 LSION 位打开或关闭;RCC备份域控制寄存器RCC_BDCR中的 LSEDAY 标志指示LSE晶振是否稳定,硬件将此位置1,此时钟才可以使用;如在RCC 时钟中断寄存器 (RCC_CIR) 中使能中断,则可产生中断。

 原理图上32.768MHz的外部晶振,直接接到芯片的引脚上。

主要作为RTC使能(上图);

RCC备份域控制寄存器RCC_BDCR(下图);

2.3 HSI 

HSI:High Speed Internal Clock signal,高速内部时钟。RC振荡器,频率16MHz,可以直接用作系统时钟或者PLL输入当HSE故障时,系统会自动的使用HSI,直到HSE启动成功(可做辅助时钟使用);HSI RC振荡器能够在不需要任何外部器件的条件下提供系统时钟(成本较低)。它的启动时间比HSE晶体振荡器短。然而,即使在校准之后它的时钟频率精度仍较差。

使用:RCC 时钟控制寄存器 (RCC_CR) 中的 HSIRDY 标志指示 HSI RC 是否稳定。在启动时,硬件将此位置 1 后,HSI 才可以使用。HSI RC 可通过 RCC 时钟控制寄存器 (RCC_CR) 中的 HSION 位打开或关闭。

D:SW系统时钟切换(System Clock switch);由软件置 1 或者清 0 来选择系统时钟源,再停止或者待机模式中直接或者间接的作为系统时钟的HSE出现故障时,HSI作为辅助时钟被系统强制的作为系统时钟;其中:

  • 00:HSI作系统时钟;
  • 01:HSE作系统时钟;
  • 10:PLL输出作系统时钟;
  • 11:不可用;

控制寄存器 (RCC_CR) (下图)

2.4 HSE

HSE:High Speed External Clock signal,高速外部时钟;可以接石英/陶瓷谐振器,频率范围为4MHz~26MHz。HSE也可以直接作为系统时钟或者PLL输入。

HSE的特点是 精度非常高

RCC 时钟控制寄存器 (RCC_CR) 中的 HSERDY 标志指示高速外部振荡器是否稳定。在启动时,硬件将此位置 1 后,此时钟才可以使用。如在 RCC 时钟中断寄存器 (RCC_CIR) 中使能 中断,则可产生中断。HSE 晶振可通过 RCC 时钟控制寄存器 (RCC_CR) 中的 HSEON 位打开或关闭。

原理图上8MHZ的外部晶振,直接接到芯片引脚上。

 RCC 时钟控制寄存器 (RCC_CR) (下图)

 

2.5 PLLCLK

PLLCLK:锁相环倍频输出;

由于在 PLL 使能后主 PLL 配置参数便不可更改,所以建议先对 PLL 进行配置,然后再使能 (选择 HSI 或 HSE 振荡器作为 PLL 时钟源,并配置分频系数 M、N、P 和 Q)。PLL总时钟经SystemInit 初始化以后的状态为168MHz;

主PLL(PLL)由 HSE或者HSI 提供时钟信号,并具有两个不同的输出时钟;第一个输出PLLP用于生成高速的系统时钟(最高168MHz);第二个输出PLLQ用于生成USB OTG FS的时钟(48MHz),随机数发生器的时钟和SDIO时钟。

专用PLL(PLLI2S)用于生成精确时钟,从而在I2S接口实现高品质音频性能。

主PLL先经过一个分频系数为M(PLL/M)的分频器,然后经过倍频系数为N的倍频器,出来之后经过分频系数为P(第一输出PLLP)或者第二输出(PLLQ)的分频器分频之后,最终生成主PLL时钟。ag . 外部晶振选择8MHz,设置相应的分频器M=8,倍频器倍频系数N=336,分频器分频系数P=2,可以计算得到主PLL生成的第一个输出高速时钟PLLP为:

PLL=8MHz * N/ (M*P)=8MHz* 336 /(8*2) = 168MHz  

2.6 SYSCLK

SYSCLK:系统时钟,最高为72M,通常的配置是SYSCLK=PLLCLK=168M。HSI、HSE、PLLCLK均可直接充当系统时钟;通过CFGR和SW进行控制;SW 系统切换已在2.3 HSI中讲解;在库函数里面关于CFGR(寄存器)主要是设置了HCLK、APB1和APB2 的时钟频率,还有通过寄存器后两位选择HSE/HSI/PLL这三个其中一个作为系统时钟。系统时钟经SystemInit函数初始化以后的状态为168MHz;

2.7 HCLK

HCLK:AHB(AHB是一种总线的协议,AHB用于高性能、高时钟频率的系统结构,典型的应用如ARM核与系统内部的高速RAM、NAND FLASH、DMA、Bridge的连接。)总线时钟;为AHB总线的外设提供时钟,为CorTex系统定时器提供时钟(SysTick)、为内核提供时钟(FCLK);

AHB总线时钟时钟经SystemInit函数初始化以后的状态为168MHz;HCLK=SYSCLK;

HCLK是通过系统时钟分频得到的,分频因子可以是1、2、4、8、16、128、256、512。通过CFGR、HPRE寄存器进行控制;

2.8 PCLK1

PCLK1:APB1总线时钟;PCLK1(APB1总线时钟)由PCLK经过低速APB1预分频得到,分频因子可以是1、2、4、8、16。PCLK1属于低速的总线时钟,最高可以为42MHz;APB1总线时钟经SystemInit函数初始化以后的状态为42MHz;PCLK1=SYSCLK/4;

PCLK1为APB1总线的外设提供时钟。1 或 2 倍频之后则为APB1总线的定时器2~7 提供时钟;

2.9 PCLK2

PCLK2:APB2总线时钟;由PCLK经过高速APB2预分频得到,分频因子可以是1、2、4、8、16。PCLK2属于高速的总线时钟,最高可以达到72MHz。APB2总线时钟为APB2总线的外设提供时钟。精确的说是为APB2的定时器1和8 提供时钟,最大为84M。APB2总线时钟时钟经SystemInit函数初始化以后的状态为84MHz;PCLK2=SYSCLK/2;

 见时钟树的APBx外设时钟APBx定时器时钟

2.10 RTC/AWU

一旦选定 RTCCLK 时钟源后,要想修改所做选择,只能复位电源域。

RTCCLK 时钟源可以是 HSE 1 MHz(HSE 由一个可编程的预分频器分频)、LSE 或者 LSI 时钟。选择方式是编程 RCC 备份域控制寄存器 (RCC_BDCR) 中的 RTCSEL[1:0] 位和 RCC 时钟配置寄存器 (RCC_CFGR) 中的 RTCPRE[4:0] 位。所做的选择只能通过复位备份域的方式修改。

如果选择 LSE 作为 RTC(实时时钟) 时钟,则系统电源丢失时 RTC 仍将正常工作。

如果选择 LSI 作为 AWU(自动唤醒单元)时钟,则在系统电源丢失时将无法保证 AWU 的状态。如果 HSE 振荡器通过一个介于 2 和 31 之间的值进行分频,则在备用或系统电源丢失时将无法保证 RTC 的状态。

3 SysTick定时器

3.1 为什么会有Systick定时器?

        SysTick定时器被捆绑在NVIC(中断优先级)中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。例如,为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。

3.2 SysTick定时器的作用 

        SysTick是一个24位的倒计数定时器,计到0时,将从RELOAD寄存器中自动重装载定时初值。只要不把他在SysTick控制及状态寄存器中的使能位清除,就永不停歇,即使在睡眠模式下也能工作;

        SysTick定时器除了能服务于操作系统之外,还可以作为一个时钟,用于测量时间。但是需要注意:当处理器在调试期间被喊停时,SysTick定时器也会暂停运作;SysTick定时器常用来做延时,或者实时系统的心跳时钟;

        SysTick定时器能产生中断;SysTick中断的优先级也可以设置;

        定时器的作用简单来说就是我们在中断中定义一个时间,时间会从当前值Value--;当减到0以后,重装载寄存器会重装载到定义的值,也就是回到定义的数值,源源不断的进行减减;就像51单片机里面的定时器中断一样,我定义interruptCount=1000,1000--;执行中断的内容;if(interruptCount==0){interruptCount=1000;}源源不断的进行;

3.3 SysTick定时器的寄存器

有4个寄存器控制SysTick定时器

SysTick控制及状态寄存器:

COUNTFLAG:16位,读取寄存器,复位值0,如果在上次读取本寄存器后,SysTick已经数到了0,则该位为1。如果读取该位,该位将自动清0;

CLKSOURCE:2位,读写寄存器,复位值0,0=外部时钟源(STCLK),1=内核时钟(FCLK);外部时钟源是AHB总线时钟的1/8,内核时钟是HCLK时钟;

TICKINT:1位,读写寄存器,复位值0,1=SysTick倒数到0时产生SysTick异常请求;(确定我们是否要产生中断)

ENABLE:0位,读写寄存器,复位值0,SysTick定时器的使能位;(使能);

SysTick重装载数值寄存器:

RELOAD:23:0位段,读写寄存器,复位值0,当倒数至零时,将被重装载值;

SysTick当前数值寄存器:

CURRENT:23:0位段,读写寄存器,复位值0,读取时返回当前倒计数的值,写入时他则使之清0,同时还会清除在SysTick控制及状态寄存器中的COUNTFLAG标志;

SysTick校准数值寄存器:

NOREF:31位,读取寄存器,1=没有外部参考时钟(STCLK不可用),0=外部参考时钟可用;

SKEW:30位,读取寄存器,1=校准值不是准确的10ms,0=校准值是准确的10ms;

TENMS:23:0位,读写寄存器,10ms时间内倒计数的格数;

配置函数:SysTick_CLKSourceConfig();

SysTick_Config(uint32_t ticks);初始化SysTick,时钟为HCLK,并开启中断;

void SysTick_Handler(void);中断服务函数;

4. IO引脚复用和映射

STM32F4有很多的内置外设,这些外设的外部引脚都是与GPIO复用的。也就是说,一个GPIO如果可以复用为内置外设的功能引脚,那么当这个GPIO作为内置外设使用的时候,就叫做复用

ag. 引脚上标注  PC11——PC11/SPI3 MISO/U3 RX/U4 RX/SDIO D3/DCMI D4/I2S3ext SD   那么,PC11可以作为SPI3_MISO/U3_RX/U4_RX/SDIO_D3/DCMI_D4/I2S3ext_SD等复用功能输出;但是这么多的复用功能,如果同时的全部开启,系统会乱套;STM32F4的复用选择功能可以让PC11仅连接到某个特定的外设,防止相互之间的干扰;

STM32F4系列微控制器IO引脚通过一个复用器连接到内置外设或模块。该复用器一次只允许一个外设的复用功能(AF)连接到对应的IO口。这样可以确保共用同一个IO引脚的外设之间不会发生冲突。 

我们配置相应的寄存器GPIOx_AFRL或者GPIOx_AFRH,让对应引脚通过复用器连接到对应的复用功能外设。GPIOx_AFRH控制的是一组IO口的高八位,GPIOx_AFRL控制的是一组IO口的低八位。

对于外设复用功能的配置,除了ADC和DAC要将IO配置为模拟通道之外其他外设功能一律 要配置为复用功能模式,这个配置是在IO口对应的GPIOx_MODER寄存器中配置的。同时要配置GPIOx_AFRH或者GPIOx_AFRL寄存器,将IO口通过复用器连接到所需要的复用功能对应的AFx

通过MCU微控制器的PA9和PA10引脚我们来介绍一下如何配置串口1为复用功能:

1. 首先打开IO时钟和复用功能时钟(切记:32不同于51的最大区别就是想要使用任何外设,必须先对外设所对应时钟的寄存器进行使能)

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); ---使能GPIOA时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); ---使能USART1时钟

2. 在初始化GPIO口的寄存器GIPOx_MODER中将所需的IO配置为复用功能(ADC和DAC设置为模拟通道)

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;---复用功能

3. 配置GPIOx_AFRL或者GPIOx_AFRH寄存器,将IO连接到所需的AFx。

GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); ---PA9复用为USART1

GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); ---PA10复用为USART1

5. NVIC中断优先级

CM4内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置;开发板STM32F4xx系列共92个中断,包括10个内核中断和82个可屏蔽中断;其中最常用的就是82个可屏蔽中断;

5.1 中断寄存器

ISER[8]:

ISER全称是:Interrupt Set-Enable Registers,这是一个中断使能寄存器组。

CM4内核支持256个中断,在ISER中用8个32位寄存器来控制;要想使能某个中断,必须设置相应的ISER位为1,使该中断使能(但需要注意:这里也仅仅是使能,要想设置一个完整的中断还需要配合中断分组、屏蔽、IO口映射)

ICER[8]:

ICER全称是:Interrupt Clear-Enable Registers,是一个中断除能寄存器组。

除能---使能;正如其名,该寄存器和ISER作用正好相反,是用来清除某中断使能的;NVIC的这些寄存器都是写1有效的,写0是无效的。

ISPR[8]:

ISPR全称是:Interrupt Set-Pending Registers,是一个中断挂起控制寄存器组。

通过置1,将正在进行的中断挂起,而执行同级或更高级别的中断。

ICPR[8]:

ICPR全称是:Interrupt Clear-Pending Registers,是一个中断解挂控制寄存器组。

通过置1,可以将挂起的中断解挂;

IABR[8]:

IABR全称是:Interrupt Active Bit Registers,是一个中断激活标志位寄存器组。

对应位所代表的中断和ISER一样,如果为1,则表示该位所对应的中断正在被执行。这是一个只读寄存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。 

IP[240]:-----------NVIC寄存器中最重要的寄存器

IP全称是:Interrupt Priority Registers,是一个中断优先级控制的寄存器组。

IP寄存器由240个8bit寄存器组成,8bit的高四位低四位分别表示抢占优先级响应优先级;抢占优先级在前;

 规则:

1. 抢占优先级的级别高于响应优先级。而数值越所代表的优先级就越

2. 如果两个中断的抢占优先级和响应优先级都是一样的话,看哪个中断先发生就先执行。

3. 高优先级的抢占优先级是可以打断正在进行的低强占优先级中断的。

ag. 假定设置中断优先级组为2,然后设置中断3(RTC_WKUP中断)的抢占优先级为2,响应优先级为1。中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0。那么这3个中断的优先级顺序为:中断7>中断3>中断6。 切记:抢占优先级数值越小,所代表的优先级就越高。

5.2 NVIC中断优先级设置函数

1. 首先进行中断优先级分组:NVIC_PriorityGroupConfig

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  --- 根据上述表格,设置2位抢占优先级,2位响应优先级;

2. 中断初始化函数NVIC_Init 

中断初始化函数和GPIO初始化函数是一样的,是用结构体来进行初始化的;其共有4个成员变量;

NVIC_InitTypeDef NVIC_InitStructure;---定义结构体变量NVIC_InitStructure

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;---初始化的是哪一个中断(串口1)

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;---中断的抢占优先级别(抢占优先级1)

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;---中断的响应优先级别(响应优先级2)   子优先级就是响应优先级

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; ---中断通道是否使能(使能)

NVIC_Init(&NVIC_InitStructure); ---取地址,初始化NVIC寄存器

5.3 中断优先级设置步骤

1. 系统运行开始的时候设置中断分组。确定组号,也就是确定抢占优先级和响应优先级的分配位数。调用函数为NVIC_PriorityGroupConfig();   main函数

2. 设置所用到的中断的中断优先级别。对每个中断调用函数为NVIC_Init(); 

  • 4
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值