基于STM32的Proteus仿真32单片机,实现了测量正弦波、方波、正弦波和锯齿波等波形频率...
最终效果:输入10kHz方波显示10001Hz,50Hz正弦波显示49.98Hz,误差都在指标内。核心就三板斧:定时器、输入捕获、数学计算,实测方波正弦波都能测,误差稳稳压在1%以内。每次捕获到上升沿就记录时间差,这个period变量保存的就是信号周期(单位μs)。使用 Proteus 仿真32单片机,实现了可以测量正弦波、方波、正弦波和锯齿波等波形频率的 频率计,测量误差在1%以内。使用 Pro
基于stm32简易测频计 有报告 使用 Proteus 仿真32单片机,实现了可以测量正弦波、方波、正弦波和锯齿波等波形频率的 频率计,测量误差在1%以内
撸起袖子焊板子这事儿虽然过瘾,但今天咱们玩点省钱的——直接在Proteus里用STM32搞个数字测频计。核心就三板斧:定时器、输入捕获、数学计算,实测方波正弦波都能测,误差稳稳压在1%以内。

测频原理说白了就是数数:一秒钟有多少个波峰波谷。但实际处理时要注意,不同波形触发方式不同。比如方波用边沿触发,正弦波得先整形成方波再说。这里用定时器2的输入捕获功能(TIM2_CH1),搭配GPIOA的PA0引脚作为信号输入口。
// 定时器基础配置
TIM_TimeBaseInitTypeDef TIM_InitStructure;
TIM_InitStructure.TIM_Prescaler = 72-1; // 72MHz/72=1MHz
TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_InitStructure.TIM_Period = 0xFFFF;
TIM_InitStructure.TIM_ClockDivision = 0;
TIM_TimeBaseInit(TIM2, &TIM_InitStructure);
// 输入捕获配置
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
这段配置把定时器时钟降到1MHz(每个计数代表1μs),捕获上升沿触发。Filter参数设为0关闭滤波器,实测发现对于干净的仿真信号够用了,真要是现场环境得加数字滤波。
核心算法在中断服务函数里玩时间差计算:
volatile uint32_t last_capture = 0;
volatile uint32_t period = 0;
void TIM2_IRQHandler(void) {
if(TIM_GetITStatus(TIM2, TIM_IT_CC1) == SET) {
uint16_t current_capture = TIM_GetCapture1(TIM2);
period = current_capture - last_capture;
last_capture = current_capture;
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
}
}
每次捕获到上升沿就记录时间差,这个period变量保存的就是信号周期(单位μs)。注意volatile关键字防止编译器优化掉变量,实测漏了这个会导致计算结果抽风。

基于stm32简易测频计 有报告 使用 Proteus 仿真32单片机,实现了可以测量正弦波、方波、正弦波和锯齿波等波形频率的 频率计,测量误差在1%以内
频率计算简单粗暴:
float get_freq(void) {
if(period == 0) return 0;
return 1000000.0f / period; // 1MHz时钟换算
}
但实际应用中得做异常值处理。测试时发现当信号频率超过500kHz时误差会增大,这时候需要切换测量模式——改测脉宽为测固定时间内的脉冲数。不过对1%误差指标来说,用当前模式在100Hz-100kHz范围内完全hold住。

Proteus里搭电路时,信号源要接施密特触发器整形(哪怕输入是方波)。仿真时试过同时给锯齿波和正弦波,发现占空比变化会影响捕获精度,后来在信号输入端并联104电容搞定。
误差控制的关键点:
- 外部晶振用8MHz并开启PLL倍频到72MHz,比内部时钟稳得多
- 在捕获中断里禁用其他高优先级中断
- 每次测量取5次结果去掉最大最小值再平均
- 信号幅度控制在3V-5V之间(STM32的IO容忍5V)
最终效果:输入10kHz方波显示10001Hz,50Hz正弦波显示49.98Hz,误差都在指标内。整套代码不到200行,吃透了其实比用现成的频率计模块更有成就感。下次准备加上LCD实时显示和自动量程切换,那才是真·电子制作人的浪漫。
更多推荐



所有评论(0)