STM32F407单片机时钟系统介绍及配置

一、时钟树

A 输入时钟源,可分为外部时钟源和内部时钟源,字母代表意义如下图

因此共有四种时钟源,即

HSI(高速内部振荡器)、HSE(高速外部振荡器)、

LSI(低速内部振荡器)、LSE(低速外部振荡器);

B 为锁相环“PLL”;

C 为系统时钟源选择器此项决定了 MCU 的系统主时钟“SYSCLK”的大小;

D Cortex-M 内核系统的时钟和使能单元

E 为定时器以及其它外设的时钟源 APB1/APB2Advanced Peripheral Bus);

F STM32 MCO时钟输出功能

1、时钟源

输入时钟源(Input Clock)主要包括 HSIHSELSILSE 

外部时钟源就是从外部通过接晶振的方式获取的时钟源。内部时钟源是由内部 RC 振荡器产生。

芯片上电时默认由内部的 HSI 时钟启动

2、锁相环PLL

锁相环(Phase-Locked Loop,简称PLL)是一种电子电路,通过反馈控制机制实现输出信号的频率和相位与输入参考信号的同步。

在STM32主控中,锁相环的作用主要有两个:输入时钟净化倍频

下图为使用PLL作为系统时钟源时的配置图,

标号①表示的是 PLL 时钟源的选择器可选HSI 信号,HSE信号

标号②表示PLL输入时钟的分频系数可选0~63

标号表示配置锁相环倍频系数即选择倍频因子,有三个参数PPL_N、PPL_N、PPL_Q

3、系统时钟

STM32 的系统时钟是可配置的,它可以为 HSIPLLCLKHSE中的一个,通过 CFGR 的位 SW[1:0]设置。AHBAdvanced High-performance BusAPB1APB2Advanced Peripheral Bus内核时钟等时钟通过系统时钟分频得到

下图为系统时钟配置图,

标号④为系统时钟输入源选择可选HSIPLLCLKHSE中的一个;

标号⑤AHB预分频器,可选择分频系数1248163264128256512

AHB总线时钟直接作为 GPIO(A\B\C\D\E\F\G\H\I\)、以太网、DCMIFSMCAHB总线、Cortex内核、存储器和 DMA HCLK时钟,并作为 Cortex 内核自由运行时钟FCLK

下面介绍一下由AHBAdvanced High-performance Bus总线时钟得到的时钟:

标号⑥APB1预分频器,分频因子可以选择 124816

#注意:与APB1低速总线连接的外设有:看门狗定时器、定时器2/3/4/5/6/7RTC 时钟、USART2/3/4/5SPI2(I2S2)SPI3(I2S3)I2C1~3CAN 2DAC

标号⑦APB2预分频器,分频因子可以选择 124816

#注意:与 APB2高速总线连接的外设有定时器1/8/9/10/11SPI1USART1USART63ADCSDIO接口

标号⑧决定了定时器时钟频率,该位由硬件自动设置,分为两种情况:

1、如果APB预分频器为 1定时器时钟频率等于APB域的频率;

2、否则,等于APB域的频率的两倍(×2)。

标号⑨RTC时钟,其时钟源有三个途径:HSE/xx = 2~31)、LSE LSI

二、时钟系统配置

STM32F407 默认的情况下,使用的是内部8MHSI作为时钟源,所以不需要外部晶振也可以下载和运行代码。168MHz是官方推荐使用的最高的稳定时钟频率

第 1 步:配置 HSE_VALUE

代码中通过使用宏定义的方式来选择 HSE_VALUE 的值是25M或者8M选择定义 HSE_VALUE 的值为 8M。代码如下:

#if !defined (HSE_VALUE)

#define HSE_VALUE 8000000U          /*!< Value of the External oscillator in Hz */

#endif

#endif                                                   /* HSE_VALUE */

 第 2 步:调用 SystemInit 函数 

在系统启动之后,程序会先执行 SystemInit 函数,进行一些初始化配置。SystemInit 主要做了如下两个方面工作: 1) 外部存储器配置 2) 中断向量表地址配置。因此,是可以把一些重要的初始化放到 SystemInit 这里,在 main 函数运行前就把重要的一些初始化配置好,使得 main 函数更加简单,但对于初学者,我们暂时不建议这种用法。

HAL 库的 SystemInit 函数并没有任何时钟相关配置,所以后续的初始化步骤,还必须编写自己的时钟配置函数。

第 3 步:在 main 函数里调用用户编写的时钟设置函数 

函数 sys_stm32_clock_init 就是用户的时钟系统配置函数。

uint8_t sys_stm32_clock_init(uint32_t plln, uint32_t pllm, uint32_t pllp, uint32_t pllq)

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

使用 HAL 库配置 STM32F4 时钟系统的一般步骤为:

1)配置时钟源相关参数:调用函数HAL_RCC_OscConfig()

2)配置系统时钟源以及 SYSCLKAHBAPB1 APB2 的分频系数:调用函数 HAL_RCC_ClockConfig()

步骤详解:

步骤 1:配置时钟源相关参数

调用HAL_RCC_OscConfig()函数

HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct);

·函数描述

该函数用于配置时钟源。

·函数形参

形参1(RCC_OscInitTypeDef *RCC_OscInitStruct结构体 RCC_OscInitTypeDef 类型指针定义如下:

typedef struct

{

 uint32_t    OscillatorType;                   /* 需要选择配置的振荡器类型 */

 uint32_t    HSEState;                          /* HSE 状态 */

 uint32_t    LSEState;                           /* LSE 状态 */

 uint32_t    HSIState;                            /* HSI 状态 */

 uint32_t    HSICalibrationValue;          /* HSI 校准值 */

 uint32_t    LSIState;                            /* LSI 状态 */

 RCC_PLLInitTypeDef PLL;                 /* PLL 配置 */

}RCC_OscInitTypeDef;

该结构体前面几个参数主要是用来选择配置的振荡器类型。比如要开启 HSE那么就要设置OscillatorType的值为RCC_OSCILLATORTYPE_HSE然后设置 HSEState 的值为 RCC_HSE_ON开启HSE。对于HSILSILSE,配置方法类似

RCC_OscInitTypeDef 这个结构体还有一个很重要的成员变量是 PLL,它是结构体 RCC_PLLInitTypeDef 类型。它的作用是配置 PLL 相关参数,它的定义如下

typedef struct

{

uint32_t    PLLState;           /* PLL 状态 */

uint32_t    PLLSource;        /* PLL 时钟源 */

uint32_t    PLLM;                /* PLL 倍频系数 M */

uint32_t    PLLN;                /* PLL 倍频系数 N */

uint32_t    PLLP;                /* PLL 倍频系数 P */

uint32_t    PLLQ;               /* PLL 倍频系数 Q */

}RCC_PLLInitTypeDef;

 该结构体主要用来设置 PLL 时钟源以及相关分频倍频参数结构体定义的相关内容结合时钟树中红色框的内容更容易理解

举例:时钟初始化函数 sys_stm32_clock_init 中的实际应用配置内容如下

/*使能HSE,并选择HSE作为PLL时钟源,配置PLL1,开启USB时钟*/

 rcc_osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSE;

 rcc_osc_init.HSEState = RCC_HSE_ON;                                 /* 打开 HSE */

 rcc_osc_init.PLL.PLLState = RCC_PLL_ON;                           /* 打开 PLL */

 rcc_osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSE;      /* PLL 时钟源选择 HSE */

 rcc_osc_init.PLL.PLLN = plln;

 rcc_osc_init.PLL.PLLM = pllm;

 rcc_osc_init.PLL.PLLP = pllp;

 rcc_osc_init.PLL.PLLQ = pllq;

通过该段程序,我们开启了 HSE 时钟源,同时选择 PLL 时钟源为 HSE,然后把 sys_stm32_clock_init 的形参直接设置作为 PLL 的参数 M 的值,这样就达到了设置 PLL 时钟源 相关参数的目的。 

 设置好PLL时钟源参数之后,也就确定了PLL的时钟频率,然后可以进行步骤2

步骤 2:配置系统时钟源,以及 SYSCLKAHBAPB1 APB2 相关参数

调用HAL_RCC_ClockConfig()函数

HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct,

uint32_t FLatency);

·函数描述

该函数用于配置系统时钟源以SYSCLKAHBAPB1 APB2 的分频系数

·函数形参

形参1(RCC_ClkInitTypeDef *RCC_ClkInitStruct是结构体 RCC_ClkInitTypeDef 类型指针变量,用于设置SYSCLK时钟源以及SYSCLKAHBAPB1 APB2 的分频系数

形参2(uint32_t FLatency用于设置 FLASH 延迟

RCC_ClkInitTypeDef 结构体类型定义如下:

typedef struct

{

 uint32_t    ClockType;                           /* 要配置的时钟 */

 uint32_t    SYSCLKSource;                  /* 系统时钟源 */

 uint32_t    AHBCLKDivider;                  /* AHB 分频系数 */

 uint32_t    APB1CLKDivider;                /* APB1 分频系数 */

 uint32_t    APB2CLKDivider;                /* APB2 分频系数 */

}RCC_ClkInitTypeDef;

举例:sys_stm32_clock_init 函数中实际应用配置内容如下:

/* 选中 PLL 作为系统时钟源并且配置 HCLK,PCLK1 和 PCLK2*/

rcc_clk_init.ClockType = ( RCC_CLOCKTYPE_SYSCLK \

                                             | RCC_CLOCKTYPE_HCLK \

                                             | RCC_CLOCKTYPE_PCLK1 \

                                             | RCC_CLOCKTYPE_PCLK2);

                                                                                        /* 设置系统时钟时钟源为 PLL */

rcc_clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; rcc_clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1;     /* AHB 分频系数为 1 */ rcc_clk_init.APB1CLKDivider = RCC_HCLK_DIV4;        /* APB1 分频系数为 4 */ rcc_clk_init.APB2CLKDivider = RCC_HCLK_DIV2;        /* APB2 分频系数为 2 */

 sys_stm32_clock_init 函数中的 RCC_ClkInitTypeDef 结构体配置内容:

第一个参数 ClockType 配置表示我们要配置的是 SYSCLK、HCLK、PCLK1 和 PCLK 四个 时钟。

第二个参数 SYSCLKSource 配置选择系统时钟源为 PLLCLK。

第三个参数 AHBCLKDivider 配置 AHB 分频系数为 1。

第四个参数 APB1CLKDivider 配置 APB1 分频系数为 4。

第五个参数 APB2CLKDivider 配置 APB2 分频系数为 2。 

至此,mian 函数中便可直接调用sys_stm32_clock_init()函数,并且设置它的四个形参。

举例:假如我们在 mian 函数中调用 sys_stm32_clock_init(336, 8, 2, 7),则可以计算出,PLL 时钟为 PLLCLK = HSE * 336 / 8 / 2 = 168MHz。

总结

1、STM32F407时钟系统系统

2、时钟系统配置:

①宏定义 HSE_VALUE;

②调用HAL_RCC_OscConfig()函数,配置输入时钟源;

③调用HAL_RCC_ClockConfig()函数,配置系统时钟源以及 SYSCLK、AHB、APB1 和 APB2 相关参数;

④在main函数中调用sys_stm32_clock_init()函数并设置形参;

#注意:②和③中的函数均在sys_stm32_clock_init()函数中调用,main函数中只调用sys_stm32_clock_init()函数,且sys_stm32_clock_init()函数的描述在sys.c中,main.c中只配置该函数的四个形参。

STM32F407是一款高性能的ARM Cortex-M4内核的单片机,最小系统的设计主要包括芯片选择、外围电路设计、封装和PCB布局。 首先,我们需要选择STM32F407芯片,该芯片具有128KB至1MB的Flash存储器和192KB的SRAM,还拥有多种外设如UART、SPI、I2C等,以满足不同应用需求。 其次,外围电路设计需要包括时钟电路、电源电路和复位电路。对于时钟电路,可以选择使用外部晶体振荡器,根据芯片手册规定的频率接入晶振引脚,并将晶振输出连接到芯片的时钟输入引脚。关于电源电路,应提供合适的电压稳定器和滤波电容,以确保芯片稳定工作。对于复位电路,可以使用通过复位按钮或自动检测异常电压的方式实现复位。 此外,在选择封装和PCB布局方面,应根据设计需求选择合适的封装类型,如QFP、LQFP等,并确保引脚布局合理,便于外部连接。对于PCB布局,需要根据外围电路和封装选择进行引脚布线,保证信号传输可靠性和电磁兼容性,并合理规划地面层和电源层。 最后,还需要配置开发环境,包括使用适当的软件工具如Keil MDK等进行编程和调试,以及选择合适的编程方式如JTAG或SWD进行芯片烧录和调试。 总之,STM32F407单片机最小系统的设计需要根据具体应用需求选择芯片、设计外围电路、选择封装和PCB布局,并配置合适的开发环境,以实现系统的可靠运行和开发工作的顺利进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值