嵌入式系统中STM32时钟系统详解

news2024/12/23 13:21:49
1. STM32的时钟源主要有:
  • 内部时钟

  • 外部时钟

  • 锁相环倍频输出时钟

1.1 详细介绍

HSI(内部高速时钟)

  • 它是RC振荡器,频率可以达到8MHZ,可作为系统时钟和PLL锁相环的输入

HSE(外部高速时钟)

  • 接入晶振范围是4-16MHZ,可作为系统时钟和PLL锁相环的输入,还可以经过128分频之后输入给RTC。

LSI(内部低速时钟)

  • 它是RC振荡器,频率大概为40KHZ,供给独立看门狗或者RTC,并且独立看门口只能依靠LSI作为时钟源

LSE(外部低速时钟)

  • 通常外接32.768MHZ晶振提供给RTC

PLL(锁相环)

  • 用来倍频输出。因为开发板外部晶振只有8MHZ,而STM32最大工作频率是72MHZ。他可以通过HSI输入,HSE输入或两分频输入,通过PLL倍频(2-16),倍频之后输入给系统时钟。

MCO(时钟输出管脚)

  • 通常对应STM32 PA8,它可以选择一个时钟信号输出,给外部的系统提供时钟源

2. 标准库的时钟配置

2.1 stm32启动文件

首先打开startup_stm32f10x_hd.s,该文件为stm32的启动文件,在该文件内会发现有这么一块用汇编写的代码。

      Reset_Handler   PROC
            EXPORT  Reset_Handler    [WEAK]
            IMPORT  __main
            IMPORT  SystemInit
            LDR     R0, =SystemInit
            BLX     R0               
            LDR     R0, =__main
            BX      R0
            ENDP

通过这段汇编代码可以看出,程序在执行main函数之前,会先执行SystemInit函数。

2.2 SystemInit函数详解
void SystemInit (void)
{
  /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;

  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
  RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
  RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */   

  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;

  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;

  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
  RCC->CFGR &= (uint32_t)0xFF80FFFF;

#ifdef STM32F10X_CL
  /* Reset PLL2ON and PLL3ON bits */
  RCC->CR &= (uint32_t)0xEBFFFFFF;

  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x00FF0000;

  /* Reset CFGR2 register */
  RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x009F0000;

  /* Reset CFGR2 register */
  RCC->CFGR2 = 0x00000000;      
#else
  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */

#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
  #ifdef DATA_IN_ExtSRAM
    SystemInit_ExtMemCtl(); 
  #endif /* DATA_IN_ExtSRAM */
#endif 

  /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
  /* Configure the Flash Latency cycles and enable prefetch buffer */
  SetSysClock();

#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif 
}
打开内部8M时钟
RCC->CR |= (uint32_t)0x00000001

通过查看寄存器手册可知,这段代码为打开内部8M时钟。

设置时钟配置寄存器
#ifndef STM32F10X_CL
  RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
  RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */   

对应寄存器说明可查看《STM32中文参考手册_V10》的6.3.2 时钟配置寄存器(RCC_CFGR)章节。

后续代码,有兴趣可根据《STM32中文参考手册_V10》手册,查看代码具体作用。

2.3 SetSysClock()函数详解
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
  SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
  SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
  SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
  SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
  SetSysClockTo56();  
#elif defined SYSCLK_FREQ_72MHz
  SetSysClockTo72();
#endif
}

system_stm32f10x.c文件中会根据芯片的型号定义对应的宏

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
 #define SYSCLK_FREQ_24MHz  24000000
#else
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz  24000000 */ 
/* #define SYSCLK_FREQ_36MHz  36000000 */
/* #define SYSCLK_FREQ_48MHz  48000000 */
/* #define SYSCLK_FREQ_56MHz  56000000 */
#define SYSCLK_FREQ_72MHz  72000000
#endif

3. 时钟配置函数

3.1 时钟初始化配置函数
void SystemInit(void);
SYSCLK(系统时钟)=72MHZ;
AHB总线时钟(HCLK=SYSCLK)=72MHZ;
APB1总线时钟(PCLK1=SYSCLK/2)=36MHZ;
APB2总线时钟(PCLK1=SYSCLK/1)=72MHZ;
PLL主时钟=72MHZ;
3.2 外设时钟使能配置函数
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
3.3 时钟源使能函数
void RCC_HSICmd(FunctionalState NewState);
void RCC_LSICmd(FunctionalState NewState);
void RCC_PLLCmd(FunctionalState NewState);
void RCC_RTCCLKCmd(FunctionalState NewState);
3.4 时钟源和倍频因子配置函数
void RCC_HSEConfig(uint32_t RCC_HSE);
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
void RCC_PCLK1Config(uint32_t RCC_HCLK);
void RCC_PCLK2Config(uint32_t RCC_HCLK);
3.5 外设时钟复位函数
void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
3.6 自定义系统时钟
void RCC_HSE_Config(u32 div,u32 pllm)
{
    RCC_DeInit();
    RCC_HSEConfig(RCC_HSE_ON);
    if(RCC_WaitForHSEStartUp()==SUCCESS)
    {   
        RCC_HCLKConfig(RCC_SYSCLK_Div1);
        RCC_PCLK1Config(RCC_HCLK_Div2);
        RCC_PCLK2Config(RCC_HCLK_Div1);
        RCC_PLLConfig(div,pllm);
        RCC_PLLCmd(ENABLE);     
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK)
    while(RCC_GetSCLKSource()!=0x08);

    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/713752.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构--线性表(顺序表、单链表、双链表、循环链表、静态链表)

前言 学习所记录,如果能对你有帮助,那就泰裤辣。 目录 1.线性表概念 定义 基本操作 2.顺序表 定义 顺序表的实现--静态分配 动态分配 顺序表的特点 顺序表的插入和删除 顺序表的查找 按位查找 按值查找 3.单链表 定义 单链表的初始化 不带…

112.(cesium篇)cesium地球自转+文字上下滚动

地图之家总目录(订阅之前必须详细了解该博客) 地图之家:cesium+leaflet+echart+地图数据+地图工具等相关内容的介绍 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 112.(cesium篇)cesium地球自转+文字上下滚动 下面献上完整代码…

Kubernetes(k8s)集群搭建,完整无坑,不需要科学上网~

文章目录 写在前面一、准备三个centos7虚拟机1、创建Vagrantfile2、启动三台虚拟机3、配置centos7支持ssh登录(所有机器)4、修改 linux 的 yum 源(所有机器)5、更新并安装依赖(所有机器)6、安装docker&…

SPI硬件实现-GD32

SPI硬件实现-GD32 #include "w25qxx_spi.h"void w25qxx_init(void){// 使能外设时钟w25qxx_rcu_init();// IO口进行配置,使之复用为SPI0, PA4\PA5\PA6\PA7,NSS\SCK\MISO\MOSIw25qxx_io_init();// SPI0初始化w25qxx_spi_init();spi_enable(SPI0); }// 使能外设时钟…

HTTP/HTTPS 简介||HTTP 消息结构

HTTP/HTTPS 简介 HTTP 协议是 Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网( WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。 HTTP 是一个基于 TCP/IP 通信协议来传递数据&a…

〖动态规划60题〗泰波纳契数列模型

文章目录 1.第N个泰波那契数(简单)解题流程1. 状态表示2. 状态转移方程3. 初始化dp表4. 填表顺序5. 返回值 代码编写 2.三步问题解题流程1. 状态表示2. 状态转移方程3. 初始化dp表4. 填表顺序5. 返回值 代码编写 3.使用最小花费爬楼梯解题流程1. 状态表示…

Redis高可用——主从复制

redis的主从复制 一、Redis 主从复制1.主从复制的作用:2.主从复制流程: 二、搭建Redis 主从复制1.安装 Redis①.环境准备②.修改内核参数③.安装redis④.创建redis工作目录⑤.环境变量⑥.定义systemd服务管理脚本 2.修改 Redis 配置文件(Mast…

阅读源码技巧

目录 搭建 Demo方法论之关注调用栈方法论之死盯日志方法论之查看被调用的地方探索答案作业是的,正如标题描述的这样,我试图通过这篇文章,教会你如何阅读源码。 事情大概是这样的,前段时间,我收到了一个读者发来的类似于这样的示例代码: 他说他知道这三个案例的回滚情况是…

详解TCP

目录 1.TCP概论 1.1.什么是TCP 1.2.TCP连接的建立过程 1.3.TCP的传输过程 1.4.TCP连接的释放过程 2.JAVA中的TCP 3.TCP带来的一些性能问题 1.TCP概论 1.1.什么是TCP 为了保证所有设备能相互通信,从而建立了一张互联互通的计算机网络,在这张大网…

使用java.lang.Record类删除样板代码

样板是一个源自钢铁制造业的术语,其中形成模具以铸造类似的物体。在编程世界中,样板代码是代码的一部分,项目里面使用的地方很多,但是通常创建完成之后就很少或者就不会更改了。在Java中,不可变的数据载体类用于与数据…

SpringBoot第13讲:SpringBoot接口如何参数校验国际化

SpringBoot第13讲:SpringBoot接口 - 如何参数校验国际化 本文是SpringBoot第13讲,上文我们学习了如何对SpringBoot接口进行参数校验,但是如果需要有国际化的信息(比如返回校验结果有中英文),应该如何优雅处…

【C++】vector介绍及使用

🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。 🚁 个人主页:不 良 🔥 系列专栏:🛸C 🛹Linux 📕 学习格言:博观而约取&#xff0…

【智能座舱系列| 域控制器】——座舱域控制器

传统多芯片架构 原来的座舱里面的控制器基本上是分开的,导航主机是一家,液晶仪表是一家,同时还有一个AVM全景一家,还有TBOX等,这里线束连接就非常复杂,而且不同供应商直接的协调调试也非常复杂。 上图是IMX6 的多芯片方案,液晶仪表、中控导航、后排娱乐都使用了IMX6最小…

axure可视化大屏模板200例 •axure模板 大屏可视化 •axure数据可视化原型 •axure可视化组件 •axure

可视化axure原型可视化大屏模板200例,带动画效果,可直接复用 axure可视化大屏模板200例 axure可视化大屏模板200例数据可视化原型可视化组件下载—无极低码 axure模板 大屏可视化axure数据可视化原型axure可视化组件axure原型演示axure绘制界面原型图…

AI日报|哈佛“AI教授”即将上线;首个生成式AI技能专业证书来了;电话推销员很烦?AI帮你“制裁”他

今日值得关注的人工智能新动态: 将GPT-4用在课程设计中 哈佛大学“AI教授”即将上线 微软推出首个生成式AI技能专业证书 纽约州议会:伤害或羞辱他人的deepfake是非法的 阿诺德施瓦辛格:《终结者》中的AI已成现实 AI诊断“老年痴呆”&…

大数据分析案例-基于决策树算法构建信用卡欺诈识别模型

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

数字IC验证的学习路径,新人必备!

优秀的验证工程师,需要掌握的技能有很多,兼备硬件和软件,可以说是更加触类旁通。所以还是需要循序渐进,从最基础的内容开始逐步掌握。 文内所有的学习资料,面试题目(文末可全领) 1.数电和veri…

VS2015 修复失败

Repair/Modify operation did not finish successfully. “Setup error – repair/modify operation did not finish successfully.” message shown when starting Visual Studio 2015 Problem: When starting Visual Studio 2015, the following message is shown “Setu…

企业实施CIS控制

什么是CIS控件 CIS 关键安全控制由互联网安全中心开发,是一套规范性的、优先的网络安全最佳实践和防御措施,可以帮助防止最普遍和最危险的攻击,并支持多框架时代的合规性。 这些可操作的网络防御最佳实践由一组 IT 专家使用从实际攻击及其有…