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

相关推荐
UTP协同自动化测试4 小时前
物联网模组测试难点 |APP指令下发+UART 响应+GPIO 电平变化,如何一次性验证?
功能测试·嵌入式硬件·物联网·模块测试
yoyobravery5 小时前
蓝桥杯第15届单片机满分
单片机·职场和发展·蓝桥杯
4caf17 小时前
作业2:6位数码管静态显示
嵌入式硬件·51单片机
不做无法实现的梦~7 小时前
STM32解析PPM协议
stm32·单片机·嵌入式硬件
czhaii8 小时前
基于Arm Cortex-M7内核GD32H7
单片机·嵌入式硬件
番茄灭世神8 小时前
MCU开发常见软件BUG总结(持续更新)
c语言·stm32·单片机·嵌入式·gd32
wanghanjiett8 小时前
双轮平衡车建模及控制 2 PID控制原理与调参
嵌入式硬件·控制算法
EVERSPIN9 小时前
SQPI PSRAM为单片机提供RAM扩展方案
单片机·嵌入式硬件·psram·sqpi psram
Ar-Sr-Na9 小时前
STM32现代化AI开发指南-VSCode环境配置(macOS)
c语言·人工智能·vscode·stm32·嵌入式硬件·硬件工程
进击的小头9 小时前
第6篇:嵌入式芯片算力核心来源:多级流水线架构与指令并行机制详解
单片机·嵌入式硬件·架构