STM32(二十五)——修改主频、睡眠模式、停机模式、待机模式

一、修改主频

MCMSIS 系统时钟配置文件

对外暴露的核心接口
接口 类型 作用
SystemInit() 函数 复位后、进入 main() 前,由启动文件自动调用,完成系统时钟源、PLL 倍频、AHB/APBx 预分频器及 Flash 等待周期的配置
SystemCoreClock 全局变量 保存当前内核时钟(HCLK)频率值,用户可用于配置 SysTick 定时器或其他外设时钟
SystemCoreClockUpdate() 函数 当程序运行中动态修改内核时钟后,必须调用此函数来更新 SystemCoreClock 变量
关键使用提示
  • 调用时机SystemInit()startup_stm32f10x_xx.s 启动文件自动执行,无需用户在 main() 中手动调用
  • 时钟更新 :若在应用程序中动态修改了时钟配置(如切换 PLL 倍频),必须调用 SystemCoreClockUpdate() 来同步变量,否则基于 SystemCoreClock 的延时、定时器配置会出现偏差。
  • 兼容性:该文件是 STM32F1 系列标准 CMSIS 库的一部分,与 Keil MDK、IAR 等开发环境兼容。

更改主频

这个是已经修改过的了,原本是72MHZ,现在修改为36MHZ。

条件编译分支

  • 当芯片为 超值型(VL 系列)STM32F10X_LD_VL / MD_VL / HD_VL
    • 仅可启用 SYSCLK_FREQ_24MHz(24 MHz)、SYSCLK_FREQ_HSE(8MHz)
  • 其他型号(非 VL 系列):
    • 当前启用 SYSCLK_FREQ_36MHz(36 MHz)
    • 24/48/56/72 MHz 选项被注释,处于未启用状态
修改文件属性

如果文件上有个小钥匙的话,可以到文件存储地址中更改文件属性。

可右击文件,点击第五个Open Containing Folder,

右击文件,点击属性

取消只读

二、睡眠模式+串口收发

复制代码
uint8_t RxData;

int main(void)
{
	OLED_Init();
	OLED_ShowString(1, 1, "RxData:");
	
	Serial_Init();
	
	while (1)
	{
		if (Serial_GetRxFlag() == 1)
		{
			RxData = Serial_GetRxData();
			Serial_SendByte(RxData);
			OLED_ShowHexNum(1, 8, RxData, 2);
		}
		OLED_ShowString(2,1,"Running");
		Delay_ms(100);
		OLED_ShowString(2,1,"       ");
		Delay_ms(100);
		
		__WFI();
		
		
	}
	
}

__WFI():让 CPU 进入休眠,直到有中断来才唤醒

__WFE():让 CPU 进入休眠,直到有事件发生才唤醒

代码执行流程

  1. 初始化 OLED、串口
  2. 循环等待串口接收数据
  3. 收到数据后:
    • 回发给电脑(串口回环)
    • 在 OLED 上显示十六进制值
  4. 第二行闪烁显示 Running 表示程序正常运行
  5. 最后用 __WFI() 让单片机休眠等待中断,降低功耗

三、停机模式+对射式红外线传感器计次

复制代码
int main(void)
{
	
	OLED_Init();
	CountSensor_Init();
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	OLED_ShowString(1,1,"Count:");
	
	while(1)
	{
		
		OLED_ShowNum(1,7,CountSensor_Get(),5);
		
		OLED_ShowString(2,1,"Running");
		Delay_ms(100);
		OLED_ShowString(2,1,"       ");
		Delay_ms(100);
		
		PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);
		SystemInit();
	}
	
}

一、程序执行流程

  1. 初始化 OLED 显示屏
  2. 初始化计数传感器(配置为外部中断引脚)
  3. 开启 PWR 电源时钟,为进入低功耗模式做准备
  4. 进入主循环,实时显示传感器计数值
  5. 运行状态闪烁提示后,进入 STOP 停止模式深度休眠
  6. 计数传感器触发外部中断,唤醒单片机
  7. 调用 SystemInit () 恢复系统时钟
  8. 回到主循环,继续显示计数并再次休眠

二、核心知识点

1. STOP 停机模式
  • STM32 深度低功耗模式,功耗达到 μA 级
  • 模式特性:所有时钟停止、内核停止运行
  • 数据保存:寄存器、RAM 数据全部保持,计数值不会丢失
  • 唤醒条件:只能由中断 / 事件唤醒
2. 唤醒方式
  • 本程序唤醒源:计数传感器外部中断
  • 通用规则:STOP 停机模式可通过任一外部中断唤醒
3. 唤醒后必须调用 SystemInit ()
  • 进入 STOP 前:系统时钟为配置频率(如 72MHz)
  • 退出 STOP 后:硬件自动将时钟切换为 HSI 8MHz
  • 不执行该函数后果:时钟错乱,延时、OLED、串口等外设工作异常
4. 开启 PWR 电源时钟
  • 必备操作:RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  • 作用:只有开启该时钟,单片机才能进入 STOP 等低功耗模式
5. 进入 STOP 停机模式函数

PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);

  • PWR_Regulator_ON:稳压器保持开启,唤醒速度更快
  • PWR_STOPEntry_WFI:休眠方式为等待中断唤醒

四、待机模式+实时时钟

复制代码
int main(void)
{
	RCC_BackupResetCmd(ENABLE);
	RCC_BackupResetCmd(DISABLE);
	
	
	OLED_Init();
	MyRTC_Init();
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	OLED_ShowString(1,1,"CNT:");
	OLED_ShowString(2,1,"ALR:");
	OLED_ShowString(3,1,"ALRF:");
	
	PWR_WakeUpPinCmd(ENABLE);
	uint32_t Alarm = RTC_GetCounter() + 10;
	RTC_SetAlarm(Alarm);
	OLED_ShowNum(2,6,Alarm,10);
	
	while(1)
	{
		OLED_ShowNum(1,6,RTC_GetCounter(),10);
		OLED_ShowNum(3,6,RTC_GetFlagStatus(RTC_FLAG_ALR),1);
		
		OLED_ShowString(4,1,"Running");
		Delay_ms(100);
		OLED_ShowString(4,1,"       ");
		Delay_ms(100);
		
		OLED_ShowString(4,9,"STANDBY");
		Delay_ms(1000);
		OLED_ShowString(4,9,"       ");
		Delay_ms(100);
		
		OLED_Clear();
		
		PWR_EnterSTANDBYMode();
	}
	
}

一、程序执行流程

  1. 备份域复位,初始化 RTC 时钟
  2. 初始化 OLED 显示屏
  3. 开启 PWR 电源时钟
  4. 使能 WKUP 唤醒引脚,设置 10 秒后 RTC 闹钟
  5. 循环显示 RTC 计数值、闹钟值、闹钟标志
  6. 状态提示后,清屏并进入 STANDBY 待机模式
  7. 唤醒源触发(RTC 闹钟 / WKUP 引脚),单片机复位重启
  8. 程序从头开始执行,重新初始化并运行

二、核心知识点

1. STANDBY 待机模式
  • STM32 最低功耗模式,功耗接近 0(nA 级)
  • 模式特性:内核、所有时钟、RAM、寄存器全部断电
  • 数据保存:仅备份域(RTC)保持运行,普通数据全部丢失
  • 唤醒条件:唤醒后相当于系统复位,程序从头执行
2. 唤醒方式
  • 本程序唤醒源:RTC 闹钟中断 + WKUP(PA0)引脚上升沿
  • 通用规则:STANDBY 待机模式只能由指定唤醒源唤醒(WKUP 引脚上升沿、RTC 闹钟、复位等)
3. 唤醒后无需调用 SystemInit ()
  • 进入 STANDBY 后,单片机完全断电复位
  • 唤醒后程序从头运行,启动文件会自动执行 SystemInit ()
  • 无需手动调用时钟初始化函数
4. 开启 PWR 电源时钟
  • 必备操作:RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  • 作用:只有开启该时钟,单片机才能进入 STANDBY 低功耗模式
5. 进入 STANDBY 待机模式函数

PWR_EnterSTANDBYMode();

  • 无参数,直接进入最深低功耗模式
  • 进入后,内核停止,外设断电,仅 RTC 和唤醒电路保持工作

注这里的RTC的晶振使用的外部的LSE,如果不起振,可切换为内部晶振LSI

相关推荐
李永奉2 小时前
中科蓝讯SDK开发-BT893x 面条耳机连接vivo手机后连接APP端,最后手机端设置页面手动断开蓝牙连接,此时耳机端假断开
c语言·开发语言·嵌入式硬件·物联网·智能手机·电脑
大爱编程♡2 小时前
STM32-DMA
stm32·单片机·嵌入式硬件
云泽8083 小时前
STM32 USART 详解(三):硬件架构、内部寄存器与物理层收发原理
stm32·嵌入式硬件·硬件架构
天空'之城3 小时前
单片机基础核心知识点汇总(三十三)
数据库·单片机·嵌入式硬件
数字新视界5 小时前
机房动环监控的智能化管理与安全提升探索
嵌入式硬件·物联网·数据中心·数据中心基础设施管理·dcim管理系统
@嵌入式扫地僧6 小时前
TFLite Micro STM32/ESP32 开箱即用推理骨架 + INT8 量化脚本实战:零调试跑通端侧 AI 推理完整步骤
人工智能·嵌入式硬件·tinyml·端侧ai·tflite micro
自小吃多6 小时前
高云FPGA ModelSim中的仿真
笔记·嵌入式硬件·fpga开发
单片机仿真设计7 小时前
基于 STM32 的家庭环境监测与火灾报警灭火系统(Proteus 仿真)
stm32·单片机·嵌入式硬件·proteus·毕设
深圳市恒锐丰科技杨生7 小时前
EG4321 锂电池 CC‑CV 充电管理控制器|屹晶 EGmicro
嵌入式硬件·硬件工程
辰域电子7 小时前
STM32项目开源:智能万年历/智能闹钟设计(代码+原理图+仿真)
stm32·单片机·嵌入式硬件·开源·proteus