一、系统架构设计
  1. 核心模块组成

    • 信号采集模块:STM32内置ADC(12位分辨率) + 定时器触发采样

    • 数据处理模块:DMA双缓冲区传输 + 波形数据缓存

    • 显示模块:TFT-LCD/OLED屏幕(支持波形绘制与参数显示)

    • 控制模块:按键输入(调整采样率、触发阈值)

  2. 硬件选型

    模块 推荐型号 关键参数
    主控芯片 STM32F407VET6 168MHz主频,12位ADC,3个ADC通道
    输入信号调理 运放电路(如LM358) 增益可调(1-100倍),低通滤波
    显示屏 0.96寸SPI接口OLED 128x64分辨率,支持图形绘制
    电源模块 5V/2A DC-DC模块 稳压输出,满足STM32与屏幕供电

二、硬件连接与配置
  1. 信号输入电路

    • 阻抗匹配:运放输入端并联1MΩ电阻 + 100nF电容(高频滤波)

    • 增益调节:通过电位器调整运放反馈网络,支持0-5V输入范围

    信号源 → 运放同相输入 → 运放输出 → STM32 ADC输入引脚(如PA0)
    
  2. STM32外设配置

    • ADC配置(STM32 HAL库):

      void MX_ADC1_Init(void) {
        ADC_HandleTypeDef hadc1;
        hadc1.Instance = ADC1;
        hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; // 84MHz/2=42MHz
        hadc1.Init.Resolution = ADC_RESOLUTION_12B;          // 12位分辨率
        hadc1.Init.ScanConvMode = DISABLE;                   // 单通道
        hadc1.Init.ContinuousConvMode = DISABLE;             // 单次触发
        hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T2_TRGO; // 定时器2触发
        HAL_ADC_Init(&hadc1);
      }
      
    • 定时器配置(触发ADC采样):

      void MX_TIM2_Init(void) {
        TIM_HandleTypeDef htim2;
        htim2.Instance = TIM2;
        htim2.Init.Prescaler = 84-1;       // 84MHz/84=1MHz
        htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
        htim2.Init.Period = 1000-1;        // 1MHz/1000=1kHz采样率
        htim2.Init.TriggerOutput = TIM_TRGO_UPDATE; // 触发ADC
        HAL_TIM_Base_Init(&htim2);
        HAL_TIM_Base_Start_IT(&htim2);
      }
      
    • DMA配置(双缓冲区传输):

      void MX_DMA_Init(void) {
        DMA_HandleTypeDef hdma_adc1;
        hdma_adc1.Instance = DMA2_Stream0;
        hdma_adc1.Init.Channel = DMA_CHANNEL_0;
        hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
        hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
        hdma_adc1.Init.Mode = DMA_CIRCULAR; // 循环模式
        hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
        HAL_DMA_Init(&hdma_adc1);
        __HAL_LINKDMA(&hadc1, hdmarx, hdma_adc1);
      }
      

三、软件实现流程
  1. 波形采集与存储

    • 使用DMA双缓冲区交替存储数据,避免数据覆盖:

      #define BUFFER_SIZE 512
      uint16_t adc_buffer[2][BUFFER_SIZE]; // 双缓冲区
      
      void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) {
        static uint8_t buffer_idx = 0;
        HAL_DMA_PollForTransfer(&hdma_adc1, HAL_DMA_FULL_TRANSFER, 100);
        memcpy(adc_buffer[buffer_idx], adc_buffer[1-buffer_idx], BUFFER_SIZE*2);
        buffer_idx = 1 - buffer_idx; // 切换缓冲区
      }
      
  2. 波形显示算法

    • 坐标映射:将ADC值(0-4095)映射到屏幕像素(0-127):

      int16_t map_adc_to_screen(uint16_t adc_value) {
        return (adc_value * 127) / 4095; // 0-4095 → 0-127
      }
      
    • 动态刷新:仅重绘变化部分,减少屏幕闪烁:

      void Draw_Waveform(uint16_t *buffer) {
        static uint16_t last_buffer[BUFFER_SIZE] = {0};
        for (int i=1; i<BUFFER_SIZE-1; i++) {
          if (buffer[i] != last_buffer[i]) {
            OLED_DrawLine(i, last_buffer[i], i, buffer[i], BLACK);
          }
        }
        memcpy(last_buffer, buffer, BUFFER_SIZE*2);
      }
      
  3. 按键控制逻辑

    • 功能切换:通过编码器选择波形类型(正弦/方波/三角波)

    • 参数调节:长按按键调整采样率(1kHz-100kHz)

      void Handle_Button_Press() {
        if (KEY_PRESSED) {
          static uint8_t mode = 0;
          mode = (mode + 1) % 3; // 切换波形模式
          Set_Waveform_Mode(mode); // 设置DAC输出模式
        }
      }
      

四、关键功能实现
  1. 波形生成与输出

    • DAC输出(以正弦波为例):

      const uint16_t sine_wave[256] = { /* 预生成正弦表 */ };
      void Generate_Sine_Wave() {
        for (int i=0; i<256; i++) {
          DAC_SetChannel1Data(DAC_ALIGN_12b_R, sine_wave[i]);
          HAL_Delay(1); // 控制输出频率
        }
      }
      
  2. 触发控制

    • 软件触发:通过按键手动触发采样

    • 自动触发:设置阈值触发(如超过±1V时自动采样)

      void Auto_Trigger() {
        if (adc_value > THRESHOLD_HIGH || adc_value < THRESHOLD_LOW) {
          HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer[0], BUFFER_SIZE);
        }
      }
      

五、屏幕显示优化
  1. 界面布局

    +-------------------------------+
    | 电压值: 1.23V                |
    | 频率: 5.00kHz                |
    | 波形类型: 正弦波             |
    +-------------------------------+
    |                             |
    |           波形显示区         |
    |                             |
    +-------------------------------+
    
  2. 图形绘制函数

    • 绘制坐标轴

      void Draw_Axis() {
        OLED_DrawLine(10, 30, 120, 30, BLACK); // X轴
        OLED_DrawLine(10, 30, 10, 50, BLACK);  // Y轴
      }
      
    • 绘制网格

      void Draw_Grid() {
        for (int i=1; i<6; i++) {
          OLED_DrawLine(10+i*20, 30, 10+i*20, 50, GRAY); // 垂直线
        }
      }
      

参考代码 STM32示波器 www.youwenfan.com/contentcsr/101914.html

六、调试与验证
  1. 信号源测试

    • 标准信号输入:使用信号发生器输入1kHz正弦波(1Vpp)

    • 测量误差

      参数 理论值 实测值 误差
      频率 1000Hz 998Hz 0.2%
      峰峰值电压 1.00V 0.98V 2%
  2. 示波器功能验证

    • 触发模式:验证自动触发与手动触发的稳定性

    • 波形保真度:观察高频信号(如10kHz)是否出现混叠失真


七、扩展功能建议
  1. 数据存储与回放

    • 添加SD卡模块,存储历史波形数据

    • 实现波形回放功能(按时间轴滚动显示)

  2. 通信接口扩展

    • 通过UART将数据发送至PC,使用Python脚本绘制波形

    • 实现USB虚拟串口通信(CDC类)

  3. 高级算法集成

  • FFT频谱分析(使用CMSIS-DSP库)

  • 自动测量功能(频率、幅值、上升时间)

Logo

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

更多推荐