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

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 嵌入式开发学习之--RCC(下)

嵌入式开发学习之--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 }

形参说明:

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,这个是超频,要慎用。

总结

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

相关实践学习
通过workbench远程登录ECS,快速搭建Docker环境
本教程指导用户体验通过workbench远程登录ECS,完成搭建Docker环境的快速搭建,并使用Docker部署一个Nginx服务。
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
6天前
|
传感器 C++
精通嵌入式开发:从原理到实践
嵌入式开发是一门涉及硬件和软件交叉领域的技术,要想精通这门技术,需要从理论基础到实际操作都有深入的了解和实践。
17 3
|
7月前
|
传感器 C语言 芯片
「入门指南」轻松学习嵌入式 GPIO:从原理到应用一步到位
「入门指南」轻松学习嵌入式 GPIO:从原理到应用一步到位
|
7月前
|
传感器 开发工具 数据安全/隐私保护
嵌入式开发
一、嵌入式开发是什么 嵌入式开发是指在嵌入式系统中进行软件开发的过程。嵌入式系统是一种特殊的计算机系统,它被设计用于执行特定的任务,通常嵌入在其他设备或系统中,如家电、汽车、医疗设备等。嵌入式开发涉及到设计、编写和调试嵌入式系统的软件,以满足特定的需求和功能要求。 嵌入式开发通常需要掌握特定的编程语言和开发工具,如C、C++、汇编语言等。开发人员需要了解硬件平台的特性和限制,以便进行有效的软件设计和优化。嵌入式开发还涉及到驱动程序的开发、实时操作系统的使用、硬件接口的编程等。 嵌入式开发的目标是开发出高效、可靠、节能的嵌入式软件,以满足特定应用的需求。嵌入式系统的应用范围广泛,从智能手机到工业
76 0
嵌入式开发学习之--RCC(上)
嵌入式开发学习之--RCC(上)
嵌入式开发学习之--RCC(上)
|
内存技术
嵌入式开发学习之--位带操作
嵌入式开发学习之--位带操作
|
存储 Java 数据安全/隐私保护
嵌入式开发学习之--串口通讯(下)
嵌入式开发学习之--串口通讯(下)
嵌入式开发学习之--串口通讯(下)
|
芯片 开发者
嵌入式开发学习之--串口通讯(上)
嵌入式开发学习之--串口通讯(上)
嵌入式开发学习之--串口通讯(上)
|
机器人 C++
基于stm32的嵌入式开发学习之--前言
基于stm32的嵌入式开发学习之--前言
|
存储 小程序 编译器
【从零开始的嵌入式生活】必备基础知识1——数据的表示和程序编译调试
【从零开始的嵌入式生活】必备基础知识1——数据的表示和程序编译调试
【从零开始的嵌入式生活】必备基础知识1——数据的表示和程序编译调试
|
Ubuntu Linux 数据安全/隐私保护
【从零开始的嵌入式生活】必备基础知识,从环境安装开始(2)
【从零开始的嵌入式生活】必备基础知识,从环境安装开始(2)
【从零开始的嵌入式生活】必备基础知识,从环境安装开始(2)