一、修改主频
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 进入休眠,直到有事件发生才唤醒
代码执行流程
- 初始化 OLED、串口
- 循环等待串口接收数据
- 收到数据后:
- 回发给电脑(串口回环)
- 在 OLED 上显示十六进制值
- 第二行闪烁显示
Running表示程序正常运行 - 最后用
__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();
}
}
一、程序执行流程
- 初始化 OLED 显示屏
- 初始化计数传感器(配置为外部中断引脚)
- 开启 PWR 电源时钟,为进入低功耗模式做准备
- 进入主循环,实时显示传感器计数值
- 运行状态闪烁提示后,进入 STOP 停止模式深度休眠
- 计数传感器触发外部中断,唤醒单片机
- 调用 SystemInit () 恢复系统时钟
- 回到主循环,继续显示计数并再次休眠
二、核心知识点
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();
}
}
一、程序执行流程
- 备份域复位,初始化 RTC 时钟
- 初始化 OLED 显示屏
- 开启 PWR 电源时钟
- 使能 WKUP 唤醒引脚,设置 10 秒后 RTC 闹钟
- 循环显示 RTC 计数值、闹钟值、闹钟标志
- 状态提示后,清屏并进入 STANDBY 待机模式
- 唤醒源触发(RTC 闹钟 / WKUP 引脚),单片机复位重启
- 程序从头开始执行,重新初始化并运行
二、核心知识点
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
