一、系统概述与核心功能
1. 系统定位
基于TMS320F2808(C2000系列定点DSP)的音频范围扫频仪,旨在为电子工程师、音响发烧友及高校实验室提供一款低成本、高精度、宽频带的频率响应测试工具。系统利用F2808片内高达100MHz的运算能力,结合高分辨率增强型PWM(ePWM-HR)与直接数字频率合成(DDS)算法,在无需外部昂贵DAC芯片的情况下,生成纯净、高精度的正弦扫频信号(20Hz-20kHz),并配合片上ADC自动采集待测设备(如音箱、滤波电路)的输出幅值,最终通过串口将幅频特性曲线发送至PC端LabVIEW软件进行可视化分析。
2. 核心功能模块
| 模块 | 功能描述 |
|---|---|
| DDS信号生成 | 利用F2808的BootROM内置512点正弦表,配合HRPWM技术,实现频率范围20Hz-20kHz、频率步进1Hz、频率精度极高的正弦波输出 |
| 扫频控制 | 支持线性扫频与对数扫频两种模式,可通过按键自由设定起始频率、截止频率及扫频步进(或时间间隔) |
| 幅频采集 | 利用片上12位ADC(最高12.5MSPS)实时采集待测设备的音频输出信号,计算有效值(RMS) |
| 人机交互 | OLED液晶屏实时显示当前扫频频率与输出电压;4个独立按键控制扫频启停、模式切换及参数调整 |
| 数据上传 | 通过片上SCI(串口)将"频率-幅值"数据上传至上位机LabVIEW,绘制高精度伯德图 |
二、硬件设计方案
1. 核心硬件选型
| 模块 | 型号/规格 | 关键参数 | 接口方式 |
|---|---|---|---|
| 主控核心 | TMS320F2808PZA | 100MHz C28x内核,32位CPU定时器,16路ADC,6路ePWM(含高分辨率模式) | 核心控制器 |
| 信号调理 | 二阶巴特沃斯低通滤波器 | 截止频率设定为22kHz,用于滤除PWM载波高频分量,还原纯净正弦波,衰减斜率-40dB/十倍频程 | 模拟电路 |
| 输入调理 | 精密整流电路+分压网络 | 将待测设备输出的双极性音频信号(+/- 5V)转换为0-3V单极性信号,送入DSP的ADC采样端 | ADCINA0 (GPIO0) |
| 显示模块 | 0.96寸OLED (SSD1306) | 128×64分辨率,I2C接口,低功耗,支持ASCII字符及简易图形绘制 | I2C-A (GPIO28/29) |
| 交互模块 | 轻触按键 × 4 | 启动/暂停、模式切换、参数加、参数减 | GPIO12 - GPIO15 (上拉输入) |
| 通信模块 | USB转TTL串口模块 | 实现DSP与上位机PC的物理连接,波特率115200bps | SCIA (GPIO28/29) |
| 电源模块 | DC 5V/2A开关电源 | 经板载LDO降至3.3V(I/O供电)与1.8V(内核供电),并设置模拟/数字电源磁珠隔离 | 外部供电接口 |
2. 硬件电路设计要点
2.1 核心电路连接
- TMS320F2808最小系统:外接20MHz无源晶振(经内部PLL倍频至100MHz),JTAG仿真调试接口,复位电路。
- HRPWM信号输出:选用ePWM1A(GPIO0)作为正弦波发生器输出引脚。利用F2808的脉宽高精度扩展技术(MEP),将PWM的有效位数提升至14位以上,极大降低了频谱泄漏。
- 音频输入调理:待测设备的音频输出端首先经过精密绝对值电路(由运放OPA2277构成)进行全波整流,再经由RC滤波电路得到直流幅值,最后通过电阻分压网络限幅至0-3V,接入ADCINA0。
2.2 抗干扰与安全设计
- 电源去耦:在DSP的VDD(内核)和VDDIO(I/O)引脚旁紧贴放置0.1μF和10μF的去耦电容。
- 模拟地与数字地分割:PCB设计时严格区分模拟地(AGND)与数字地(DGND),并在ADC芯片下方通过0Ω磁珠单点接地,最大限度降低数字噪声对微弱音频信号的干扰。
- 信号屏蔽:PWM输出端的低通滤波器放置在DSP芯片尽可能近的位置,并使用屏蔽罩包裹,防止高频谐波辐射干扰ADC采样。
三、软件设计与核心代码
1. 系统架构
采用前后台系统(超循环),以定时器中断为后台驱动,主循环为前台逻辑。核心流程:
- 初始化:配置系统时钟(100MHz)、GPIO、高分辨率ePWM、ADC及SCI串口。
- 主循环 :
- 扫描按键状态,根据当前模式(设置/运行)调整扫频参数。
- 调用DDS算法更新ePWM的占空比。
- 读取ADC采样值并转换为电压幅值。
- 更新OLED显示内容。
- 定时器中断(每秒触发一次):触发ADC开始采样,并将当前"频率-幅值"数据打包通过SCI发送至上位机。
2. 核心代码实现(基于TI ControlSUITE库)
2.1 DDS正弦波生成(基于查表法与HRPWM)
c
#include "DSP2808_Device.h"
#include "DSP2808_GlobalPrototypes.h"
// ======== 全局变量与宏定义 ========
#define SAMPLING_FREQ 100000 // PWM载波频率 100kHz (系统时钟 100MHz / 1000)
#define SINE_TABLE_SIZE 512 // 正弦查找表大小 (存储在BootROM中,地址需查阅手册)
#define MAX_FRACTION_BITS 16 // 相位累加器小数位宽
// 相位累加器与频率控制字
Uint32 phase_accumulator = 0;
Uint32 freq_ctrl_word = 0;
// ePWM1 ISR原型声明
interrupt void epwm1_timer_isr(void);
// ======== 主函数 ========
void main(void)
{
// 系统初始化(关闭看门狗、配置PLL至100MHz、初始化外设时钟)
InitSysCtrl();
// 初始化GPIO(配置ePWM1A为输出,按键为输入等)
InitGpio();
// 初始化PIE中断控制器及向量表
InitPieCtrl();
InitPieVectTable();
// 将ePWM1的中断服务程序(ISR)映射到向量表
EALLOW;
PieVectTable.EPWM1_INT = &epwm1_timer_isr;
EDIS;
// 初始化ePWM1为高分辨率PWM模式
// 配置TB(时基)模块:向上计数,周期为1000(对应100kHz)
EPwm1Regs.TBPRD = 1000;
EPwm1Regs.TBCTR = 0x0000;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
// 配置计数器比较(CC)模块:启用高分辨率占空比控制(HRPWM)
EPwm1Regs.CMPA.half.CMPA = 500; // 初始占空比 50%
EPwm1Regs.CMPA.half.CMPAHR = 0; // 初始高分辨率部分 0
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
// 配置AQ(动作限定)模块:在计数器=0时置高,在CMPA匹配时置低
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
// 配置HRPWM控制寄存器:启用A通道的高分辨率占空比模式
EPwm1Regs.HRCNFG.all = 0x0F; // 启用MEP控制,占空比粒度达150ps级别
// 启用ePWM1中断(在计数器归零时产生中断)
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;
EPwm1Regs.ETSEL.bit.INTEN = 1;
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;
// 启用PIE组内中断及CPU级中断
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
IER |= M_INT3;
EINT; // 开启全局中断
ERTM; // 开启实时调试模式
// 计算初始频率控制字 (假设初始频率为 1kHz)
// 公式: F_out = (F_ctrl_word * F_sampling) / (2 ^ MAX_FRACTION_BITS)
// 反推: F_ctrl_word = (Desired_Freq * (2 ^ MAX_FRACTION_BITS)) / F_sampling
freq_ctrl_word = ((Uint32)1000 * (1 << MAX_FRACTION_BITS)) / SAMPLING_FREQ;
// ======== 主循环 ========
while(1)
{
// 在此处编写按键扫描与参数更新逻辑
// 例如:如果按键触发频率+,则更新freq_ctrl_word的值
KickDog(); // 喂狗
}
}
// ======== ePWM1 中断服务程序 (DDS核心算法在此执行) ========
interrupt void epwm1_timer_isr(void)
{
Uint16 sine_index, next_sine_index;
Uint32 fraction_part;
Int32 interp_value;
Uint16 final_duty;
// 1. 更新相位累加器
phase_accumulator += freq_ctrl_word;
// 2. 提取查表索引 (使用高16位,假设SINE_TABLE_SIZE=512,需提取高9位)
// 实际操作中,BootROM正弦表地址映射需要根据TI手册调整,此处为逻辑示意
sine_index = (phase_accumulator >> (MAX_FRACTION_BITS - 9)) & 0x1FF;
// 3. 提取小数部分用于插值 (取低9位)
fraction_part = phase_accumulator & 0x1FF;
// 4. 线性插值计算 (提升波形平滑度)
next_sine_index = (sine_index + 1) & 0x1FF;
// 注:此处应从实际的SineTable[sine_index]中读取数值,假设读取函数 Read_Sine_Val()
Int32 curr_val = Read_Sine_Val(sine_index);
Int32 next_val = Read_Sine_Val(next_sine_index);
interp_value = curr_val + (((next_val - curr_val) * fraction_part) >> 9);
// 5. 将插值后的正弦数值转化为PWM占空比
// 将插值结果归一化并叠加1.5V直流偏置,形成0-3V的正弦波
// 假设 interp_value 范围是 -32768 到 32767
final_duty = 500 + (interp_value >> 7); // 粗略的比例缩放,需根据实际情况校准
// 6. 更新ePWM的高分辨率寄存器
// 注意:HRPWM的CMPAHR是高分辨率部分,此处直接将计算结果的低8位填入
EPwm1Regs.CMPA.half.CMPAHR = (final_duty << 8) & 0xFF00;
EPwm1Regs.CMPA.half.CMPA = (final_duty >> 8);
// 7. 清除中断标志位
EPwm1Regs.ETCLR.bit.INT = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}
2.2 频率控制字的计算逻辑
为了实现精确扫频,我们需要根据目标输出频率实时计算频率控制字(Frequency Control Word, FCW)。
c
// 扫频核心算法:更新频率控制字
// 输入:target_freq -> 想要输出的目标频率 (单位: Hz)
// 输出:无 (直接更新全局变量 freq_ctrl_word)
void Update_Frequency(long target_freq)
{
// 计算公式:FCW = (Target_Freq * 2^N) / Fsampling
// N = 相位累加器位宽 (此处设为32位,实际使用16位整数部分+16位小数部分)
// 为了保留小数精度,我们使用长整型运算,避免浮点数消耗过多CPU周期
// 注意:由于我们在中断中已经使用了16位分数,如果要实现1Hz步进,可能需要更大的累加器
// 此处示例简化版,实际项目中需根据采样率和精度需求调整移位位数
long long temp = (long long)target_freq * (1LL << 32);
freq_ctrl_word = (Uint32)(temp / SAMPLING_FREQ);
}
2.3 ADC采集与串口上传
c
// ADC转换完成中断服务程序 (示意)
interrupt void adc_isr(void)
{
// 1. 读取转换结果(假设使用ADCINA0通道)
Uint16 adc_value = AdcRegs.ADCRESULT0 >> 4; // 12位结果右对齐,取高12位
// 2. 转换为电压值 (0-3.3V)
float voltage = (float)adc_value * 3.3f / 4095.0f;
// 3. 发送到串口 (格式化字符串:"Freq,Voltage\r\n")
char tx_buf[50];
sprintf(tx_buf, "%ld,%.2f\r\n", current_sweep_freq, voltage);
// 调用SCI发送函数 (需根据TI库实现)
SCIa_SendString(tx_buf);
// 清除中断标志
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
参考代码 音频范围扫频仪__TMS320F2808 www.youwenfan.com/contentcst/133163.html
四、关键技术与优化
1. 高分辨率PWM(HRPWM)的应用
TMS320F2808的ePWM模块引入了微边沿定位(MEP) 技术。传统的PWM受限于时钟周期(100MHz下最小步长为10ns),而HRPWM可以将边沿控制精度提升至150ps(皮秒) 级别。这使得我们在仅使用数字PWM和低通滤波器模拟DAC时,依然能获得极高的频率纯度和极低的谐波失真(THD),完美契合音频测试对信号质量的苛刻要求。
2. 线性插值法提升波形质量
直接从512点正弦表中查表会导致输出波形呈阶梯状,引入高次谐波。通过在查表索引之间引入线性插值(Linear Interpolation),利用相位累加器被舍弃的小数部分,在两个相邻的查表值之间进行加权计算。这相当于在数字域实现了"过采样",大幅平滑了PWM占空比的跳变,使最终生成的模拟正弦波更加圆润、逼真。
3. 灵活的扫频模式切换
- 线性扫频 :频率随时间匀速增加(如20Hz →\rightarrow→ 20kHz)。适用于需要均匀覆盖整个频段的常规测试。
- 对数扫频(1/3倍频程扫频):频率按指数规律增加。由于人耳的听觉特性是对数的,对数扫频能以恒定速率扫过每一个"八度"音阶,更符合心理声学测试标准,常用于音响系统的频响测试。
五、系统调试与扩展
1. 调试步骤
| 阶段 | 操作 | 工具 |
|---|---|---|
| 硬件调试 | 测量PWM输出引脚波形,检查是否出现预期的100kHz载波与正弦包络 | 示波器、逻辑分析仪 |
| 信号质量测试 | 使用音频分析仪测量输出正弦波的频谱纯度与信噪比(SNR) | 音频分析仪、APx515测试仪 |
| 闭环测试 | 将输出直接连接到输入(自检),观察LabVIEW上显示的曲线是否为一条直线 | 上位机LabVIEW、串口调试助手 |
| 抗干扰测试 | 在输入端注入强干扰噪声,验证ADC采样算法的鲁棒性 | 信号发生器、示波器 |
2. 扩展功能
- 相位测量:利用eCAP(增强型捕获模块)测量输入与输出信号的相位差,绘制相位频率曲线。
- 自动增益控制(AGC):在软件中加入幅值反馈环路,使输出正弦波的幅值在扫频过程中始终保持恒定(1Vpp),无论负载如何变化。
- 蓝牙无线示波器:添加低成本的蓝牙串口模块,让手机APP直接接收并绘制幅频曲线,摆脱PC线缆束缚。
六、总结
基于TMS320F2808的音频扫频仪巧妙地利用了C2000系列DSP的高分辨率PWM 和强大数学运算能力,以极具性价比的硬件成本实现了原本需要昂贵台式设备(如Agilen 33220A)才能完成的音频扫频功能。该系统不仅可以作为独立的桌面测试仪器使用,其开源的代码架构和丰富的外设接口也为后续二次开发(如植入音箱箱体内部作为自动均衡器)提供了广阔的想象空间。