基于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(直接数字频率合成)算法——不过那又是另一个坑了。

源码包里还藏着几个骚操作:

  1. 用PWM模拟DAC输出(省硬件成本)
  2. 组合波的混叠算法
  3. 自动幅度补偿(频率越高输出电压越低的问题)

这些彩蛋就等各位自己挖了。总之玩波形发生器,记住三字真言:快!准!稳!少一个都得跟示波器大眼瞪小眼。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐