基于51单片机的波形发生器系统仿真设计 实现功能: 1、通过按键切换波形。 可输出正弦波/方波...
基于51单片机的波形发生器系统仿真设计 实现功能: 1、通过按键切换波形。 可输出正弦波/方波/三角波/锯齿波/组合波(正弦波+三角波+锯齿波) 2、通过滑动变阻器进行波形幅度调节(0-5V),并通过Adc0809测量幅值大小并显示在数码管上 3、通过按键设置步进值(0、10…90、100Hz)后,可按设定的步进值进行频率(10-2000Hz)调节 4、可调节方波的占空比(±10% / 10%-90%) 包含仿真+源码 仿真软件:Proteus7.8 编程软件:Keil5 编程语言:C语言 PS:频率过高,波形会失真

蹲在实验室折腾波形发生器这事儿,可算是让我把51单片机玩出花了。今天要唠的这个系统,核心就是靠STC89C52带着DAC0832输出各种波形,顺手还能调幅度、改频率、玩占空比。别看Proteus里仿真跑得欢,真调起来分分钟教你做人——特别是频率飚到2000Hz时,那波形扭得跟麻花似的。

先看硬件配置(Proteus里拖元件就跟搭积木似的):
- 主控:STC89C52,老熟人
- 数模转换:DAC0832,直连P0口
- 模数转换:ADC0809接滑动变阻器
- 显示:四位共阳数码管,74HC245驱动
- 输入:矩阵键盘+独立按键
波形生成的核心在定时器中断里蹦跶。上代码!
// 定时器0中断服务
void Timer0() interrupt 1 {
TH0 = (65536 - freq_value)/256; //重载值决定频率
TL0 = (65536 - freq_value)%256;
switch(wave_type){
case 0: output = sin_table[phase]; break; //正弦波查表
case 1: output = phase<128 ? 255 : 0; break; //方波
case 2: output = phase*2; break; //三角波
case 3: output = phase; break; //锯齿波
case 4: output = (sin_table[phase] + phase)/2; //组合波
}
phase = (phase+1)%256; //相位累加
P0 = output; //直通DAC
}
这里用了个256点的正弦波表,其实用公式实时算也行,但51这运算速度...还是查表实在。相位累加器phase每次+1,相当于波形在时间轴上的步进。

基于51单片机的波形发生器系统仿真设计 实现功能: 1、通过按键切换波形。 可输出正弦波/方波/三角波/锯齿波/组合波(正弦波+三角波+锯齿波) 2、通过滑动变阻器进行波形幅度调节(0-5V),并通过Adc0809测量幅值大小并显示在数码管上 3、通过按键设置步进值(0、10…90、100Hz)后,可按设定的步进值进行频率(10-2000Hz)调节 4、可调节方波的占空比(±10% / 10%-90%) 包含仿真+源码 仿真软件:Proteus7.8 编程软件:Keil5 编程语言:C语言 PS:频率过高,波形会失真

调幅度这块有点门道,ADC0809读滑动变阻器数值后得做归一化处理:
void adjust_amplitude(){
uint adc_val = read_ADC();
float ratio = adc_val / 255.0; //0-5V对应0-255
actual_amp = ratio * 5.0;
//数码管显示电压值
display_buffer[0] = (uint)(actual_amp*10)/10;
display_buffer[1] = (uint)(actual_amp*10)%10;
}
注意这里DAC输出是0-5V对应0-255数字量,但实际硬件可能需要加运放做电平调整。

频率步进设置最坑的是防抖处理。长按按键时得做加速度检测,不然调个100Hz能按到怀疑人生:
void key_scan(){
if(key_step_pressed){
delay_ms(20); //防抖
if(key_step_pressed){
step_count++;
if(step_count>10) step_count=10; //长按加速
freq += step_value * (step_count>5 ? 10 : 1);
limit_freq_range();
}
}
}
占空比调节在方波模式下才生效,本质是调整高低电平的时间比。比如50%占空比时,phase<128输出高电平,>128低电平。调整幅度±10%对应着把128这个临界值前后移动:
void set_duty(uint duty_percent){
threshold = 256 * duty_percent / 100;
//方波输出改为
output = (phase < threshold) ? 255 : 0;
}
最后说下波形失真的问题。当频率超过1500Hz时,由于定时器中断响应时间和DAC转换速率限制,波形采样点变得稀疏。这时候要么上更快的单片机,要么上DDS(直接数字频率合成)算法——不过那又是另一个坑了。

源码包里还藏着几个骚操作:
- 用PWM模拟DAC输出(省硬件成本)
- 组合波的混叠算法
- 自动幅度补偿(频率越高输出电压越低的问题)
这些彩蛋就等各位自己挖了。总之玩波形发生器,记住三字真言:快!准!稳!少一个都得跟示波器大眼瞪小眼。


更多推荐



所有评论(0)