• 嵌入式开发学习之--RCC(下)



    前言

    这一篇记录一下时钟的具体实验。


    提示:以下是本篇文章正文内容,下面案例可供参考

    一、使用HSE

      一般情况下,我们都是使用 HSE,然后 HSE 经过 PLL 倍频之后作为系统时钟。F429系统时钟最高为 180M,这个是官方推荐的最高的稳定时钟,如果你想铤而走险,也可以超频,超频最高能到 216M

      如果我们使用库函数编程,当程序来到 main 函数之前,启动文件:
    startup_stm32f429_439xx.s 已经调用 SystemInit()函数把系统时钟初始化成 180MHZ,SystemInit()在库文件:system_stm32f4xx.c 中定义。如果我们想把系统时钟设置低一点或者超频的话,可以修改底层的库文件,但是为了维持库的完整性,我们可以根据时钟树的流程自行写一个。

    二、使用HSI

      当 HSE 直接或者间接(HSE 经过 PLL 倍频)的作为系统时钟的时候,如果 HSE 发生故障,不仅 HSE 会被关闭,连 PLL 也会被关闭,这个时候系统会自动切换 HSI 作为系统时钟,此时 SYSCLK=HSI=16M,如果没有开启 CSS 和 CSS 中断的话,那么整个系统就只能在低速率运行,这是系统跟瘫痪没什么两样。

      如果开启了 CSS 功能的话,那么可以当 HSE 故障时,在 CSS 中断里面采取补救措施,使用 HSI,重新设置系统频率为 180M,让系统恢复正常使用。但这只是权宜之计,并非万全之策,最好的方法还是要采取相应的补救措施并报警,然后修复 HSE。临时使用 HSI 只是为了把损失降低到最小,毕竟 HSI 较于 HSE 精度还是要低点。

      F103 系列中,使用 HSI 最大只能把系统设置为 64M,并不能跟使用 HSE 一样把系统时钟设置为 72M,究其原因是 HSI 在进入 PLL 倍频的时候必须 2 分频,导致 PLL 倍频因子调到最大也只能到 64M,而 HSE 进入 PLL 倍频的时候则不用 2 分频。

      在 F429 中,无论是使用 HSI 还是 HSE 都可以把系统时钟设置为 180M,因为 HSE 或 者 HSI 在进入 PLL 倍频的时候都会被分频为 1M 之后再倍频。还有一种情况是,有些用户不想用 HSE,想用 HSI,但是又不知道怎么用 HSI 来设置
    系统时钟,因为调用库函数都是使用 HSE,下面我们给出个使用 HSI 配置系统时钟例子,起个抛砖引玉的作用。

    三、代码编写

      代码如下(示例):

     /*
    2 * m: VCO 输入时钟 分频因子,取值 2~63
    3 * n: VCO 输出时钟 倍频因子,取值 192~432
    4 * p: SYSCLK 时钟分频因子 ,取值 2,4,6,8
    5 * q: OTG FS,SDIO,RNG 时钟分频因子,取值 4~15
    6 * 函数调用举例,使用 HSE 设置时钟
    7 * SYSCLK=HCLK=180M,PCLK2=HCLK/2=90M,PCLK1=HCLK/4=45M
    8 * HSE_SetSysClock(25, 360, 2, 7);
    9 * HSE 作为时钟来源,经过 PLL 倍频作为系统时钟,这是通常的做法
    10 
    11 * 系统时钟超频到 216M 爽一下
    12 * HSE_SetSysClock(25, 432, 2, 9);
    13 */
    14 void HSE_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q)
    15 {
    16 __IO uint32_t HSEStartUpStatus = 0;
    17 
    18 // 使能 HSE,开启外部晶振,野火 F429 使用 HSE=25M
    19 RCC_HSEConfig(RCC_HSE_ON);
    20 
    21 // 等待 HSE 启动稳定
    22 HSEStartUpStatus = RCC_WaitForHSEStartUp();
    23 
    24 if (HSEStartUpStatus == SUCCESS) {
    25 // 调压器电压输出级别配置为 1,以便在器件为最大频率
    26 // 工作时使性能和功耗实现平衡
    27 RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    28 PWR->CR |= PWR_CR_VOS;
    29 
    30 // HCLK = SYSCLK / 1
    31 RCC_HCLKConfig(RCC_SYSCLK_Div1);
    32 
    33 // PCLK2 = HCLK / 2
    34 RCC_PCLK2Config(RCC_HCLK_Div2);
    35 
    36 // PCLK1 = HCLK / 4
    37 RCC_PCLK1Config(RCC_HCLK_Div4);
    38 
    39 // 如果要超频就得在这里下手啦
    40 // 设置 PLL 来源时钟,设置 VCO 分频因子 m,设置 VCO 倍频因子 n,
    41 // 设置系统时钟分频因子 p,设置 OTG FS,SDIO,RNG 分频因子 q
    42 RCC_PLLConfig(RCC_PLLSource_HSE, m, n, p, q);
    43 
    44 // 使能 PLL
    45 RCC_PLLCmd(ENABLE);
    46 
    47 // 等待 PLL 稳定
    48 while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {
    49 }
    50 
    51 /*-----------------------------------------------------*/
    52 //开启 OVER-RIDE 模式,以能达到更高频率
    53 PWR->CR |= PWR_CR_ODEN;
    54 while ((PWR->CSR & PWR_CSR_ODRDY) == 0) {
    55 }
    56 PWR->CR |= PWR_CR_ODSWEN;
    57 while ((PWR->CSR & PWR_CSR_ODSWRDY) == 0) {
    58 }
    59 // 配置 FLASH 预取指,指令缓存,数据缓存和等待状态
    60 FLASH->ACR = FLASH_ACR_PRFTEN
    61 | FLASH_ACR_ICEN
    62 | FLASH_ACR_DCEN
    63 | FLASH_ACR_LATENCY_5WS;
    64 /*-----------------------------------------------------*/
    65 
    66 // 当 PLL 稳定之后,把 PLL 时钟切换为系统时钟 SYSCLK
    67 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    68 
    69 // 读取时钟切换状态位,确保 PLLCLK 被选为系统时钟
    70 while (RCC_GetSYSCLKSource() != 0x08) {
    71 }
    72 } else {
    73 // HSE 启动出错处理
    74 
    75 while (1) {
    76 }
    77 }
    78 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

      形参说明:
    在这里插入图片描述

      HSI 为 16M,参数 m 我们一般也设置为 16,所以我们需要修改系统时钟的时候只需要修改参数 n 和 p 即可,SYSCLK=PLLCLK=HSI/m*n/p。

      函数调用举例:HSI_SetSysClock(16, 360, 2, 7) 把系统时钟设置为 180M,这个跟库里面的系统时钟配置是一样的。HSI_SetSysClock(16, 432, 2, 9)把系统时钟设置为 216M,这个是超频,要慎用。


    总结

      时钟很关键,他是各个设备的生命线,一旦时钟没有正确配置,那么基于时钟的所有外设都会出问题。以后经常用经常配置就熟悉了。

  • 相关阅读:
    pycharm plot不显示的问题
    嵌入式&QT&Git面试题
    个人深度学习环境配置
    机器学习笔记 - 常用概率分布
    equals()方法
    上帝视角看Vue源码整体架构+相关源码问答
    基于simulink的Active anti-islanding-AFD主动反孤岛模型仿真
    初学者记录一下mysql学习中遇到的两个问题
    学习笔记-java代码审计-表达式注入
    华为机试 - 任务最优调度
  • 原文地址:https://blog.csdn.net/code_lyb/article/details/128196354