STM32完全学习——系统时钟设置

news2024/11/20 2:22:48

一、时钟框图的解读

首先我们知道STM32在上电初始化之后使用的是内部的HSI未经过分频直接通过SW供给给系统时钟,由于内部HSI存在较大的误差,因此我们在系统完成上电初始化,之后需要将STM32的时钟切换到外部HSE作为系统时钟,那么我们需要完成下面一些设置完成切换。首先我们需要打开外部HSE的震荡电路然后,等待外部震荡电路就绪后,在切换PLLTPRE为HSE的1分频,在设置PLLSRC为PLLXTPRE过来的时钟。然后设置PLLMUL倍频系数,然后打开PLL开关等待PLL稳定。然后设置APB1总线为2分频,最后切换系统时钟为PLL输出的时钟。

二、相关寄存器

三、编程实现

#ifndef __SYSTEM_H__
#define __SYSTEM_H__

#define uint unsigned int
	
typedef struct rRCC
{
	uint CR;
	uint CFGR;
	uint CIR;
	uint APB2RSTR;
	uint APB1RSTR;
	uint AHBENR;
	uint APB2ENR;
	uint APB1ENR;
	uint BDCR;
	uint CSR;
	uint AHBRSTR;
	uint CFGR2;	
}RCC_TypeDef;

static RCC_TypeDef *RCC = (RCC_TypeDef *)0x40021000;

void set_system_clock(void);

#endif

#include "system.h"

uint HSERDY_FLAG = 0;     //HSE就绪标志
uint PLLRDY_FLAG = 0;     //PLL就绪标志
uint SWRDY_FLAG  = 0;     //时钟切换标志
uint false_time = 0;      //超时时间标志

void set_system_clock(void)
{
	rFLASH_ACR = 0x00000032; //这个用来设置系统时钟于Flash访问时间的比率 根据系统时钟的不同设置的值不同
	RCC->CR &= (~(0x01 << 16));      //将HSEON这位清零
	RCC->CR |= (0x01 << 16);         //开启外部HSE振荡器电路
	
	
	do                               //判断外部HSE电路是否就绪
	{
		HSERDY_FLAG = ((RCC->CR) & (0x01 << 17));
		false_time++;
	}while((false_time < 0x00ffffff) && (HSERDY_FLAG == 0));
	false_time = 0;
	if (HSERDY_FLAG != 0)            //如果外部振荡器电路就绪才会执行
	{ 
		RCC->CFGR &= (~((0x01 << 17) | (0x01 << 16) | (0x0f << 18)));  //设置PLL倍频系数为9倍频
		RCC->CFGR |= ((0x01 << 16) | (0x0 << 17) | (0x07 << 18));  //设置PLL时钟来源为PREDIV1 并且设置PLLXTPRE不对输入的时钟分频
		RCC->CR &= (~(0x01 << 24));       //使能PLL时钟
		RCC->CR |= (0x01 << 24);
		do 
		{
			PLLRDY_FLAG = ((RCC->CR) & (0x01 << 25));
			false_time++;
		}while((false_time < 0x00ffffff) && (PLLRDY_FLAG == 0));  //等待PLL时钟就绪
		false_time = 0;
		if (((RCC->CR) & (0x01 << 25)) != 0)
		{	
			RCC->CFGR &= (~((0x01 << 22) | (0x07 << 8)));  
			RCC->CFGR |= ((0x0 << 22) | (0x04 << 8));     //全速USB OTG配置为PLL输出2分频 APB1总线2分频 PLL输出作为系统时钟
			RCC->CFGR &= ~(0x03 << 0); 
			RCC->CFGR |= (0x02);    //切换系统时钟为PLL输出时钟
			do
			{
				SWRDY_FLAG = ((RCC->CFGR) & (0x03 << 2));
		        false_time++;	
			}while((false_time < 0x00ffffff) && ((SWRDY_FLAG) == 0));
			if (((RCC->CFGR) & (0x03 << 2)) != 0)  //判断时钟是否切换成功
			{
				
			}
			else
			{
				while(1);
			}
		}
	}
	else
	{
		while(1);
	}
}


上面的代码一个是.h文件另一个是.c文件,但是当我们运行上面的代码时我发现了一个问题,当我们将时钟切换到PLL输出作为系统时钟时,系统就不运行了。就死机了。这是为什么呢,通过翻看数据手册发现,系统时钟和内部flah有一些关系,我们来看flash的寄存器就可以发现。

我们来看bit0-2发现,当复位时默认是000,因此系统时钟必须在0到24MHz之间,这时候我们使用的是内部的HSI时钟,时钟只有8MHz,因此这个时候系统是可以正常运行的,但是当我们将时钟切换到外部HSE时,由于我们做了一系列的倍频,因此这个时候系统时钟到了72MHz,因此我们呢这里需要将这个寄存器的值也设置为010,系统就可以正常运行了。

#define FLASH_ACR  0x40022000
#define rFLASH_ACR *((uint *)FLASH_ACR)

void set_system_clock(void)
{
	rFLASH_ACR = 0x00000032;     //这个用来设置系统时钟于Flash访问时间的比率 根据系统时钟的不同设置的值不同
	
	RCC->CR &= (~(0x01 << 16));      //将HSEON这位清零
	RCC->CR |= (0x01 << 16);         //开启外部HSE振荡器电路
	
	
	do                               //判断外部HSE电路是否就绪
	{
		HSERDY_FLAG = ((RCC->CR) & (0x01 << 17));
		false_time++;
	}while((false_time < 0x00ffffff) && (HSERDY_FLAG == 0));
	false_time = 0;
	if (HSERDY_FLAG != 0)            //如果外部振荡器电路就绪才会执行
	{ 
		RCC->CFGR &= (~((0x01 << 17) | (0x01 << 16) | (0x0f << 18)));  //设置PLL倍频系数为9倍频
		RCC->CFGR |= ((0x01 << 16) | (0x0 << 17) | (0x07 << 18));  //设置PLL时钟来源为PREDIV1 并且设置PLLXTPRE不对输入的时钟分频
		RCC->CR &= (~(0x01 << 24));       //使能PLL时钟
		RCC->CR |= (0x01 << 24);
		do 
		{
			PLLRDY_FLAG = ((RCC->CR) & (0x01 << 25));
			false_time++;
		}while((false_time < 0x00ffffff) && (PLLRDY_FLAG == 0));  //等待PLL时钟就绪
		false_time = 0;
		if (((RCC->CR) & (0x01 << 25)) != 0)
		{	
			RCC->CFGR &= (~((0x01 << 22) | (0x07 << 8)));  
			RCC->CFGR |= ((0x0 << 22) | (0x04 << 8));     //全速USB OTG配置为PLL输出2分频 APB1总线2分频 PLL输出作为系统时钟
			RCC->CFGR &= ~(0x03 << 0);  
			RCC->CFGR |= (0x02); 
			do
			{
				SWRDY_FLAG = ((RCC->CFGR) & (0x03 << 2));
		    false_time++;	
				
			}while((false_time < 0x00ffffff) && ((SWRDY_FLAG) == 0));
			
			if (((RCC->CFGR) & (0x03 << 2)) != 0)
			{
				
			}
			else
			{
				while(1);
			}
		}
	}
	else
	{
		while(1);
	}
}

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

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

相关文章

基于Java Springboot滁州市特产销售系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

H.265流媒体播放器EasyPlayer.js视频流媒体播放器关于直播流播放完毕是否能监听到

EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;无须安装任何插件&#xff0c;起播快、延迟低、兼容性强&#xff0c;使用非常便捷。 EasyPlayer.js播放器不仅支持H.264与H.265视频编码格式&#xff0c;也能支持WebS…

Ubuntu22.04基于ROS2-Humble安装moveit2教程(亲测)

一、安装ROS2-Humble 1、参考&#xff1a;Ubuntu22.04安装ROS2-humble-CSDN博客 2、确保安装完成 source /opt/ros/humble/setup.bash 方法一&#xff1a;二进制安装 sudo apt install ros-humble-moveit* 方法二&#xff1a;安装源码编译 一、卸载二进制安装包 sudo a…

SpringBoot学习记录(三)之多表查询

SpringBoot学习记录&#xff08;三&#xff09;之多表查询 一、多表查询概述1、数据准备2、介绍3、分类 二、内连接三、外连接四、子查询1、标量子查询2、列子查询3、行子查询4、表子查询 三、案例1、准备环境2、需求实现3、&#xff08;附&#xff09;数据准备 一、多表查询概…

Ubuntu 的 ROS 操作系统 turtlebot3 SLAM仿真

引言 SLAM&#xff08;同步定位与地图构建&#xff09;在Gazebo仿真环境中的应用能够模拟真实机器人进行环境建图和导航。通过SLAM仿真&#xff0c;开发者可以在虚拟环境中测试算法&#xff0c;而不必依赖真实硬件&#xff0c;便于调试与优化。 Gazebo提供了多个虚拟环境&…

TCP连接秘籍:三次握手建立连接,四次挥手优雅告别

在数字通信的广阔天地中&#xff0c;TCP协议如同一座稳固的桥梁&#xff0c;连接着网络世界的每一个角落。它不仅确保了数据的可靠传输&#xff0c;还通过精细设计的连接建立与断开机制&#xff0c;展现了其无与伦比的优雅与智慧。TCP的三次握手&#xff0c;犹如初次相遇时的礼…

【惠州大亚湾】之维修戴尔服务器DELLR730XD

1&#xff1a;广东省惠州市大亚湾某游客服务中心来电报修1台DELL PowerEdge R730xd服务器无法正常开机的问题。听该负责描述这台服务器因为服务中心电力切换导致意外关机&#xff0c;来电后发现就无法正常开机了。所以找到我们希望配合维修。 2&#xff1a;该机器由于特别着急…

常见网络厂商设备默认用户名/密码大全

常见网络厂商的默认用户名/密码 01 思科 (Cisco) 设备类型&#xff1a;路由器、交换机、防火墙、无线控制器 默认用户名&#xff1a;cisco 默认密码&#xff1a;cisco 设备类型&#xff1a;网管型交换机 默认用户名&#xff1a;admin 默认密码&#xff1a;admin 02 华…

PH热榜 | 2024-11-18

DevNow 是一个精简的开源技术博客项目模版&#xff0c;支持 Vercel 一键部署&#xff0c;支持评论、搜索等功能&#xff0c;欢迎大家体验。 在线预览 1. Momen 标语&#xff1a;快速搭建你的最小可行产品&#xff0c;然后扩展它&#xff0c;无需任何编程经验。 介绍&#xff…

LoFTR: Detector-Free Local Feature Matching with Transformers—特征点匹配算法系列

LoFTR: Detector-Free Local Feature Matching with Transformers 受到&#xff1a;受到开创性作品 SuperGlue 的启发 摘要总结&#xff1a; 提出了一种局部图像特征匹配的新方法。更为突出说明的是室内场景下的特征点的匹配问题。 不是依次执行图像特征检测、描述和匹配&#…

Percona XtraBackup备份docker版本mysql 5.7

my.cnf配置文件 [client] default_character_setutf8[mysqld] # 数据存储目录&#xff08;必须手动指定&#xff09; datadir/var/lib/mysql/data# 字符集 collation_server utf8_general_ci character_set_server utf8 # 二进制日志 server-id1 log_bin/var/log/mysql/binl…

Windows安装vcpkg教程(VS2022)

内容摘要&#xff1a; 本文详细介绍如何在Windows系统上使用 Git 克隆 vcpkg 仓库来安装vcpkg工具&#xff0c;并链接Visual Studio 2022。 目录 一、关于vcpkg 二、开发环境 三、安装Git 四、使用 Git 克隆 vcpkg 仓库 一、关于vcpkg vcpkg 是一个开源的 C 包管理工具&am…

nodejs入门(1):nodejs的前后端分离

一、引言 我关注nodejs还是从前几年做了的一个电力大数据展示系统开始的&#xff0c;当然&#xff0c;我肯定是很多年的计算机基础的&#xff0c;万变不离其宗。 现在web网站都流行所谓的前后端结构&#xff0c;不知不觉我也开始受到这个影响&#xff0c;以前都是前端直接操作…

智能停车解决方案之停车场室内导航系统(二):核心技术与系统架构构建

hello~这里是维小帮&#xff0c;如有项目需求和技术交流欢迎大家私聊我们&#xff01;点击文章最下方获取智慧停车场方案~撒花&#xff01; 随着城市化进程的加速&#xff0c;停车难问题日益凸显。智能停车系统作为缓解停车压力的有效手段&#xff0c;其核心技术与架构的构建至…

Django5 2024全栈开发指南(三):数据库模型与ORM操作

目录 一、模型的定义二、数据迁移三、数据表关系四、数据表操作4.1 Shell工具4.2 数据新增4.3 数据修改4.4 数据删除4.5 数据查询4.6 多表查询4.7 执行SQL语句4.8 数据库事务 Django 对各种数据库提供了很好的支持&#xff0c;包括 PostgreSQL、MySQL、SQLite 和 Oracle&#x…

中仕公考怎么样?事业编面试不去有影响吗?

事业编考试笔试已经通过&#xff0c;但是面试不去参加会有影响吗&#xff1f; 1. 自动放弃面试资格&#xff1a;未能按时出席事业单位的面试将被视为主动放弃该岗位的竞争机会。 2. 个人信誉问题&#xff1a;面试作为招聘流程的关键步骤&#xff0c;无故缺席可能被解释为诚信…

MySql结合element-plus pagination的分页查询

实现效果如下&#xff1a; 重点&#xff1a;使用mysql查询的limit和offset 原生SQL写法&#xff1a; select c.id as deptid,c.name as department,position,a.name staffname,2024-11 as shijian ,CASE WHEN b.shijian IS NULL THEN no ELSE yes END AS submit from fa_wecom…

学习笔记019——Ubuntu部署tomcat

1、下载Tomcat压缩包。本人下载的版本是&#xff1a;apache-tomcat-8.5.77.tar.gz 2、将压缩包上传到Ubuntu某个目录。 本人存放的目录是 /opt 目录下, 命令解压&#xff1a; ## 解压tomcat压缩包 tar -zxvf apache-tomcat-8.5.77.tar.gz 3、vim打开bin目录的setclasspath…

【JavaSE】(6)抽象类和接口

目录 一、抽象类 1、什么是抽象类 2、抽象类的特点 3、抽象类的作用 4、抽象类示例代码 二、接口 1、什么是接口 2、接口的书写建议 3、接口的特点 4、实现多个接口 5、接口能“忘记类型” 6、接口间的继承 7、接口的应用 7.1、引用类型的比较--Comparable 和 Co…

Git学习教程(更新中)

持续更新完善中… 1 Git简介 1.1 Git是什么&#xff1f; Git是一个开源的分布式版本控制系统&#xff0c;由Linus Torvalds创建&#xff0c;用于有效、高速地处理从小到大的项目版本管理。它能够记录项目文件的变更历史&#xff0c;让多个开发者可以协作开发同一个项目&#…