从零到一:基于STM32与DDS技术的可编程信号发生器实战(附完整工程文件)

从零到一:基于STM32与DDS技术的可编程信号发生器实战(附完整工程文件)

1. 项目背景与核心器件选型

第一次接触信号发生器是在大学电子实验课上,看着老师用一台黑色仪器输出各种波形,总觉得这东西神秘又昂贵。直到后来发现用STM32配合DDS芯片就能DIY,成本不到200元,我决定自己动手做一个。这个项目最吸引人的地方在于:用嵌入式开发板实现专业设备的功能,而且所有代码和电路都开源可修改。

先说说为什么选STM32F103C8T6作为主控。这款芯片属于"蓝 pill"开发板标配,72MHz主频足够处理波形数据,内置DAC虽然能用但精度有限。实测发现直接用PWM模拟正弦波时,频率超过5kHz就会出现明显畸变。这就是引入AD9833 DDS模块的关键原因——它能直接输出0-12.5MHz的模拟信号,分辨率达到0.1Hz,价格却只要25元左右。

硬件选型时踩过两个坑:第一是供电问题,AD9833需要5V电压但STM32是3.3V逻辑,必须用电平转换芯片(我用的是74HC4050);第二是输出滤波,DDS芯片输出的信号带有高频毛刺,需要设计二阶低通滤波器。建议选择这些关键器件:

  • 主控:STM32F103C8T6(性价比之王)
  • DDS模块:AD9833或AD9850(后者频率更高但更贵)
  • 显示屏:LCD1602(够用)或OLED(更美观)
  • 按键编码器:EC11(调节频率比普通按键方便十倍)

2. 电路设计实战细节

画原理图时建议先分模块处理。我的设计分为五个部分:电源转换主控最小系统DDS接口电路滤波放大电路人机交互模块。其中最容易出错的是DDS芯片的SPI接口布线,SCLK信号一定要远离模拟输出线路,否则会引入数字噪声。

PCB布局有三个经验值得分享:

  1. 把DDS模块和滤波电路放在板子边缘,远离数字部分
  2. 晶振下方不要走任何信号线
  3. 模拟地(AGND)和数字地(DGND)通过0欧电阻单点连接

电源部分特别重要,我用了两级滤波:第一级在USB输入处加100μF电解电容滤低频,第二级在每个芯片的VCC引脚旁加0.1μF陶瓷电容滤高频。测试时发现如果不加这两个电容,输出波形会有明显的电源纹波。

注意:焊接AD9833时一定要控制好温度,这个芯片对静电敏感。我第一次焊接就因为没接地线导致芯片损坏,后来买了防静电焊台才解决问题。

3. 软件架构与关键代码

整个工程用STM32CubeMX初始化,基于HAL库开发。软件层的核心是DDS驱动波形生成算法。先看DDS的初始化代码:

void AD9833_Init(void) { HAL_GPIO_WritePin(DDS_FSYNC_GPIO_Port, DDS_FSYNC_Pin, GPIO_PIN_RESET); SPI_Transmit(0x2100); // 复位AD9833 SPI_Transmit(0xC000); // 选择正弦波输出 SPI_Transmit(0x2000); // 退出复位状态 HAL_GPIO_WritePin(DDS_FSYNC_GPIO_Port, DDS_FSYNC_Pin, GPIO_PIN_SET); }

频率设置函数有个技巧:AD9833的频率寄存器是28位的,需要分两次发送。这里用位操作提高效率:

void AD9833_SetFrequency(uint32_t freq) { uint32_t freq_word = (freq * 268435456LL) / 25000000; uint16_t lsb = freq_word & 0x3FFF; uint16_t msb = (freq_word >> 14) & 0x3FFF; HAL_GPIO_WritePin(DDS_FSYNC_GPIO_Port, DDS_FSYNC_Pin, GPIO_PIN_RESET); SPI_Transmit(0x4000 | lsb); SPI_Transmit(0x4000 | msb); HAL_GPIO_WritePin(DDS_FSYNC_GPIO_Port, DDS_FSYNC_Pin, GPIO_PIN_SET); }

人机交互部分实现了三个功能:

  1. 旋转编码器调节频率(每格增加/减少1Hz或100Hz)
  2. 按键切换波形类型(正弦/方波/三角波)
  3. LCD实时显示当前参数

4. 调试技巧与性能优化

第一次通电时可能会遇到DDS模块无输出的情况。建议按这个顺序排查:

  1. 用逻辑分析仪检查SPI信号是否正常
  2. 测量AD9833的25MHz时钟输入
  3. 检查滤波电路运放供电电压

频率精度测试时,我发现当输出高频信号(>1MHz)时,实际频率会比设定值低约0.8%。这是因为程序中的延时影响了SPI通信速率。解决方法是在计算频率字时加入补偿系数:

// 补偿公式 freq_word = (freq * 268435456LL * 1002) / (25000000 * 1000);

输出幅度调节可以通过两种方式实现:硬件上用电位器调整运放增益,软件上修改DDS的输出幅度寄存器。实测发现软件调节更方便但会降低信噪比,建议在1Vpp以下用硬件调节。

最终成品性能参数:

  • 频率范围:1Hz-5MHz(正弦波),1Hz-1MHz(方波)
  • 频率分辨率:0.1Hz
  • 输出幅度:0-5Vpp可调
  • 波形失真度:<1%(@1kHz)

完整的工程文件包含STM32源码、原理图、PCB文件和3D打印外壳设计,已经过实物验证。调试过程中最耗时的其实是机械结构设计——如何让旋钮手感更好、如何固定LCD屏幕等细节,这些往往比电路设计更考验耐心。