一、核心流程

简易数字示波器的核心是 “信号采集 - 数据处理 - 波形显示” 闭环:

1.信号采集:通过 ADC(模数转换)模块,将输入的模拟电信号(如正弦波、方波等)转化为单片机可识别的数字量;

2.数据处理:利用 51 单片机对采集到的数字信号进行存储、滤波等简单处理,剔除噪声干扰;

3.波形显示:借助外接显示屏(如 LCD1602、TFT 屏 )或通过串口上传数据到上位机,还原出电信号的波形。

二、关键理论支撑

1.奈奎斯特采样定理:为保证信号不失真,采样频率需至少为被测信号最高频率的 2 倍。比如测量 1kHz 的方波,采样频率应≥2kHz 。

2.ADC 转换原理:51 单片机本身无 ADC 外设时,需外接 ADC 芯片(如 ADC0804、PCF8591 ),通过模拟输入引脚采集电压信号,经量化、编码输出对应数字值。

三、硬件设计与搭建

(一)核心器件选择

器件名称 功能说明 选型建议
51 单片机 系统控制与数据处理核心 AT89C51/STC89C52
ADC 模块 模拟信号转数字信号 ADC0804(8 位精度,低速场景)、PCF8591(I²C 接口,易用性高)
显示模块 波形可视化输出 LCD1602(字符屏,简易显示)、TFT 彩屏(图形化,效果好)
信号输入电路 调理输入信号(分压、滤波等) 电阻分压网络 + 小电容滤波

(二)硬件连接示例(以 AT89C51 + ADC0804 为例 )

  1. ADC0804 与单片机连接
    • ADC0804 的DB0~DB7(数据总线)连接 51 单片机的P0口;
    • WR(写信号)接单片机P2.0RD(读信号)接P2.1,用于控制 ADC 读写时序;
    • INTR(转换结束信号)接P3.2(外部中断 0),转换完成触发单片机中断读取数据。
  2. 信号输入调理:输入信号先经电阻分压(如将 0~5V 信号适配 ADC 量程 ),再通过 104 小电容滤波,接入 ADC0804 的IN+引脚。
  3. 显示模块:若用 LCD1602,其RSRWE分别接单片机P1.0P1.1P1.2,数据口接P0口。

    四、软件设计与实现

    (一)主程序流程
    C写的代码:

    #include <reg51.h>
    #include <intrins.h>
    
    // 定义ADC0804控制引脚
    sbit ADC_WR = P2^0;
    sbit ADC_RD = P2^1;
    sbit ADC_INTR = P3^2;
    
    // 存储采样数据
    unsigned char adc_buf[128];  // 假设存储128个采样点
    unsigned char cnt = 0;       // 采样计数
    
    // ADC初始化与数据读取函数
    unsigned char adc_read() {
        ADC_WR = 0;  // 启动ADC转换
        _nop_();     // 延时等待转换
        _nop_();     
        ADC_WR = 1;  
        while(ADC_INTR);  // 等待转换完成
        ADC_RD = 0;       // 读取数据
        unsigned char data = P0; 
        ADC_RD = 1;
        return data;
    }
    
    // 定时器0初始化(用于定时采样)
    void timer0_init() {
        TMOD = 0x01;  // 16位定时器模式
        TH0 = 0xff;   // 初值设置,控制采样频率
        TL0 = 0xff;   
        ET0 = 1;      // 使能定时器中断
        EA = 1;       // 开总中断
        TR0 = 1;      // 启动定时器
    }
    
    // 定时器0中断服务程序(定时采样)
    void timer0_isr() interrupt 1 {
        TH0 = 0xff;  // 重置初值
        TL0 = 0xff;  
        if(cnt < 128) {
            adc_buf[cnt++] = adc_read();  // 采集数据存入缓冲区
        } else {
            TR0 = 0;  // 采样完成,关闭定时器
        }
    }
    
    // LCD显示波形(简易示例,仅演示逻辑)
    void lcd_show_wave() {
        // 假设LCD已初始化,此处遍历adc_buf,映射数值到LCD显示
        for(unsigned char i=0; i<128; i++) {
            // 简单映射:将ADC值(0~255)转换为LCD行位置
            unsigned char pos = adc_buf[i] / 16;  // 8位ADC,分16段显示
            // 在LCD第pos行第i列打印标记(如'*')
            // 实际需结合LCD驱动函数实现
        }
    }
    
    void main() {
        timer0_init();  // 初始化定时器,开始定时采样
        while(1) {
            if(cnt >= 128) {  // 采样完成
                lcd_show_wave();  // 显示波形
                cnt = 0;          // 重置计数,准备下次采样
                TR0 = 1;          // 重新启动定时器
            }
        }
    }
    

    (二)关键功能模块解析

  4. .ADC 采样控制:通过定时器 0 定时触发采样(如 50μs 一次 ),利用外部中断或查询方式判断转换完成,确保数据采集的周期性与准确性。

  5. 数据存储与处理:开辟数组adc_buf缓存采样点,可扩展实现简单数字滤波(如滑动平均滤波,去除随机噪声 )。

  6. // 滑动平均滤波函数
    unsigned char filter(unsigned char new_val) {
        static unsigned char buf[4];
        static unsigned char idx = 0;
        unsigned char sum = 0;
        buf[idx++] = new_val;
        if(idx >= 4) idx = 0;
        for(unsigned char i=0; i<4; i++) sum += buf[i];
        return sum / 4;
    }
    
  7. 波形显示逻辑:将 ADC 数值(0~255)映射到 LCD 屏幕的行、列位置,用字符(如*)或点阵还原波形。若用 TFT 屏,可直接绘制曲线,效果更直观。
  8. 信号观测:可捕捉低频信号(如 10Hz~1kHz 的方波、正弦波 ),在显示屏上还原出周期性波形;
  9. 基本测量:通过采样点计算信号的幅值(最大值 - 最小值 )、周期(相邻波峰间隔的采样时间 )。
  10. 提升采样率:更换高速 ADC(如 ADC0820,转换时间 2μs ),或优化单片机时钟(如 STC89C52 可超频到 40MHz ),突破低频限制;
  11. 上位机联动:通过串口将采样数据发送到 PC,用 Python(PyQtGraph 库 )绘制更专业的波形图,支持频谱分析、光标测量等功能;
  12. 触发功能实现:添加边沿触发、脉宽触发逻辑,精准捕获特定条件下的信号(如上升沿触发、阈值触发 ),接近专业示波器的核心功能。

    五、实际效果与优化方向

    预期效果

     

    六、总结

    利用 51 单片机实现数字示波器效果,是对单片机外设控制、信号处理理论的综合实践。从硬件搭建(ADC、显示模块选型与连接 )到软件编程(采样控制、波形还原 ),每一步都能加深对嵌入式系统与电子测量的理解。尽管简易示波器在采样率、精度上无法与专业设备媲美,但作为学习项目,它能帮你打通 “信号采集 - 处理 - 可视化” 的完整链路。后续可结合 STM32、高速 ADC 进一步升级,探索更复杂的信号分析场景,真正玩转嵌入式测量!

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐