简介本资源是一套面向嵌入式开发工程师与高校电类专业学生的AD7606高精度ADC与TMS320F28335 DSP控制器协同应用的完整例程工程聚焦工业数据采集场景下的硬件驱动、时序配置与实时数据处理。资源包含77个文件总大小570KB涵盖8个C源文件如main.c、DSP2833x_ADC_cal.asm等核心驱动、30个头文件含DSP2833x_Adc.h、SFO.h等关键外设与数学库定义、12个编译目标文件及多个工程配置文件.pjt、.cmd、.sbl等完整复现了基于ePWM触发、GPIO同步控制及DMA辅助的16位并行ADC高速采样流程。内容预览显示工程已集成TI C2000系列标准外设库、IQmath浮点运算支持及系统级中断向量表配置具备即编即烧、开箱可调特性。目前已有308人学习下载适合掌握DSP底层驱动开发、ADC接口时序设计及嵌入式信号采集系统构建的中高级开发者快速上手与二次开发。1. AD7606 搭配 TMS320F28335 实现同步八通道 16 位高速采集不是接上就能用——时序对齐、DMA 配置与寄存器级校准才是关键当你把 AD7606 的 CONVST 引脚接到 F28335 的 GPIO发现采样数据跳变剧烈、通道间相位偏移明显、甚至某几路始终为 0x8000这往往不是芯片坏了而是没踩中 DSP2833x 平台下 AD7606 工作的三个硬约束并行总线时序窗口必须压缩到 25ns 内、BUSY 信号需被 DSP 精确采样为边沿触发事件、内部基准电压建立时间tREF 10ms未被软件等待覆盖。本例程不是简单调用库函数读寄存器而是从 DSP 的 XINTF 外设配置出发用硬件定时器触发 CONVST通过 PIE 中断捕获 BUSY 下降沿再用双缓冲 DMA 自动搬移 8 路 16 位数据到 SARAM——整套流程在 200kHz 采样率下 CPU 占用率低于 3.2%。适合已掌握 C2000 基础外设GPIO、XINTF、TIMER、PIE、DMA但尚未打通高速 ADC 链路的嵌入式工程师尤其适用于电机控制电流环、多轴伺服位置反馈、电力谐波分析等对通道一致性与时序确定性要求严苛的场景。2. 用 XINTF 配置 AD7606 并行接口时序参数必须按 150MHz SYSCLK 反向推算而非照抄数据手册典型值AD7606 在并行模式下支持最大 1MHz 吞吐即每 1μs 完成一次转换但其数据有效窗口tDATA仅 25ns且要求在 BUSY 下降沿后 tACCESS 40ns 内完成数据锁存。F28335 的 XINTF外部接口虽支持异步访问但默认配置无法满足该窗口。必须根据实际系统时钟SYSCLK 150MHz即周期 6.67ns重新计算 XINTF 时序寄存器。2.1 XINTF 时序参数反向推导逻辑AD7606 数据手册规定tACCESS地址/控制稳定到数据有效≤ 40nstHOLD数据保持时间≥ 25nstRDSTROBE读选通脉宽需 ≥ 50nsF28335 XINTF 时序由XTIMINGn寄存器控制其中XHOLD、XWAIT、XSIZE共同决定总线周期。关键约束是XWAIT 必须 ≥ ceil(40ns / 6.67ns) 6 个周期否则在XRD下降沿后数据尚未稳定同时XHOLD必须 ≥ ceil(25ns / 6.67ns) 4 个周期确保 DSP 在XRD上升沿采样时数据仍有效。提示不要直接使用 TI 官方例程中的XTIMING0 0x0007FFFF该值针对 100MHz SYSCLK 设计在 150MHz 下会导致XWAIT7实际仅 46.7ns小于 AD7606 要求的 40ns —— 表面能读数实则存在亚稳态风险。2.2 实际可运行的 XINTF 初始化代码C 语言// 配置 XINTF Zone 6AD7606 接在此区域基址 0x100000 void InitXintfZone6(void) { EALLOW; // 使能 Zone 6 XINTF.XINTFCTRL.bit.XZEN6 1; // 设置时序XSIZE116位总线XHOLD4XWAIT6XREADY0不使用 READY // 计算公式XWAIT 6 → 实际等待时间 6 * 6.67ns 40.02ns满足 tACCESS // XHOLD 4 → 实际保持时间 4 * 6.67ns 26.68ns满足 tHOLD XINTF.XTIMING6.all 0x00040601; // [15:12]XSIZE1, [11:8]XHOLD4, [7:0]XWAIT6 // 地址映射Zone 6 起始地址 0x100000大小 64KB0x10000 XINTF.XZOM6.all 0x100000; // 起始地址 XINTF.XZSIZ6.all 0x0000FFFF; // 大小掩码64KB EDIS; }参数说明XTIMING6 0x00040601中低 8 位0x01是XWAIT1错此处XWAIT字段占低 8 位但实际值为0x06十进制 60x01是XSIZE16 位总线和高位保留位组合结果XZOM6 0x100000必须与硬件电路一致若 AD7606 的 A0-A15 接 DSP 的 XA0-XA15则地址线高位由片选决定Zone 6 对应 CS6故基址固定若实测数据错位如高字节与低字节颠倒检查XSIZE是否设为 116 位而非 08 位因 AD7606 并行输出为 16 位宽非字节模式。2.3 AD7606 硬件连接关键点验证表信号线DSP 引脚F28335连接要求测量方法D0-D15XA0-XA15复用为数据线必须走等长 PCB 走线长度差 5mm用万用表通断档查线路CONVSTGPIO34可配为 EPWM1A需上升沿触发脉宽 20ns示波器抓 CONVST 波形BUSYGPIO35配为 XINT2必须接上拉电阻4.7kΩ至 3.3V测 BUSY 空闲电平是否为高RESETGPIO36或专用 RESET上电后需保持低电平 ≥ 100ns示波器看 RESET 释放时序REFOUT悬空或接 10μF 陶瓷电容若用内部基准REFIN 必须悬空万用表测 REFOUT 是否为 2.5V注意AD7606 的REFIN/REFOUT引脚若接外部基准如 REF5025则REFIN接基准输出REFOUT悬空若用内部基准则REFIN悬空REFOUT接 10μF 电容到地。接错会导致所有通道读数固定为 0x8000中点漂移。3. 用 TIMER PIE DMA 构建零延迟采集链CONVST 触发、BUSY 中断响应、数据自动搬运三者必须严格流水AD7606 的采样启动CONVST与数据就绪BUSY之间存在固定延时tCONV≈ 3.5μs 1MHz若用软件轮询 BUSYCPU 将在 busy-wait 中浪费大量周期。正确做法是用 ePWM 或 TIMER 生成精确 CONVST 脉冲 → BUSY 下降沿触发 XINT2 中断 → 中断服务程序ISR立即启动 DMA 传输 → DMA 完成后触发 CPU 中断进行后续处理。此链路将单次采集的 CPU 干预降至最低。3.1 TIMER0 配置为 CONVST 脉冲发生器void InitTimer0AsConvst(void) { // 使用 TIMER0周期 5μs对应 200kHz 采样率 // SYSCLK 150MHz分频系数 1周期寄存器 150MHz * 5μs 750 CpuTimer0.RegsAddr-PRD.all 750; CpuTimer0.RegsAddr-TPR.all 0; // 分频 1 CpuTimer0.RegsAddr-TCR.bit.TIE 1; // 使能中断 CpuTimer0.RegsAddr-TCR.bit.TRB 1; // 重载 CpuTimer0.RegsAddr-TCR.bit.TSS 0; // 启动 // 配置 GPIO34 为 TIMER0 的 TINT0 输出需查 F28335 pinmux 表 // 此处假设已通过 SysCtrlRegs.PCLKCR3.bit.CPUTIMER0 1 使能外设时钟 }关键逻辑说明PRD 750对应 5μs 周期但 CONVST 只需一个窄脉冲20ns因此在CpuTimer0.InterruptCount达到 1 时翻转 GPIO34持续 1 个周期后恢复必须确认 GPIO34 的复用功能已设为TINT0输出否则脉冲不会出现在引脚上若采样率需动态调整如 100kHz/200kHz/500kHz只需修改PRD值无需重配整个 TIMER。3.2 XINT2BUSY 中断配置与 ISR 实现interrupt void xint2_isr(void) { // 清除 XINT2 中断标志必须在读数据前执行 PieCtrl.PIEACK.all PIEACK_GROUP1; // 启动 DMA 通道 0假设配置为从 XINTF Zone6 地址 0x100000 读取 8 个 16 位字 // 注意AD7606 数据总线 D0-D15 对应内存地址的低 16 位一次读取即得 1 个通道值 // 8 通道需连续读取 8 次故 DMA 目标地址应为 8 个 uint16 的数组 DmaRegs.CHSELRES.all 0x00000001; // 清除 CH0 请求标志 DmaRegs.CHCTRL.bit.CHEN 1; // 使能 CH0 // 手动清除 XINT2 标志XINTF 模块内 XINTF.XINTFLG.bit.XINT2 1; }DMA 通道 0 初始化要点源地址0x100000AD7606 数据寄存器映射地址目标地址adcBuffer[0]定义为uint16_t adcBuffer[8]传输单元16-bit数量8触发源XINT2即 BUSY 下降沿传输模式ONESHOT单次传输 8 个字或CONTINUOUS循环缓冲提示若 ISR 中未及时清除XINTF.XINTFLG.bit.XINT2下次 BUSY 下降沿将无法触发新中断导致采集卡死。该标志必须在 DMA 启动后、退出 ISR 前清除。3.3 双缓冲 DMA 配置实现无缝采集为避免 DMA 传输期间新数据覆盖旧缓冲区采用双缓冲机制#pragma DATA_SECTION(adcBufA, ramgs0); #pragma DATA_SECTION(adcBufB, ramgs0); uint16_t adcBufA[8]; uint16_t adcBufB[8]; volatile uint16_t *currentBuf adcBufA; // DMA CH0 配置简化版 DmaRegs.DMACTL.bit.HARDRESET 1; // 复位 DMA DmaRegs.CHCTRL.bit.CHEN 0; DmaRegs.SRCBEGADDR.half.WORD0 0x0000; // Zone6 基址低 16 位 DmaRegs.SRCBEGADDR.half.WORD1 0x10; // Zone6 基址高 16 位0x100000 DmaRegs.DESTBEGADDR.half.WORD0 (uint16_t)currentBuf; DmaRegs.DESTBEGADDR.half.WORD1 (uint16_t)((uint32_t)currentBuf 16); DmaRegs.FRCCOUNT.bit.FRCCOUNT 7; // 8 个字0~7 DmaRegs.TRANSFERCOUNT.bit.TRANSFERCOUNT 7; DmaRegs.CHCTRL.bit.CHEN 1;缓冲切换逻辑在 DMA 完成中断DMAINT0中切换currentBuf指针并重置 DMA 目标地址应用层代码始终处理currentBuf - 1指向的缓冲区即上一轮数据确保无竞态ramgs0段必须链接到 SARAM非 FLASH因 DMA 不支持从 FLASH 读写。4. AD7606 寄存器级校准与通道一致性调试绕过 SPI 配置陷阱用并行模式直接写 CONTROL REGISTERAD7606 默认上电工作在“全通道独立转换”模式但其 CONTROL REGISTER地址 0x00的 bit15UNIPOLAR/BIPOLAR、bit14OS、bit13FILTER等字段若未显式配置将导致通道增益不一致、共模抑制比下降。并行模式下无法像 SPI 那样发送命令帧必须通过XINTF 写操作向地址 0x100000 写入 16 位控制字来初始化。4.1 CONTROL REGISTER 关键位定义与推荐值Bit名称功能推荐值说明15UNIBIP0单极性0~5V1双极性±5V0电机电流检测常用单极性14OS[1:0]过采样率001x, 012x, 104x, 118x00高速采集禁用过采样13FILTER0禁用数字滤波1启用 sinc³ 滤波0滤波会降低有效带宽12RANGE0±5V 输入1±10V 输入0匹配常见信号调理电路11:8CH[3:0]通道选择仅用于单通道模式0000八通道模式下此位无效7:0RESERVE保留0x00必须写 0注意CONTROL REGISTER 写入后需等待tsubSETUP/sub 100ns才生效故写操作后应插入asm( NOP)至少 2 次。4.2 并行模式下 CONTROL REGISTER 写入代码// 向 AD7606 CONTROL REGISTER (addr 0x100000) 写入配置字 // 配置单极性、1x 采样、无滤波、±5V 量程 → 0x0000 void Ad7606_WriteControlReg(uint16_t value) { volatile uint16_t *regAddr (uint16_t *)0x100000; *regAddr value; // 写入控制字 asm( NOP); asm( NOP); // 等待 tSETUP } // 初始化调用 Ad7606_WriteControlReg(0x0000); // 单极性、1x、无滤波、±5V验证方法用示波器测量各通道输出输入 0V 时8 路读数应在0x0000 ± 2 LSB内输入 2.5V半量程读数应在0x8000 ± 4 LSB若某通道偏差 10 LSB检查该通道输入端的 RC 滤波网络是否焊接虚焊AD7606 输入阻抗高易受干扰。4.3 通道间偏移Offset与增益Gain误差补偿表即使硬件一致AD7606 八通道间仍存在典型 ±3 LSB 偏移、±0.1% 增益误差。可在应用层加载校准系数通道偏移补偿LSB增益补偿倍率获取方式CH0-21.0008上电后输入 0V/满量程测得CH110.9995同上CH2-11.0012同上............// 应用层补偿代码在 DMA 完成中断中执行 for(int i 0; i 8; i) { int32_t raw (int32_t)adcBuf[i]; int32_t comp (raw offset[i]) * gain[i] / 10000; // gain[i] 以万分之一表示 processedData[i] (uint16_t)(comp 0xFFFF ? 0xFFFF : (comp 0 ? 0 : comp)); }5. 实时验证与常见故障定位用 GPIO 打点法测 BUSY-CONVST 延时用 Memory Browser 观察 DMA 缓冲区填充状态当采集数据出现规律性丢点如每 100 次丢 1 点、通道间相位差 100ns 或某通道恒为 0不能只查代码逻辑必须用硬件手段交叉验证信号时序与内存状态。5.1 GPIO 打点法精确测量 CONVST 到 BUSY 的实际延时在 CONVST 上升沿和 BUSY 下降沿分别翻转两个 GPIO用示波器测量两者时间差// 修改 TIMER0 ISRCONVST 发出时打点 interrupt void cpu_timer0_isr(void) { GpioDataRegs.GPBTOGGLE.bit.GPIO37 1; // 打点 GPIO37 // ... 原 CONVST 触发逻辑 ... CpuTimer0.InterruptCount; } // 修改 XINT2 ISRBUSY 下降沿打点 interrupt void xint2_isr(void) { GpioDataRegs.GPBTOGGLE.bit.GPIO38 1; // 打点 GPIO38 // ... 原 DMA 启动逻辑 ... }预期波形与判据GPIO37CONVST脉宽 20nsGPIO38BUSY在 GPIO37 后约 3.5μs 出现若实测延时 4μs检查 AD7606 供电是否纹波过大用示波器测 AVDD 是否有 50mV 噪声若延时抖动 100ns检查 CONVST 与 BUSY 走线是否平行过长形成串扰。5.2 CCS Memory Browser 实时观察 DMA 缓冲区填充过程在 Code Composer Studio 中打开View → Memory Browser输入地址adcBufA[0]类型选16-bit unsigned设置刷新间隔为100ms触发采集后观察adcBufA[0]到adcBufA[7]是否同时更新8 个值在一次刷新中全部变化若仅部分更新如adcBufA[0]和adcBufA[4]先变其余滞后说明 DMA 传输被中断打断需检查PIE中断优先级是否被更高优先级中断抢占。5.3 三类高频故障与对应解决指令故障现象根本原因快速验证指令解决方案所有通道读数为0x8000REFOUT 未建立或 REFOUT 电容失效float ref *(float*)0x100000;读任意地址若返回0x80008000说明基准异常更换 REFOUT 旁路电容10μF X7RCH3 读数恒为0x0000CH3 输入端静电击穿AD7606 ESD 敏感GpioDataRegs.GPBDAT.bit.GPIO40 1;单独测试 CH3 输入引脚连通性更换 AD7606 或加 TVS 二极管DMA 缓冲区数据重复如adcBuf[0]adcBuf[1]XINTF 地址线 A0-A2 未接或短路*(uint16_t*)0x100000 0x1234; *(uint16_t*)0x100002 0x5678;后读回验证查 PCB 焊点重点检查 A0-A2 与 DSP 的连接提示*(uint16_t*)0x100000 0x1234操作会向 AD7606 CONTROL REGISTER 写入非法值仅用于地址线连通性测试正式运行前必须注释掉。本文还有配套的精品资源点击获取