ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于STM32与DAC8562的音频信号发生器设计与实现

基于STM32与DAC8562的音频信号发生器设计与实现 1. 项目概述从“信号发生器”到“音频信号源”的实践最近在整理工作室的音频测试设备发现手头虽然有几台专业的音频分析仪但一个灵活、可编程、能输出特定波形和序列的低频信号源却总是缺那么一台。市面上的成品函数发生器功能强大但价格不菲且对于音频频段20Hz-20kHz的应用来说很多高频功能用不上体积和操作也略显复杂。于是一个想法冒了出来能不能用我们最熟悉的微控制器结合一个高性能的数模转换器DAC自己动手做一个专注于音频应用的“DAC信号发生器”这个“RT Spark 1: DAC Signal Generator”项目本质上就是构建一个以微控制器为核心通过DAC芯片产生模拟电压信号并能通过软件精确控制其波形、频率、幅度和直流偏置的简易信号源。它不追求超宽的频带或极高的精度而是瞄准了音频电路调试、传感器激励、基础电子实验等场景追求的是低成本、高灵活性和可玩性。对于电子爱好者、嵌入式开发者或是音频DIY玩家来说这样一个自制的工具不仅能解决实际问题其搭建过程本身也是对模拟数字混合电路设计、实时信号处理、嵌入式编程的一次绝佳实践。2. 核心硬件选型与设计思路拆解一个DAC信号发生器的核心无非三部分产生数字波形的“大脑”MCU、将数字量变为模拟量的“翻译官”DAC、以及将模拟信号进行调理输出的“喉舌”输出缓冲与滤波电路。每一部分的选型都直接关系到最终信号的性能上限和项目的复杂度。2.1 微控制器MCU性能与精度的权衡MCU是整个系统的主控负责波形数据的计算、存储和定时发送给DAC。这里的关键指标是计算能力、定时器精度和内存大小。对于音频频段的信号一个周期内需要足够多的采样点来保证波形还原度。根据奈奎斯特定理采样频率至少是信号最高频率的两倍。对于20kHz的音频采样率需大于40kHz。实际上为了获得较好的波形质量我们通常会将采样率设定在100kHz甚至更高。这意味着MCU需要每10微秒就向DAC输送一个新的数据点。因此我选择了意法半导体的STM32F4系列具体型号为STM32F407VET6。理由如下高性能ARM Cortex-M4内核带FPU浮点运算单元对于实时计算正弦波、三角波等函数值非常有优势即使软件实时生成波形也能保证在100kHz采样率下游刃有余。丰富的定时器其高级定时器如TIM1/TIM8可以产生极高精度的PWM或触发DMA这对于精确控制DAC的更新周期至关重要。我们可以配置一个定时器以精确的间隔如10us触发一次DMA传输将内存中的波形数据自动搬运到DAC的数据寄存器完全解放CPU。大容量SRAM和Flash对于存储预计算的波形表Wave Table非常方便。例如一个包含1024个点的16位正弦波表仅占用2KB内存这对于拥有192KB SRAM的F407来说绰绰有余。多种通信接口预留了USB、UART等方便后期扩展为通过电脑软件控制的可编程信号源。注意如果追求极致的简单和低成本也可以考虑STM32F1系列或GD32系列它们同样具备DMA和定时器只是计算性能稍弱更适合使用预存波形表而非实时计算的方式。2.2 数模转换器DAC分辨率与建立时间DAC芯片是将数字世界与模拟世界连接起来的关键。其核心参数是分辨率、建立时间和接口类型。分辨率决定了输出模拟电压的精细程度。常见的8位、10位、12位、16位。对于音频应用12位4096级是入门16位65536级能提供更好的动态范围和信噪比。本项目选择了TI的DAC8562这是一款双通道、16位、SPI接口的DAC。建立时间指DAC输入数字码变化后输出稳定到最终值一定误差范围内所需的时间。它直接限制了DAC的最高输出频率。DAC8562的建立时间典型值为10μs达到0.003%精度这意味着它理论上能较好地支持到几十kHz的信号更新率满足音频需求。接口SPI接口简单高效易于与STM32连接。DAC8562还内部集成了基准电压源2.5V简化了外部电路设计。选择双通道DAC是为了未来的扩展性例如可以产生两路相关信号用于立体声测试或者一路作为信号输出另一路作为直流偏置控制。2.3 输出缓冲与滤波电路从“有”到“好”直接从DAC芯片引脚输出的信号驱动能力很弱通常只能驱动几毫安的电流且含有高频的采样毛刺。因此输出级电路必不可少。电压跟随器缓冲器使用一颗低噪声、低失调电压、高输入阻抗的运算放大器如OPA1612、ADA4898-1构成电压跟随器。它的作用一是增强带负载能力可以驱动较低的阻抗如600Ω的音频负载二是隔离DAC输出与外部负载避免负载变化直接影响DAC的工作。抗混叠滤波尽管DAC输出是阶梯状的模拟信号但其频谱中除了目标频率外还包含以采样频率及其倍频为中心的高频镜像分量。我们需要一个低通滤波器LPF来衰减这些高频噪声。考虑到最高信号频率为20kHz我将滤波器的截止频率-3dB点设定在25-30kHz左右采用二阶有源滤波器如Sallen-Key结构在通带内提供平坦响应在阻带提供-40dB/十倍频程的衰减能有效平滑波形。电平移位与幅度调节DAC8562的输出范围是0-Vref即0-2.5V或0-5V取决于配置。而标准的音频线路电平通常是±几伏如±2V。因此输出电路还需要完成直流偏置将单极性输出变为双极性和幅度缩放的功能。这可以通过一个由运放构成的加法器电路来实现将DAC信号与一个可调的直流电压相加。3. 软件架构与波形生成策略硬件是骨架软件是灵魂。信号发生器的软件核心任务是按精确的时间间隔向DAC输送正确的数据。这里有几种策略各有利弊。3.1 策略一预计算波形表Wave Table与DMA循环模式这是最经典、对CPU占用最低的方法。适用于标准波形正弦、方波、三角波、锯齿波和任意自定义波形。原理在程序初始化时根据当前设定的波形类型、频率和幅度预先计算出一个完整周期或几个周期的波形数据存储在一个数组中波形表。然后配置DMA将这个数组设置为源地址DAC的数据寄存器为目标地址并设置为循环模式。最后用一个高精度定时器以固定的频率即采样率触发DMA传输。优势CPU仅在参数改变时需要重新计算波形表在输出阶段几乎零参与所有时间都用于响应UI如按键、编码器或通信。输出频率极其稳定抖动极小。频率控制输出信号的频率f_out f_trigger / N其中f_trigger是定时器触发频率采样率N是波形表长度。通过改变定时器的预分频和重装载值来微调f_trigger可以实现频率的连续变化。实现细节以生成1kHz正弦波为例假设采样率fs 100kHz波形表长度N 100。那么每个周期有100个点。定时器应配置为每1/fs 10us触发一次DMA。波形表中的数据data[i] 32768 32767 * sin(2 * π * i / N)假设DAC设置为0-5V输出对应数字量0-6553532768为零点。3.2 策略二实时计算与DMA乒乓缓冲当需要动态改变波形参数如频率调制FM、幅度调制AM或者波形过于复杂无法预先存储时可以采用实时计算。原理配置双缓冲Ping-Pong Buffer。DMA正在从缓冲区A读取数据发送给DAC的同时CPU抓紧时间计算下一批数据填充到缓冲区B。当缓冲区A发送完毕DMA自动切换至缓冲区B同时触发中断通知CPU去填充已发送完的缓冲区A。如此循环。优势极其灵活可以实时生成任意复杂的信号。挑战对CPU计算能力要求高。必须保证在下一个缓冲区被DMA读空之前CPU能完成计算并填充完毕。这限制了最高输出频率和波形复杂度。对于STM32F4在100kHz采样率下实时计算正弦波是可行的但更复杂的运算就可能吃力。在本项目中我采用了混合策略对于基本的固定波形使用预存表DMA循环保证最佳性能同时预留了实时计算的接口用于未来实现扫频、调制等高级功能。3.3 关键外设配置定时器与DMA的协同这是软件中最精妙的部分配置不当会导致输出频率不准、波形抖动。定时器配置以STM32的TIM2为例将其配置为更新事件UEV触发DMA。时钟源内部时钟如84MHz。预分频器PSC根据所需采样率计算。例如要得到fs100kHz定时器计数频率应为fs。若定时器时钟CK_CNT 84MHz则PSC 84MHz / 100kHz - 1 839。自动重装载值ARR设置为1。这样每次计数器从0计数到ARR即1就会产生一次更新事件周期为(PSC1)*(ARR1)/CK_CNT 10us。DMA配置传输方向内存到外设DAC。外设地址DAC的DHRx寄存器地址例如0x40007408。内存地址波形表数组的首地址。数据宽度半字16位对应DAC8562的16位数据。模式循环模式。触发源定时器更新事件。DAC配置使能DAC选择触发源为定时器事件使能DMA请求。当这一切配置好后只需启动定时器和DMA波形就会自动、精确、不间断地输出CPU可以完全抽身去做其他事情。4. 核心功能实现与操作逻辑一个可用的信号发生器除了核心的波形生成还需要友好的人机交互HMI来设定参数。我为其设计了一个基于旋转编码器和OLED屏幕的简易界面。4.1 参数控制系统设计信号发生器需要调节的主要参数有波形类型、频率、幅度、直流偏置。我使用了一个旋转编码器进行选择/调节一个按键作为确认/功能键一块128x64的OLED显示屏用于显示状态。菜单层级主界面显示当前输出的波形、频率、幅度峰值、偏置电压。按下编码器进入主菜单波形选择-频率设置-幅度设置-偏置设置-返回。进入子项如频率设置后旋转编码器调节数值短按切换调节位个/十/百/千/小数点长按返回上一级。参数调节算法频率调节频率值改变后需要动态计算并更新定时器的预分频器PSC和波形表。公式为N fs / f_out。但N必须是整数波形表长度而fs由定时器决定。为了保持fs相对固定以保证滤波器效果我采用的方法是固定一个较高的fs如200kHz通过改变波形表长度N来粗调频率通过微调定时器ARR值来进行细调即DDS直接数字频率合成的思想。这能实现宽范围且高分辨率的频率调节。幅度/偏置调节这两个参数直接影响波形表中的每一个数据点。当用户调整时需要根据新的幅度A和偏置B重新计算整个波形表new_table[i] B A * original_table[i]。其中original_table[i]是归一化到[-1, 1]的原始波形数据。为了避免在调整过程中输出异常数据我采用双缓冲机制在新的后台缓冲区中计算好新表计算完成后通过一个原子操作切换DMA的目标地址到新缓冲区。4.2 波形表生成与动态更新波形表的生成是核心算法。以正弦波为例生成一个包含N个点、幅度为A、偏置为B的波形表// 预计算正弦波表 void generate_sine_table(uint16_t *table, uint32_t length, float amplitude, float offset) { // 假设DAC满量程对应数字量范围 0-65535 零点在32768 float dac_zero 32768.0f; float dac_scale 32767.0f; // 对应 ±1V 如果参考电压是2.5V且运放增益为2 for (uint32_t i 0; i length; i) { float angle 2.0f * PI * i / length; float value offset amplitude * sinf(angle); // 计算归一化电压值-1 to 1 // 转换为DAC数字量 int32_t dac_value (int32_t)(dac_zero value * dac_scale); // 限幅保护 if (dac_value 65535) dac_value 65535; if (dac_value 0) dac_value 0; table[i] (uint16_t)dac_value; } }对于方波和三角波计算更为简单。方波就是前半个周期输出高电平后半个周期输出低电平。三角波则是线性递增再线性递减。4.3 输出级电路的控制与校准硬件电路的增益和偏移并非完全理想因此软件中需要引入校准系数。幅度校准设置一个已知的幅度如软件设置1Vpp用高精度万用表或示波器测量实际输出电压。计算误差系数calib_gain V_expected / V_actual。在计算波形表时将用户设定的幅度A_user乘以calib_gain得到实际使用的幅度A_real。偏置校准设置幅度为0偏置为0V测量实际输出得到一个零点误差电压V_offset_error。在计算波形表时将用户设定的偏置B_user加上V_offset_error得到B_real。这些校准参数可以存储在MCU的Flash中上电时读取。通过预留一个“校准模式”菜单可以引导用户完成这个过程。5. 实测性能分析与优化技巧搭建完成后我用示波器和频谱分析仪对其进行了系统测试。5.1 基础波形测试与失真分析正弦波在1kHz 1Vpp输出下用示波器观察波形光滑无明显台阶感得益于100kHz的高采样率和后级滤波。用频谱仪观察基波幅度为0dB二次谐波失真THD在-60dBc以下三次谐波更低。这对于一个自制设备来说已经相当不错足以应对大多数音频电路的测试。方波上升/下降时间主要受运放摆率Slew Rate和滤波器带宽限制。实测使用OPA1612摆率20V/μs在10kHz方波下上升时间约几百纳秒过冲和振铃不明显。在更高频率下由于低通滤波器的限制方波会变得圆滑趋近于正弦波这符合预期。频率精度在10Hz到10kHz范围内用频率计测量输出信号频率与设定值的误差小于0.1%主要误差来源于MCU主时钟的精度。可以通过使用外部高精度晶振或时钟校准来进一步提升。5.2 噪声与稳定性排查初始测试时发现输出正弦波上有少量高频毛刺和低频抖动。高频毛刺在示波器上打开高分辨率模式发现毛刺是周期性的与DAC的更新周期同步。这大概率是DAC内部开关动作引起的“馈通”噪声。解决方案在DAC的输出引脚与运放输入之间增加一个几十到几百皮法的小电容到地形成一个一阶低通可以有效滤除这种超高频噪声。同时确保DAC的电源引脚有充足的去耦电容通常用1μF钽电容并联一个100nF陶瓷电容。低频抖动表现为波形基线缓慢上下波动。这通常是电源噪声或地线干扰。解决方案电源为模拟部分DAC、运放使用独立的线性稳压电源如LM317与数字部分MCU的开关电源隔离。在模拟电源入口处增加π型滤波。地线采用“星型接地”或单点接地。将模拟地AGND和数字地DGND在电源入口处通过一个0欧姆电阻或磁珠连接避免数字噪声电流流过模拟地平面。布局DAC芯片尽量靠近MCU的SPI引脚缩短数字走线。模拟输出走线远离任何数字信号线特别是时钟线和PWM线。5.3 负载能力与保护机制测试信号源的输出级需要能驱动一定的负载。测试时我连接了从100kΩ到600Ω不等的电阻负载。空载/轻载输出波形完美。重载如600Ω当输出幅度较大如±2V时输出电流达到2V / 600Ω ≈ 3.3mA。此时需要观察运放输出是否出现削波clipping或温升。OPA1612的典型输出电流可达30mA驱动600Ω负载完全没有问题。但如果负载阻抗更低如50Ω就需要选择输出电流能力更强的运放或者在输出级增加一个互补推挽晶体管缓冲电路。短路保护这是一个必须考虑的安全功能。我采用的保护措施是在运放输出端串联一个小的电阻如22Ω并在其后对电源轨接上快恢复二极管进行钳位。这样即使输出短路到地或电源电流会被电阻限制电压被二极管钳位保护了运放。当然这会在输出电阻上引入一个小的压降需要在设计增益时予以考虑。6. 扩展应用与未来升级设想一个基础的单通道音频信号源已经完成但它还有巨大的潜力可以挖掘。6.1 应用场景延伸音频测试这是最直接的应用。可以产生正弦波进行频响测试、总谐波失真THD测试产生方波进行瞬态响应测试产生白噪声或粉红噪声进行信噪比测试。传感器激励许多传感器如应变片、热敏电阻需要稳定的交流或直流激励信号。本信号源可以产生精确的电压配合仪表放大器电路可以搭建完整的传感器测量系统。电子教学与实验用于演示滤波器特性低通、高通、带通、放大器增益、比较器阈值等基础电路概念比函数发生器更直观因为参数可通过简单界面设置。可编程电源通过软件控制可以输出缓慢变化的斜坡电压或复杂的电压序列用于电池充电测试、电机驱动测试等。6.2 硬件升级方向多通道同步利用DAC8562的双通道特性可以开发双通道同步输出功能。两个通道共享同一个定时器触发可以输出相位相关的两路信号用于立体声测试或差分信号驱动。更高精度与速度升级DAC芯片到18位甚至24位音频DAC如PCM1794A配合更高性能的运放和更精密的基准电压源可以将THDN总谐波失真加噪声做到-110dB以下达到专业音频测试仪的水平。同时使用更高主频的MCU如STM32H7或FPGA可以将采样率提升到1MHz以上输出频率扩展到几百kHz用于超声波或简单射频实验。增加输入测量功能增加一个高性能的模数转换器ADC如ADS127L01配合适当的输入调理电路就可以让设备同时具备信号发生和信号分析的能力变成一个简单的音频分析仪或动态信号分析仪。6.3 软件与交互升级上位机软件控制通过USB虚拟串口或USB Audio Class开发电脑端控制软件。用户可以在图形界面上绘制任意波形、设置扫频序列、进行调制AM/FM/PM然后下载到设备执行。这将极大地扩展其功能性。存储与调用预设在Flash中开辟存储区保存多组常用的参数配置波形、频率、幅度、偏置可以一键调用。高级信号生成利用MCU的FPU和实时计算能力实现线性/对数扫频、任意波形生成、脉冲序列生成、伪随机噪声生成等功能。这个“RT Spark 1”项目就像一颗种子从一个简单的想法开始通过硬件选型、电路设计、软件编程、调试优化最终生长为一个切实可用的工具。整个过程充满挑战但也正是这些挑战让最终看到纯净的正弦波从自己搭建的电路中输出时那种成就感无可比拟。它不仅仅是一个信号发生器更是一个通往模拟电路、数字信号处理和嵌入式系统世界的大门。
返回列表