基于STM32的正点原子示波器项目详解

简介: 基于STM32的正点原子示波器项目详解

一、项目概述

基于STM32的正点原子示波器是一个开源的单片机学习项目,通过正点原子开发板实现简易数字示波器功能。该项目能够采集、显示和分析模拟信号,测量信号的频率、幅值等参数,是学习STM32和嵌入式系统开发的优秀实践项目。

二、硬件平台选择

正点原子提供了多款STM32开发板,均可用于示波器项目:

开发板型号 主控芯片 核心特点 适用场景
精英板 STM32F103ZET6 性价比高,资源丰富 初学者入门,基础示波器
MiniSTM32 STM32F103RCT6 小巧便携,成本低 简化版示波器
战舰版 STM32F103ZET6 功能全面,接口丰富 功能完整的示波器
探索者 STM32F407ZGT6 高性能,带FPU 高级示波器,支持复杂算法

三、核心功能特性

3.1 基本功能

  • 信号采集:通过ADC采集0-3.3V范围内的模拟信号
  • 波形显示:在TFTLCD上实时显示波形
  • 参数测量
    • 频率测量(支持FFT算法提高精度)
    • 幅值测量(最大值、最小值、峰峰值)
    • 电压测量
  • 采样控制
    • 可调节采样频率(通过按键控制)
    • 波形暂停/继续功能

3.2 高级功能(部分实现)

  • 多波形支持:正弦波、三角波、方波、锯齿波、噪声等
  • 数据导出:通过串口将测量数据发送到PC
  • 触发功能:边沿触发、电平触发
  • 自动量程:自动调整显示范围

四、硬件连接与配置

4.1 基本连接方式

信号输入 → PA6(ADC1通道6)
         或PA5(ADC1通道5)
         或PA1(ADC1通道1)

TFTLCD → FSMC接口(战舰版/探索者)
       或并口/SPI接口(精英版/Mini版)

控制按键:
KEY_UP → 波形更新/暂停
KEY0   → 提高采样率
KEY1   → 降低采样率

4.2 测试信号连接

  • 正弦波测试:PA6与PA4相连
  • 三角波/噪声测试:PA6与PA5相连

五、软件架构与关键技术

5.1 核心采集方案:ADC+TIMER+DMA

// 关键配置代码示例(基于精英板)
void Adc_Init(void)
{
   
    ADC_InitTypeDef ADC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    // 使能ADC1和GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);  // 72M/6=12MHz

    // 配置PA6为模拟输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // ADC配置
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);

    // 配置ADC通道6
    ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_1Cycles5);

    // 使能ADC和DMA
    ADC_Cmd(ADC1, ENABLE);
    ADC_DMACmd(ADC1, ENABLE);

    // 校准ADC
    ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1));
}

5.2 定时器触发配置

// 定时器2配置为PWM模式,触发ADC采样
void TIM2_PWM_Init(u16 arr, u16 psc)
{
   
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    // 使能TIM2时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    // 定时器基础配置
    TIM_TimeBaseStructure.TIM_Period = arr;
    TIM_TimeBaseStructure.TIM_Prescaler = psc;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    // PWM模式配置
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = arr/2;  // 50%占空比
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC2Init(TIM2, &TIM_OCInitStructure);

    // 使能TIM2
    TIM_Cmd(TIM2, ENABLE);
    TIM_CtrlPWMOutputs(TIM2, ENABLE);
}

5.3 DMA数据传输配置

// DMA配置,用于ADC数据自动传输
void DMA_Config(void)
{
   
    DMA_InitTypeDef DMA_InitStructure;

    // 使能DMA1时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    // DMA配置
    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 1024;  // 采样点数
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  // 循环模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);

    // 使能DMA
    DMA_Cmd(DMA1_Channel1, ENABLE);
}

六、项目文件结构

oscilloscope_project/
├── Hardware/
│   ├── adc.c/h          # ADC配置
│   ├── timer.c/h        # 定时器配置
│   ├── dma.c/h          # DMA配置
│   ├── lcd.c/h          # LCD驱动
│   ├── key.c/h          # 按键处理
│   └── usart.c/h        # 串口通信
├── System/
│   ├── delay.c/h        # 延时函数
│   ├── sys.c/h          # 系统配置
│   └── usart.c/h        # 串口配置
├── User/
│   ├── main.c           # 主程序
│   ├── oscilloscope.c/h # 示波器核心逻辑
│   ├── waveform.c/h     # 波形处理
│   └── fft.c/h          # FFT频率计算
└── README.md            # 项目说明

参考代码 基于stm32的正点原子的示波器 www.youwenfan.com/contentalh/135927.html

七、主要技术指标

参数 指标 说明
输入电压范围 0-3.3V 由STM32的ADC参考电压决定
采样频率 可调,最高约1MHz 取决于定时器配置和CPU频率
采样点数 1024点/帧 保证波形显示完整性
频率测量范围 几Hz到几百Hz 实际范围取决于采样率
显示分辨率 320×240或更高 取决于TFTLCD型号
测量精度 12位ADC 理论分辨率约0.8mV

八、使用步骤

8.1 硬件准备

  1. 开发板选择:正点原子精英板/战舰版/探索者
  2. LCD连接:将TFTLCD模块连接到开发板对应接口
  3. 信号输入:将待测信号连接到PA6(或其他ADC引脚)
  4. 电源连接:确保3.3V供电稳定

8.2 软件烧录

  1. 获取源码:从开源仓库下载项目代码
  2. 环境配置:安装Keil MDK或STM32CubeIDE
  3. 编译工程:根据开发板型号选择对应配置
  4. 下载程序:通过ST-Link或J-Link下载到开发板

8.3 操作使用

  1. 上电启动:系统自动初始化,显示示波器界面
  2. 信号连接:将待测信号连接到指定ADC引脚
  3. 参数调节
    • KEY_UP:暂停/继续波形更新
    • KEY0:提高采样率
    • KEY1:降低采样率
  4. 数据查看:波形和测量参数实时显示在LCD上

九、性能优化建议

9.1 提高采样率

  1. 降低ADC采样时间:使用ADC_SampleTime_1Cycles5
  2. 提高系统时钟:合理配置PLL,提升系统频率
  3. 优化DMA传输:使用双缓冲机制减少数据传输时间

9.2 提高测量精度

  1. ADC校准:每次上电后进行ADC校准
  2. 软件滤波:添加数字滤波算法(均值滤波、中值滤波)
  3. FFT优化:使用查表法加速FFT计算

9.3 增强功能

  1. 多通道支持:扩展为双通道示波器
  2. 存储功能:添加SD卡存储波形数据
  3. 网络通信:通过以太网或WiFi传输数据到PC

十、常见问题与解决方案

问题现象 可能原因 解决方案
无波形显示 LCD未正确初始化 检查LCD连接和初始化代码
波形失真 采样率过低 提高定时器频率,降低分频系数
测量误差大 ADC未校准 添加ADC校准程序
按键无响应 外部中断配置错误 检查按键GPIO和中断配置
内存溢出 采样数组过大 优化内存使用,使用外部SRAM

十一、项目总结

基于STM32的正点原子示波器项目是一个综合性很强的嵌入式系统实践项目,涵盖了:

  • 硬件接口:ADC、定时器、DMA、GPIO、外部中断
  • 软件算法:信号处理、FFT变换、波形显示
  • 系统设计:实时数据采集、人机交互、性能优化

该项目不仅可以帮助初学者深入理解STM32的各种外设工作原理,还能掌握数字示波器的基本设计方法。

目录
相关文章
|
存储 安全 Linux
linux系统中u-boot命令的EMMC和SD卡操作命令分析
linux系统中u-boot命令的EMMC和SD卡操作命令分析
2150 1
|
存储 前端开发 算法
C++线程 并发编程:std::thread、std::sync与std::packaged_task深度解析(一)
C++线程 并发编程:std::thread、std::sync与std::packaged_task深度解析
1077 0
|
2月前
|
编译器 开发工具
.NET 10 SDK 安装教程(dotnet-sdk-10.0.100-win-x64详细步骤)
.NET 10 SDK是微软推出的最新开发工具包,含运行时、CLI与编译器。安装只需下载exe、以管理员身份运行、勾选许可、一路Next。完成后重启终端,执行`dotnet --version`显示10.0.100即成功。(239字)
|
7月前
|
运维 监控 Linux
Linux中收集【系统】和【硬件】信息的30个常用命令总结
本文系统梳理30个Linux运维核心命令,涵盖系统信息(如`uname`、`hostname`)、硬件诊断(如`lscpu`、`smartctl`)及日志监控(如`dmesg`、`journalctl`)等全场景需求,助力高效排查故障、优化性能与实现自动化运维。
1158 2
|
8月前
|
机器学习/深度学习 人工智能 算法
从人工目检到 AI 质检-YOLOv8 驱动的 PCB 缺陷检测系统【完整源码】
本项目基于YOLOv8打造全自动PCB缺陷检测系统,涵盖缺孔、短路等六类常见缺陷。采用PyTorch+PyQt5构建端到端应用,支持图片、视频及实时摄像头检测,提供完整源码、模型权重与数据集,助力工业质检智能化升级。
1032 6
从人工目检到 AI 质检-YOLOv8 驱动的 PCB 缺陷检测系统【完整源码】
|
9月前
|
XML Java 数据库连接
MyBatis Plus 核心功能与用法
MyBatis Plus 是基于 MyBatis 的增强工具,简化单表 CRUD 操作。通过继承 BaseMapper 即可实现增删改查,支持条件构造器、分页、逻辑删除、自动填充、乐观锁等高级功能,大幅提升开发效率,无需编写冗余 SQL 与 XML,助力快速构建 Spring Boot 应用。
869 0
|
10月前
|
算法
基于STM32定时器外部计数模式实现方波频率测量
基于STM32定时器外部计数模式实现方波频率测量
|
Ubuntu Linux 数据安全/隐私保护
Ubuntu系统安装详细教程
确认您的选择无误后,安装程序将正式启动。请耐心等待,直至程序运行完毕并提示您重启。随后,您可以安全地移除安装盘,并重启计算机。至此,系统安装已全部完成!
|
Linux Shell 网络安全
LabVIEW NI Linux Real-Time深层解析
LabVIEW NI Linux Real-Time深层解析
584 0
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
1124 20