在STM32F030中使用内部晶振(HSI)并实现延时函数,需按以下步骤操作:
STM32F030默认使用HSI(8MHz)作为时钟源,但需显式配置时钟树以稳定系统。
SystemInit() 中配置)#include "stm32f0xx.h"
void SystemClock_HSI_Init(void) {
// 1. 使能HSI
RCC->CR |= RCC_CR_HSION;
while ((RCC->CR & RCC_CR_HSIRDY) == 0); // 等待HSI就绪
// 2. 配置时钟分频(可选)
RCC->CFGR |= RCC_CFGR_HPRE_DIV1; // AHB分频 = 1(8MHz)
RCC->CFGR |= RCC_CFGR_PPRE_DIV1; // APB分频 = 1(8MHz)
// 3. 选择HSI作为系统时钟源
RCC->CFGR &= ~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_HSI;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI); // 等待切换完成
}SysTick是Cortex-M内核的24位倒计时定时器,适合实现精确延时。
配置SysTick时钟源
STM32F030的SysTick时钟源为 HCLK/8(即 8MHz/8 = 1MHz,每个计数周期=1µs)。
初始化SysTick
void SysTick_Init(void) {
SysTick->LOAD = 0xFFFFFF; // 设置重载值为最大值(24位)
SysTick->VAL = 0; // 清空当前计数值
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | // 使用内核时钟
SysTick_CTRL_ENABLE_Msk; // 使能SysTick
}实现微秒和毫秒延时函数
void Delay_us(uint32_t us) {
SysTick->LOAD = us * 1; // 1MHz时钟,1us = 1个周期
SysTick->VAL = 0;
while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
}
void Delay_ms(uint32_t ms) {
while (ms--) {
Delay_us(1000);
}
}适用于对精度要求不高的场景,但需注意编译器优化问题。
void Delay_Loop(uint32_t count) {
volatile uint32_t i; // volatile防止编译器优化
for (i = 0; i < count; i++);
}
// 通过实验校准延时时间(示例基于8MHz HSI)
void Delay_ms(uint32_t ms) {
Delay_Loop(ms * 800); // 近似值,需根据实际测试调整
}在调试时,可通过以下代码确认当前系统时钟源和频率:
if ((RCC->CFGR & RCC_CFGR_SWS) == RCC_CFGR_SWS_HSI) {
// 当前系统时钟为HSI(8MHz)
}HSI精度
HSI的典型精度为±1%,若需更高精度,可使用HSI校准功能(参考 RCC->CR 中的 HSICAL 和 HSITRIM)。
优化问题
使用循环延时时,确保变量声明为 volatile,或关闭编译器优化(-O0)。
时钟分频
若修改了AHB/APB分频,需重新计算SysTick和延时参数。
通过上述步骤,即可在STM32F030中正确配置内部晶振并实现高精度延时。建议优先使用SysTick定时器以获得更稳定的性能。
举报
更多回帖