STM32手写超频到128M函数

今天学习了野火的STM32教程学会了如何设置STM32的时钟频率,步骤比较详细,也很容易理解,就是视频教程不能跳着看,只能一节节的看,不然会知识不连贯,造成有些知识不理解,连续着看还是没有什么难度的。

我把怎么设置系统时钟的步骤总结一下吧:

第一步:将RCC的所有寄存器都恢复成默认值

第二步:使能HSE

第三步:判断HSE启动是否成功

        HSE启动成功的话:

        {

                1:使能预取缓冲区

                2:预取缓冲区等待周期2

                3:设置AHB的时钟 1分频   72M

                4:APB1的时钟设置 2分频 36M

                5:APB2的时钟设置 1分频 72M

                6:锁相环时钟配置:来源HSE1分频,倍频因子9倍(也可以改成自己想要的倍数,超频就改这里)

                7:使能锁相环

                8:等待锁相环稳定

                9:系统时钟选择锁相环时钟

                10:等待系统时钟切换成功

        }

        HSE启动不成功:

        {

                写不成功的代码。

        }

*******************************************************************************************************************

按照上面的步骤操作后,系统时钟就按照我们的标准来设置了。其实这个操作没有什么太大的必要性,因为系统会自动为我们配置好的,研究这个过程是为了更深一步的了解STM32的工作步骤。能叫自己的脑子里的思路更加清晰。

下面我就把源码发出来,自己研究吧!

RCC.c文件:

#include "RCC.h"                  // Device header

/*HSE时钟设置函数(传入倍频因子)*/
void HSE_SetSysClk(uint32_t RCC_PLLMul_x)
{
	ErrorStatus HSEStatus;  //定义一个HSE启动成功与否的标志位变量
	
	RCC_DeInit();  //RCC所有寄存器恢复成默认值
	
	RCC_HSEConfig(RCC_HSE_ON);//使能HSE

	HSEStatus = RCC_WaitForHSEStartUp();//HSE启动是否成功的返回值
	
	if(HSEStatus == SUCCESS)
	{
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//使能预取缓冲区 在《STM32F10xxx闪存编程》的3.1节 的FLASH_ACR 的 位4:PRFTBE 取值1 :启用预取缓冲区
		FLASH_SetLatency(FLASH_Latency_2);  //预取缓冲区等待周期2
		
		RCC_HCLKConfig(RCC_SYSCLK_Div1);   // AHB的时钟设置 1分频
		RCC_PCLK1Config(RCC_HCLK_Div2);   // APB1的时钟设置 2分频
		RCC_PCLK2Config(RCC_HCLK_Div1);   // APB2的时钟设置 1分频
		
		RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_x); //锁相环配置 时钟来源与倍频因子  16倍频  8*16=128M
		RCC_PLLCmd(ENABLE); //使能锁相环
		
		//等待锁相环稳定
		// RCC_GetFlagStatus(uint8_t RCC_FLAG);  //RCC的标志位
		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) != SET);
		
		//选择锁相环时钟
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  //时钟源选择
		
		while( RCC_GetSYSCLKSource() != 0x08 );  //如果不等于0x08就是没有切换成功就while等待
	}
	else
	{
		/* 如果HSE启动失败,用户可以在这里添加处理错误的代码 */
	}
	
}

//配置PA8为时钟输出
void MCO_GPIO_Config(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
}

RCC.h文件:

#ifndef __RCC_H
#define __RCC_H

#include "stm32f10x.h"                  // Device header


void HSE_SetSysClk(uint32_t RCC_PLLMul_x);


void MCO_GPIO_Config(void);



#endif  /*__RCC_H*/

main.c文件:

#include "stm32f10x.h"                  // Device header
#include "led.h"  
#include "RCC.h" 

void Delay(uint32_t val)
{
	while(val)
	{
		val--;
	}
}

int main(void)
{
	LED_Init();
	//HSE_SetSysClk(RCC_PLLMul_16);  //设置时钟频率为16倍频  8*16=128M  超频
	
	MCO_GPIO_Config();
	RCC_MCOConfig(RCC_MCO_PLLCLK_Div2);//MCO输出A8口输出锁相环时钟2分频,用示波器可以测量A8口的频率
	
	while(1)
	{
		LED(ON);
		Delay(0xfffff);
		LED(OFF);
		Delay(0xfffff);
	}
}

由于我没有示波器,所以就只能用个led灯看看闪烁的速度来判断是不是超频了,所以还有个led的模块:

led.c文件:

#include "led.h"                  // Device header


void LED_Init(void)
{
	RCC_APB2PeriphClockCmd(GPIO_CLK, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_PIN;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOx, &GPIO_InitStruct);
	
}


led.h文件:

#ifndef __LED_H
#define __LED_H

#include "stm32f10x.h"                  // Device header

#define GPIOx                GPIOB
#define GPIO_PIN             GPIO_Pin_0
#define GPIO_CLK             RCC_APB2Periph_GPIOB

#define ON                   1
#define OFF                  0

#define LED(x)               if(x)\
								GPIO_ResetBits(GPIOx, GPIO_PIN);\
							 else \
								 GPIO_SetBits(GPIOx, GPIO_PIN);

void LED_Init(void);


#endif

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

闲置商标转让出现这些状态时注意!

近日以前做转让的一个朋友的商标转让证明下来,正好是2个半月,普推知产老杨发现这个时间也太快,以前差不多四个月左右,有些朋友需要购买闲置商标,3个月内所有权就变成自己的。 在购买闲置商标时要注意有一些细节&#x…

创新实训2024.05.26日志:服务端接口实现——用户开启多个会话

1. 概念图 类似于Kimi,文心一言,chatGPT等市面上主流的大模型,我们的大模型也支持同一个用户的多个会话,并且提供支持联系上下文给出解答的能力。 2. 基于会话的对话 在langchain chatchat这个对langchain框架进行二次封装的第三…

GPT-4 与 GPT-4 Turbo有什么区别?

在不断发展的人工智能和自然语言处理领域,OpenAI 的 GPT 系列一直走在最前沿,彻底改变了机器理解和生成类人文本的方式。每一次迭代,进步都会突破可能性的界限。 最新的条目 GPT-4 和 GPT-4 Turbo 引起了人工智能社区内外的极大兴趣和争论。…

推荐13款常用的Vscode插件,提高前端日常开发效率

1. Live Server Live Server 插件是一个用于前端开发的扩展,它的主要作用是提供一个本地开发服务器,以便实时预览和调试网页应用程序。其最大特点在于热重载,即开发者可实时预览代码效果。 因为Live Server 允许开发者在浏览器中实时预览您正…

【C++】详解深浅拷贝的概念及其区别

🦄个人主页:修修修也 🎏所属专栏:C ⚙️操作环境:Visual Studio 2022 目录 什么是拷贝 什么是浅拷贝 什么是深拷贝 深浅拷贝的区别及使用场景 结语 什么是拷贝 在C编程中,拷贝是一个非常重要的概念,对于理解和使用类和对象起…

浅谈JMeter体系结构

JMeter体系结构详解 JMeter是一款功能强大的开源性能测试工具,广泛应用于Web应用、数据库、FTP服务器等多种场景下的负载和压力测试。其灵活的体系结构设计使得测试计划的创建、执行与结果分析变得高效而直观。本文将深入解析JMeter的三维空间体系结构,…

C++实现定长内存池

项目介绍 本项目实现的是一个高并发的内存池,它的原型是Google的一个开源项目tcmalloc,tcmalloc全称Thread-Caching Malloc,即线程缓存的malloc,实现了高效的多线程内存管理,用于替换系统的内存分配相关函数malloc和fr…

基于UDP的TFTP文件传输-实现网盘上传下载功能

数据传输模式&#xff1a;octet(二进制模式) #include<head.h> char* down_up_request(char* buf,char* filename,int rw,int sockfd,struct sockaddr_in in); int download(struct sockaddr_in in,char* filename,char* buf,int sockfd); int upload(struct sockaddr_in…

数据结构(七)查找

2024年5月26日一稿(王道P291) 7.1 查找的基本概念 7.2 顺序查找和折半查找 7.2.1 顺序查找 7.2.2 折半查找 7.2.3 分块查找 7.3 树形查找 7.3.1 二叉排序树(BST)

FFmpeg+QT播放器实战1---UI页面的设计

1、播放器整体布局的设计 该部分使用QT的UI工具&#xff0c;进行整体页面设置&#xff0c;如下图1所示&#xff1a; 2、控制布局的设计 创建ctrBar的UI页面并进行页面布局设置&#xff0c;如下图2所示&#xff1a; 将图1中ctrBarWind对象提升为ctrBar类(该界面替代原先的控…

Modbus TCP转Profinet网关测试配置案例

本案例采用XD-ETHPN20网关做为Modbus TCP通信协议设备与Profinet通信协议设备连接的桥梁。Modbus TCP是一种基于TCP/IP协议的工业通信协议&#xff0c;而Profinet则是用于太网通信的协议。Modbus TCP转Profinet网关可实现这两种不同协议之间的数据交换和传输&#xff0c;极大地…

实在智能TARS:面向垂直领域自主训练的类GPT大模型

一、写在前面 在数字化浪潮的推动下&#xff0c;企业正寻求突破传统生产力的局限&#xff0c;以实现更高效、更智能的运营模式。实在智能科技有限公司的TARS产品&#xff0c;以其前沿的人工智能技术&#xff0c;为企业注入了新质生产力&#xff0c;引领着智能化转型的新潮流。…

数据结构(三)循环链表

文章目录 一、循环链表&#xff08;一&#xff09;概念&#xff08;二&#xff09;示意图&#xff08;三&#xff09;操作1. 创建循环链表&#xff08;1&#xff09;函数声明&#xff08;2&#xff09;注意点&#xff08;3&#xff09;代码实现 2. 插入&#xff08;头插&#x…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(十二)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 我们&#xff0c;继续讲一…

【Django项目】 音乐网站spotify复刻

代码&#xff1a;https://github.com/tomitokko/spotify-clone 注&#xff1a;该项目不是自己提供mp3文件&#xff0c;而是使用spotify 的api接口获取。

用实践结果告诉你为啥说 CloudFlare 是赛博菩萨?

最近几天明月都没有更新博客了,主要是接了几个 CloudFlare 代维配置的活儿,有需要加速优化的,有需要排除疑难故障的,有需要提高防御攻击能力的甚至还有纯粹为了体验“打不死”装逼需要的。总之,各种各样的需求,五花八门的,好在 CloudFlare 都能一一满足,最主要的是这些…

C++入门:从C语言到C++的过渡(3)

目录 1.内联函数 1.1内联函数的定义 1.2特性 2.auto关键字 2.1auto的简介 2.2注意事项 3.范围for 4.nullptr空指针 1.内联函数 在C语言中&#xff0c;无论使用宏常量还是宏函数都容易出错&#xff0c;而且无法调试。而C为了弥补这一缺陷&#xff0c;引入了内联函数的概…

【NumPy】关于numpy.clip()函数,看这一篇文章就够了

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

前端手写文件上传;使用input实现文件拖动上传

使用input实现文件拖动上传 vue2代码&#xff1a; <template><div><div class"drop-area" dragenter"highlight" dragover"highlight" dragleave"unhighlight" drop"handleDrop"click"handleClick&quo…

嵌入式C语言中结构体使用详解

各位开发者大家好,今天给大家分享一下,嵌入式C语言中结构体的使用方法。 第一个:内存对齐 内存对齐是指一个数据类型在内存中存放时,对其地址的要求。简单来说内存对齐就是使得其内存地址是该类型大小的整数倍,例如 double 类型的变量,其内存地址需要是8的倍数(double大…