基于STM32F407的示波器兼信号发生器设计

基于STM32F407的示波器兼信号发生器设计

一、项目概述

本项目基于STM32F407ZGT6微控制器设计一款双功能仪器,兼具示波器(信号采集与显示)和信号发生器(波形生成)功能。示波器支持实时波形采集、触发控制、时基/幅度调节;信号发生器支持正弦波、方波、三角波、锯齿波等波形输出,可调节频率、幅度、占空比。系统采用TFT LCD触摸显示,通过DMA+ADC/DAC实现高速数据处理,兼顾性能与成本,适合电子实验、教学演示等场景。

二、系统架构

+-----------------------+
|       STM32F407       |  // 核心:Cortex-M4@168MHz,1MB Flash,192KB RAM
| +-------------------+ |
| | 示波器模块         | |  // ADC采集+触发+显示
| +-------------------+ |
| +-------------------+ |
| | 信号发生器模块     | |  // DAC输出+波形生成
| +-------------------+ |
| +-------------------+ |
| | 人机交互模块       | |  // LCD触摸+按键
| +-------------------+ |
| +-------------------+ |
| | 电源管理模块       | |  // 3.3V/5V稳压
| +-------------------+ |
+-----------------------+
           |  |  |  |  |  |  |  |  |  |  |  |  |
           v  v  v  v  v  v  v  v  v  v  v  v
+----------+--------+--------+--------+--------+--------+--------+--------+
| 信号调理 |  TFT LCD  | 触摸控制 |  ADC采集  |  DAC输出  |  DMA传输  |  Flash  |  SRAM  |
| (放大/衰减) | (FSMC驱动) | (I2C/FSMC) | (12位@2.4MSPS) | (12位@1MSPS) | (双缓冲) | (存储波形) | (缓存数据) |
+----------+--------+--------+--------+--------+--------+--------+--------+

三、硬件设计

1. 核心资源分配

外设 功能描述 关键参数
ADC1/2 示波器信号采集(单通道/双通道) 12位分辨率,2.4MSPS@单通道
DAC1/2 信号发生器波形输出(单通道/双通道) 12位分辨率,1MSPS@单通道
TIM2/3/4 触发控制、DAC更新、时基生成 168MHz主频,分频后1ns精度
DMA1/2 ADC/DAC数据传输(双缓冲) 16流DMA,支持循环模式
FSMC TFT LCD驱动(8080并行接口) 16位数据总线,最高100MHz
I2C1 触摸芯片(如XPT2046)通信 400kHz速率

2. 关键电路设计

(1)示波器信号调理电路

(2)信号发生器输出电路

(3)TFT LCD接口

四、软件设计

1. 主程序框架

int main(void) {
  HAL_Init();
  SystemClock_Config();  // 168MHz HSE+PLL
  Peripherals_Init();   // ADC/DAC/TIM/DMA/LCD/触摸初始化
  UI_Init();            // 界面绘制(主菜单、参数显示)
  
  while (1) {
    if (system_mode == OSCILLOSCOPE_MODE) {
      Oscilloscope_Run();  // 示波器模式
    } else if (system_mode == SIGNAL_GEN_MODE) {
      SignalGen_Run();     // 信号发生器模式
    }
    UI_Update();          // 界面刷新
    Touch_Process();      // 触摸事件处理
  }
}

2. 示波器核心功能实现

(1)信号采集(ADC+DMA双缓冲)

// 双缓冲数组(每缓冲1024点,共2048点)
#define BUFFER_SIZE 1024
uint16_t adc_buffer[2][BUFFER_SIZE];
uint8_t active_buffer = 0;  // 当前活动缓冲(0/1)

void ADC_Init(void) {
  ADC_HandleTypeDef hadc1;
  hadc1.Instance = ADC1;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;  // 单次转换+DMA触发
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;  // TIM2触发
  HAL_ADC_Init(&hadc1);
  
  // DMA配置(双缓冲模式)
  DMA_HandleTypeDef hdma_adc1;
  hdma_adc1.Instance = DMA2_Stream0;
  hdma_adc1.Init.Channel = DMA_CHANNEL_0;
  hdma_adc1.Init.MemBurst = DMA_MBURST_SINGLE;
  hdma_adc1.Init.PeriphBurst = DMA_PBURST_SINGLE;
  hdma_adc1.Init.Mode = DMA_CIRCULAR;  // 循环模式
  hdma_adc1.Init.DoubleBufferMode = DMA_DOUBLE_BUFFER_MODE_ENABLE;
  hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
  hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
  hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
  HAL_DMA_Init(&hdma_adc1);
  __HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1);
  
  // 启动ADC+DMA
  HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, 2*BUFFER_SIZE);
}

(2)触发控制(边沿触发+电平触发)

typedef enum { TRIGGER_EDGE_RISE, TRIGGER_EDGE_FALL, TRIGGER_LEVEL } TriggerMode;
TriggerMode trigger_mode = TRIGGER_EDGE_RISE;
uint16_t trigger_level = 2048;  // 触发电平(12位中点)

// 触发检测(在DMA半传输/全传输中断中执行)
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) {
  if (active_buffer == 0) Check_Trigger(adc_buffer[0], BUFFER_SIZE);
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
  if (active_buffer == 1) Check_Trigger(adc_buffer[1], BUFFER_SIZE);
}

void Check_Trigger(uint16_t* buffer, uint16_t size) {
  for (int i=1; i<size; i++) {
    if (trigger_mode == TRIGGER_EDGE_RISE) {
      if (buffer[i-1] < trigger_level && buffer[i] >= trigger_level) {
        // 找到触发点,更新显示缓冲区
        memcpy(display_buffer, buffer+i, (size-i)*2);
        break;
      }
    } 
    // 其他触发模式类似
  }
}

(3)波形显示(LCD绘制)

// 将ADC采样点(0~4095)映射到LCD坐标(0~239行,0~319列)
#define VERT_SCALE 0.1f  // 垂直缩放因子(点/像素)
#define HORZ_SCALE 1.0f  // 水平缩放因子

void Draw_Waveform(uint16_t* data, uint16_t len) {
  LCD_Clear(BLACK);
  int prev_x = 0, prev_y = 240 - (data[0] - 2048) * VERT_SCALE;  // 垂直居中
  for (int i=1; i<len; i++) {
    int x = i * HORZ_SCALE;
    int y = 240 - (data[i] - 2048) * VERT_SCALE;
    LCD_DrawLine(prev_x, prev_y, x, y, GREEN);  // 绘制连线
    prev_x = x; prev_y = y;
  }
  // 显示时基/幅度参数
  LCD_ShowString(10, 10, "Timebase: 1ms/div", WHITE, BLACK);
  LCD_ShowString(10, 30, "Voltage: 1V/div", WHITE, BLACK);
}

3. 信号发生器核心功能实现

(1)波形生成(查表法+DMA循环输出)

// 正弦波表(1024点,12位精度)
#define WAVE_TABLE_SIZE 1024
const uint16_t sine_table[WAVE_TABLE_SIZE] = {
  2048, 2098, 2148, ..., 2048  // 预先计算的正弦值
};

// DAC输出配置(DMA循环模式)
void DAC_Init(void) {
  DAC_HandleTypeDef hdac1;
  hdac1.Instance = DAC1;
  HAL_DAC_Init(&hdac1);
  
  // DMA配置(循环输出波形表)
  DMA_HandleTypeDef hdma_dac1;
  hdma_dac1.Instance = DMA1_Stream5;
  hdma_dac1.Init.Channel = DMA_CHANNEL_7;
  hdma_dac1.Init.Mode = DMA_CIRCULAR;
  hdma_dac1.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_dac1.Init.MemInc = DMA_MINC_ENABLE;
  hdma_dac1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
  hdma_dac1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
  HAL_DMA_Init(&hdma_dac1);
  __HAL_LINKDMA(&hdac1, DMA_Handle1, hdma_dac1);
  
  // 启动DAC+DMA
  HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t*)sine_table, WAVE_TABLE_SIZE, DAC_ALIGN_12B_R);
}

(2)参数调节(频率/幅度/占空比)

参考代码 基于STM32F407开发的一款示波器,还可作信号发生器 www.youwenfan.com/contentcns/182611.html

四、关键功能实现

1. 示波器核心功能

2. 信号发生器核心功能

五、系统优化

1. 性能优化

2. 抗干扰设计

六、测试与验证

1. 示波器测试

2. 信号发生器测试

七、项目资源

1. 硬件清单

模块 型号/规格 数量 功能
主控 STM32F407ZGT6 1 核心控制
ADC 内置12位ADC 2 信号采集
DAC 内置12位DAC 2 波形输出
LCD 2.8寸TFT(ILI9341) 1 显示波形/参数
触摸芯片 XPT2046 1 触摸控制
运放 OPA2350(双运放) 2 信号调理
电源 LM1117-3.3V + LM2596-5V 1 3.3V/5V供电

2. 开发环境

八、总结

本设计基于STM32F407实现了示波器+信号发生器双功能,通过高速ADC/DAC+DMA完成信号采集与生成,结合TFT触摸显示提供友好交互。示波器支持实时触发、时基/幅度调节,信号发生器支持多波形输出与参数控制,可满足基础电子实验需求。系统采用模块化设计,便于扩展(如增加FFT分析、I2S音频输出等),具有较高实用价值。

专注于matlab/simulink,电子电路,编程