STM32时钟系统和时钟树

发布于:2024-05-16 ⋅ 阅读:(57) ⋅ 点赞:(0)

目录

STM32时钟系统

认识时钟树

什么是时钟

认识时钟树(F407)

配置系统时钟

系统时钟配置步骤

外设时钟使能和失能

sys_stm32_clock_init函数(F4)

 时钟配置一般步骤

System文件夹_时钟系统工作原理

System文件夹介绍

Sys文件介绍

Delay文件介绍

Systic工作原理

Syctic寄存器介绍

Usart文件介绍

printf()函数输出流程

printf的使用

printf函数支持


STM32时钟系统

认识时钟树

什么是时钟

简单来说,时钟是具有周期性的脉冲信号,最常用的是占空比为50%的方波

认识时钟树(F407)

F4时钟树--正点原子

图中为一个简化的STM32F4时钟系统。A部分表示输入时钟源,可分为外部时钟源和内部时钟源;B为锁相环“PLL”;C为我们重点需要关注的系统时钟源选择器,此项决定了MCU的系统主时钟“SYSCLK”的大小;AHB预分频器将SYSCLK分频或不分频后分发给其它外设进行处理,包括到D部分的Cortex-M内核系统的时钟和使能单元。E为定时器以及其它外设的时钟源APB1/APB2。

HSE和HSI经过/M分频之后传递锁相环,锁相环会使晶振走过*N倍频器,之后如果再走过/P分频则可以直接作为系统时钟SYSCLC,如果走过/Q分频则可以作为其他外设的时钟。

系统时钟之后会去到AHB总线的时钟

AHB时钟经过总线桥会去到APB1和APB2(这俩实际上是由AHB1桥接过来的)

LSI可以为IWDG和RTC提供时钟

LSE专门为RTC提供时钟

说白了STM32时钟源就外部高速、外部低速、内部高速、内部低速四个时钟源,另外还有3个PLL锁相环

外设的时钟源大都是由这四个时钟源经过选择器和倍频等操作得到的

STM32F4时钟树简图

配置系统时钟

系统时钟配置步骤

外设时钟使能和失能

要使用某个外设,必须先使能该外设的时钟

sys_stm32_clock_init函数(F4)

HAL_RCC_OscConfig()函数

HAL_RCC_ClockConfig()函数

 

/P输出 8M/8*336/2=168        /Q输出 8M/8*336/7=48 

//RCC_OscInitTypeDef rcc_clk_init

/* 选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2*/
/* 选择要配置的时钟为 SYSCLK、HCLK、PCLK1、PCLK2  系统时钟、AHB总线时钟、APB1、APB2总线时钟 */
    rcc_clk_init.ClockType = ( RCC_CLOCKTYPE_SYSCLK \
                                    | RCC_CLOCKTYPE_HCLK \
                                    | RCC_CLOCKTYPE_PCLK1 \
                                    | RCC_CLOCKTYPE_PCLK2);
     /* 设置系统时钟时钟源为PLL 根据时钟树简图系统时钟可供选择的时钟源还有HSE和HSI*/
    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 */
  /* 同时设置FLASH延时周期为5WS,也就是6个CPU周期 根据手册上FLASH读接口的FLASH等待周期表得到 */
    ret = HAL_RCC_ClockConfig(&rcc_clk_init, FLASH_LATENCY_5);     
   

 时钟配置一般步骤

  • 使能PWR时钟:调用函数 _HAL_RCC_PWR_CLK_ENABLE()。
  • 设置调压器输出电压级别:调用函数 _HAL_PWR_VOLTAGESCALING_CONFIG()。
  • 选择是否开启Over-Driver功能:调用函数HAL_PWREx_EnableOverDrive()。
  • 配置时钟源相关参数:调用函数HAL_RCC_OscConfig()。
  • 配置系统时钟源以及AHB,APB1和APB2的分频系数:调用函数HAL_RCC_ClockConfig()。

PWR时钟名是“Power Control时钟”。Power Control模块负责管理微控制器的电源管理功能,包括进入低功耗模式、唤醒控制、备份寄存器等。通过配置和控制PWR时钟,可以有效地管理STM32微控制器的电源消耗

  • STM32有4个时钟源:HSI、HSE、LSI、LSE和3个PLL

  • HSI是高速内部时钟,RC振荡器,频率为16MHz,精度不高。可以直接作为系统时钟或者用作PLL时钟输入。

  • HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~26MHz。

  • LSI是低速内部时钟,RC振荡器,频率为32kHz,提供低功耗时钟。主要供独立看门狗和自动唤醒单元使用。

  • LSE是低速外部时钟,接频率为32.768kHz的石英晶体。RTC

  • PLL为锁相环倍频输出。 STM32F4有三个PLL:

  • 主PLL(PLL)由HSE或者HSI提供时钟信号,并具有两个不同的输出时钟。

①第一个输出PLLP用于生成高速的系统时钟(最高180MHz)

②第二个输出PLLQ为48M时钟,用于USB OTG FS时钟,随机数发生器的时钟和SDIO时钟。

  • 第一个专用PLL(PLLI2S)生成精确时钟,在I2S和SAI1上实现高品质音频

    N是用于PLLI2S vco的倍频系数,其取值范围是:192~432;

    R是I2S时钟的分频系数,其取值范围是:2~7;

    Q是SAI时钟分频系数,其取值范围是:2~15;P没用到。

  • 第二个专用PLL(PLLSAI)同样用于生成精确时钟,用于SAI1输入时钟,同时还为LCD_TFT接口提供精确时钟。

    N是用于PLLSAI vco的倍频系数,其取值范围是:192~432;

    Q是SAI时钟分频系数,其取值范围是:2~15;

    R是LTDC时钟的分频系数,其取值范围是:2~7;P没用到。

  • PLLCLK=HSE*N/(M * P),可以通过改变N、M、P改变PLLCLK的频率

  • 系统时钟SYSCLK可来源于三个时钟源:

​ ①、HSI振荡器时钟

​ ②、HSE振荡器时钟

​ ③、PLL时钟

  • 任何外设在使用之前,必须使能相应的时钟

  • STM32F4时钟信号输出MCO1(PA8)和MCO2(PC9),MCO1:用户可以配置预分频器(1~ 5)向MCO1引脚PA8输出4个不同的时钟源:HIS、LSE、HSE、PLL。MCO2:用户可以配置预分频器(1~ 5)向MCO2引脚PC9输出4个不同的时钟源:HSE、PLL、SYSCLK、PLLI2S 。MCO最大输出时钟不超过100MHz。

  • RCC时钟控制相关寄存器定义在stm32f429xx.h中。结构体: RCC_TypeDef;RCC时钟相关定义和函数在文件stm32f4xx_hal_rcc.h、stm32f4xx_hal_rcc.c 。

System文件夹_时钟系统工作原理

System文件夹介绍

 正点原子提供的System文件夹包含常用的函数和驱动

Sys文件介绍

Delay文件介绍

Systic工作原理

Systic即系统滴答定时器,包含在M3/4/7内核里面,核心是一个24位的递减计数器

F1/F4/F7的Systic定时器的时钟来源于HCLK,也就是AHB总线上的时钟

H7的Systic定时器的时钟来源于SYS_d1cpre_ck(H7),也就是系统的d1分频器

Syctic寄存器介绍

Systic重装载数值寄存器(Load)  和  Systic当前数值寄存器(Val)

Systic控制及状态寄存器(CTRL)

由于滴答定时器是处于芯片内核中的,ST公司使用之后将CLKSOURCE位固定了,因此并不是起到选择时钟源的作用,而是被ST公司设置后起到分频的作用

TICKINT其实就是起到一个倒数计时完成后触不触发中断的作用

Usart文件介绍

printf()函数输出流程

printf的使用

printf函数支持

半主机模式 :用于ARM目标的一种机制,可以将来自应用程序代码的输入输出请求传递至运行调试器的主机

简单说,就是通过仿真器实现开发板在电脑上的输入和输出

一般不使用半主机模式,而是使用串口模式

要提供printf()函数支持,首先要避免半主机模式

可使用微库法

和代码法

如果要使用串口,就需要根据串口这个硬件重新实现fputc(int ch,FILE *f)这个函数

当串口的状态寄存器USART_UX->SR的0x40位,也就是第6位==0,代表上一个字符还没有发送完成,就循环等待。上一个字符发送完成后,将字符写入串口的数据寄存器USART_UX->SR。

如果不等待fputc上一个字符发送完成就往usart->DR写下一个字符会导致乱码