当前位置: 首页 > news >正文

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);//使能HSEHSEStatus = RCC_WaitForHSEStartUp();//HSE启动是否成功的返回值if(HSEStatus == SUCCESS){FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//使能预取缓冲区 在《STM32F10xxx闪存编程》的3.1节 的FLASH_ACR 的 位4:PRFTBE 取值1 :启用预取缓冲区FLASH_SetLatency(FLASH_Latency_2);  //预取缓冲区等待周期2RCC_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=128MRCC_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 headervoid 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 headervoid 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

相关文章:

  • 嵌入式0基础开始学习 ⅠC语言(7)指针
  • 2024年全国大学生电工数学建模竞赛B题解析 | 数据处理 代码 论文分享
  • Kiwi浏览器 - 支持 Chrome 扩展的安卓浏览器
  • Vue3解决“找不到模块“@/components/xxx.vue”或其相应的类型声明”
  • Docker: exec命令浅析
  • Java核心: 脚本引擎和动态编译
  • 三种路由协议RIP,OSPF和BGP
  • Android Graphics 显示系统 - Android 14(U)编译/运行Surface绘图、多屏同显/异显示例
  • 专为汽车内容打造的智能剪辑解决方案
  • 人工智能万卡 GPU 集群的硬件和网络架构
  • Microsoft VBA Excel 去重小工具
  • 解决go install 网络问题
  • 电子电器架构 - AUTOSAR软件架构介绍
  • 设计原则-
  • docker 命令总结
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • Angular 4.x 动态创建组件
  • Angular 响应式表单之下拉框
  • CentOS 7 修改主机名
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • Github访问慢解决办法
  • JavaScript异步流程控制的前世今生
  • node.js
  • react-native 安卓真机环境搭建
  • SpiderData 2019年2月25日 DApp数据排行榜
  • vue的全局变量和全局拦截请求器
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 06-01 点餐小程序前台界面搭建
  • 阿里云服务器如何修改远程端口?
  • 函数计算新功能-----支持C#函数
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​一些不规范的GTID使用场景
  • #define、const、typedef的差别
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (3)选择元素——(17)练习(Exercises)
  • (el-Date-Picker)操作(不使用 ts):Element-plus 中 DatePicker 组件的使用及输出想要日期格式需求的解决过程
  • (void) (_x == _y)的作用
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (二)springcloud实战之config配置中心
  • (二)WCF的Binding模型
  • (三)elasticsearch 源码之启动流程分析
  • (一)基于IDEA的JAVA基础10
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • **PHP分步表单提交思路(分页表单提交)
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • @RequestParam详解
  • [ linux ] linux 命令英文全称及解释
  • [ 云计算 | AWS ] AI 编程助手新势力 Amazon CodeWhisperer:优势功能及实用技巧
  • [AX]AX2012 SSRS报表Drill through action