资讯动态

TMS320F28377D 最小信号链:ADC、DAC 与看门狗闭环设计

发布时间:2026/9/16 12:54:34 来源:尧图企业网站定制
简介面向DSP初学者与嵌入式开发者这份基于TI TMS320C28377D双核浮点数字信号处理器的压缩包是一套覆盖模数转换、数模转换与脉宽调制波形生成基础功能的示例工程。示例聚焦实时信号处理中的外设验证常用于工业控制、电机驱动、电源管理等场景能够帮助开发者快速厘清双核处理器在信号采集与输出方面的工作机制。压缩包共73个文件体积仅417KB文件以编译生成的obj目标文件、C语言源代码、CCS工程与项目配置文件、链接映射文件、可执行输出文件以及调试配置文件为主配合Code Composer Studio开发环境即可完成编译、烧写与调试。工程目录中按两个CPU划分为对应C源文件方便开发者在双核架构下对照理解模拟量采集、模拟量输出以及脉宽调制波形的产生流程掌握外设寄存器初始化、中断服务子程序配置、信号链路搭建与波形验证的关键方法。目前已有146人学习下载对刚接触28377D的开发者来说是一份体积紧凑、内容完整的入门实践资料。1. blinky_dc 带出的 28377D 最小信号链从点灯到 AD/DA 闭环在 TMS320F28377D 的 dsp 开发里一个叫 blinky_dc 的工程足以让新手摆脱“不知从哪下手”的状态也让老手能快速验证一块新板子是否能跑。它的价值不在点灯本身而在于把 GPIO、ADC 采样、DAC 回放和看门狗串成一条最小闭环灯闪证明内核活着AD 把模拟量读进来DA 再把结果送出去看门狗负责让异常状态可被看见。对电机控制、电源电路和继电保护这类要求快速确认采样链路的应用28377D 的优势恰好全落在这一条链路上。这篇博文按这个命名工程最常见的组织方式拆开讲外设怎么初始化、参数怎么设、信号完整性怎么验最后落到一个能复用的自检工具上。2. 28377D 的 AD/DA 资源先分清 12 位与 16 位、SOC 与缓冲型 DAC28377D 的 AD/DA 不能只当普通外设看它同时提供 12 位与 16 位两种 ADC 工作模式三组独立 ADC 模块以及带输出缓冲的 12 位 DAC。很多 dsp 学习阶段的同学第一次翻寄存器映射会懵——ADC 中结果寄存器为什么和触发源分开SOC 通道为什么要单独配置实际上把硬件框图读明白比背寄存器快得多。2.1 28377D 的 ADC 架构采样保持与 SOC 触发的协作关系28377D 的每个 ADC 模块带四个采样保持器S/H A 到 D每个 S/H 后可挂多个 SOC 触发通道。硬件自动排队意味着你不需要在中断服务程序里逐个轮询通道而是让 ePWM、软件或定时器按预先配置的次序触发转换。采样保持的选择直接影响并行采样能力需要同时抓电压和电流时把两条通道分别挂到 S/H A 和 S/H B 上能拿到同一时刻的两个模拟量而不是前后错开一个转换周期。这里常犯的错是只改通道号、不改触发源。比如用软件触发把 SOC0 配到 ADCINA0却没注意到上一次转换的结果还留在结果寄存器里读出来是旧值。28377D 的 ADC 转换结果寄存器在转换完成后才更新但不会自动清零所以判断“转换是否完成”非常依赖中断标志位或 ePWM 触发时刻。12 位模式与 16 位模式的区别首先是转换时钟和转换周期。项目里对速度敏感的控制环路通常用 12 位模式比如 200 MHz 主频下把 ADC 时钟配到 40 MHz 左右单次转换的建立加转换时间能控在几百纳秒量级16 位模式更适合对纹波和噪声敏感、速度要求不高的采集比如温度、母线电压缓变量。选择时还要看 S/H 的采样窗口ACQPS 寄存器位控制采样保持电容的充电时间源阻抗高就要把 ACQPS 调大否则采样值会有明显比例误差。2.2 带缓冲的 12 位 DAC直接输出还是送比较器28377D 的 DAC 是带输出缓冲的 12 位转换器负载能力比普通电压型 DAC 强可以直接驱动下一级模拟电路也可以接到片内比较器子系统作为阈值基准。很多人有个误区总觉得 DAC 输出必须经过一级运放才能接外部其实 28377D 的缓冲输出在轻载下可以直接带 ADC 输入或高阻负载只是输出纹波和建立时间的特性要单独验证。DAC 的输出路径由 DACCTL 寄存器里的 DACOEN 位控制。把 DACOEN 置 1输出才会出现在对应引脚上数据写入 DACVALS 还是 DACVALA 决定左对齐还是右对齐格式。这里的关键是写入 DACVALS 后输出不是立刻跳变的要等数微秒到数十微秒的建立时间具体取决于负载电容。软件里如果立刻读回外部 ADC 的数据很可能读到一个还没稳定下来的中间值。2.3 参考电压与供电边界配置前的三个硬约束ADC 的参考电压决定了满量程对应的电压值。28377D 支持片内参考和外部 VREFHI 引脚参考两种方式。片内参考省事但精度受温漂影响外部参考需要参考源本身比目标信号更干净。配置之前最好确认三件事。第一VREFHI 输入范围不能超过 VDDA 供电轨也不能低于指定最低参考电平实际布局里 VREFHI 引脚旁的滤波电容要靠近引脚放。第二片内参考方式下不同 ADC 模块如果共用一个带隙基准模块之间的通道串扰会比想象中明显尤其是大量 GPIO 同时翻转时。第三ADC 上电后必须跑一遍校准流程28377D 的器件支持库里通常提供 InitAdcCal 之类的函数跳过校准直接采样的后果是零点偏移和增益误差都偏大。配置点12 位模式16 位模式ADC 时钟可配到 50 MHz 量级需降低时钟以获得更长转换时间典型用途电机电流环、电源电压环温度、振动、缓慢变化的模拟量采样窗口可调 ACQPS源阻抗不大时取 10~20建议 ACQPS 相应加大结果更新完成一次转换立即更新转换时间明显更长顺手看一眼 SOC 控制字段能少踩不少坑。把 ADCSOC0CTL 拆开看低位是通道选择中位是采样窗口高位是触发源选择。一个典型配置如下AdcaRegs.ADCSOC0CTL.bit.CHSEL 0; // ADCINA0 AdcaRegs.ADCSOC0CTL.bit.ACQPS 14; // 15 个 ADC 时钟的采样窗口 AdcaRegs.ADCSOC0CTL.bit.TRIGSEL 0; // 软件触发这段代码里 CHSEL 决定采样哪条物理通道ACQPS 决定采样保持电容充电时间TRIGSEL 为 0 表示软件触发适合最开始的点灯验证。等到要接控制环路再把 TRIGSEL 改成 ePWM 对应触发源的编号让 PWM 引脚一动作就开始采样省去中断里的启停同步问题。3. 照着 blinky_dc 的路子搭最小 AD/DA 工程28377D 初始化代码与参数解析blinky_dc 这类工程在 TI 的例程包里很常见结构通常是先关看门狗、配时钟和 GPIO再初始化用到的外设最后进主循环做轮询或等中断。下面这套顺序是把点灯、ADC 采样、DAC 回放和看门狗组合在一起的最小框架编译环境用 CCS 加 TI 的 C2000 器件支持包芯片选择 TMS320F28377D。3.1 工程骨架System Init、GPIO 与时钟使能顺序初始化顺序建议固定为关看门狗、配置系统时钟、初始化 GPIO、初始化 ADC、初始化 DAC、最后再决定是否重新打开看门狗。顺序反了会出现一类很难查的问题外设上电后还没配置完就被看门狗复位反复重启但代码停在调试器的启动入口。void main(void) { // 1. 先关看门狗配置完外设后再打开 InitWatchdog(); // 2. 时钟与 GPIO 基础配置 InitSysClk(); // 外部晶振倍频到 200MHz InitGpio(); // 3. ADC 与 DAC 模块初始化 InitADC(); InitDAC(); // 4. 打开看门狗并喂一次狗 预留标识供 watchdog 复位后判断 EnableWatchdog(); for (;;) { uint16_t adcVal ReadADC(); DacaRegs.DACVALS.all (uint16_t)(adcVal 4); // 左对齐回放 KickWatchdog(); // PA5 翻转作为运行指示灯 GpioDataRegs.GPADAT.bit.GPIO5 ^ 1; DELAY_US(10000); } }主循环里做的事情很直白读 AD、写 DA、喂狗、翻灯。DACVALS 是左对齐还是右对齐取决于初始化时选择的格式这里假设左对齐所以把 12 位 ADC 结果左移 4 位再写进去。PA5 翻转用的是异或操作配合示波器或逻辑分析仪能看到灯闪频率也能判断程序是否卡死在某个循环里。3.2 ADC 采样最小配置用 ADCA 模块采一路直流ADC 部分的初始化代码核心是上电、选参考、配 SOC、使能中断。先把外设上电再配置触发和通道最后开中断。下面给出一个带注释的直接可用的片段void InitADC(void) { EALLOW; // ADC 上电和时钟预分频 AdcaRegs.ADCCTL2.bit.PRESCALE 4; // 200MHz/(41)40MHz AdcaRegs.ADCCTL1.bit.ADCPWDN 1; // ADC 内部电源上电 AdcaRegs.ADCCTL1.bit.ADCREFSEL 0; // 使用内部参考 AdcaRegs.ADCCTL1.bit.ADCENABLE 1; // 启动 ADC 逻辑 // SOC0 配置 AdcaRegs.ADCSOC0CTL.bit.CHSEL 0; // ADCINA0 AdcaRegs.ADCSOC0CTL.bit.ACQPS 14; // 采样窗口 15 个 ADCCLK AdcaRegs.ADCSOC0CTL.bit.TRIGSEL 0; // 软件触发先跑通再换 ePWM // 等待 ADC 逻辑稳定 EDIS; DELAY_US(1000); // 校准函数来自 TI 器件支持库 InitAdcCal(); EALLOW; // 使能 ADCINT1 并清标志 AdcaRegs.ADCINTSEL1N2.bit.INT1E 1; AdcaRegs.ADCINTSEL1N2.bit.INT1SEL 0; // SOC0 完成触发 INT1 AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 1; EDIS; }这段代码里 PRESCALE 的值决定了转换时钟快慢40 MHz 的 ADC 时钟对 12 位模式是够用且保守的。ACQPS 配置为 14等价于 15 个 ADC 时钟周期的采样窗口对几十欧姆以内的源阻抗足够如果信号源是高阻分压网络建议把 ACQPS 加大到 30 以上否则读数会比真实值低。InitAdcCal 的位置放在上电之后、首次转换之前因为校准结果写在专用寄存器里跑一次就行。3.3 DAC 输出最小配置把采到的值回放出去DAC 初始化比 ADC 简单只需打开电源和输出使能。但要注意 DAC 输出使能后引脚功能会从 GPIO 切到 DAC 外设所以要先确认该引脚没有复用冲突。void InitDAC(void) { EALLOW; DacaRegs.DACCTL.bit.DACOEN 1; // 使能 DACAOUT 引脚输出 DacaRegs.DACCTL.bit.DACPWEN 1; // 打开 DAC 内部电源 EDIS; }DACOEN 和 DACPWEN 是两个容易搞混的位前者控制模拟输出是否送到引脚后者控制 DAC 模块本身的电源开关。只开 DACPWEN 不开 DACOEN寄存器能写但引脚上没有电压变化。反过来只开 DACOEN 不开电源读回输出还是零。主循环里写 DACVALS 的代码看似简单但要注意数据格式DACVALS 左对齐和 DACVALA 右对齐对应不同的移位关系同一个模拟输出值用错格式会出现整体偏置或量化错误。3.4 看门狗与 PA5除了点灯最容易忽略的复位源看门狗的配置代码通常是整套例程里最短的却也最容易被删掉。28377D 的看门狗要求按 0x55、0xAA 的顺序逐步写入 WDKEY中间必须关中断否则喂狗序列被打断计数器照常递减并最终强制复位。void KickWatchdog(void) { EALLOW; WdRegs.WDKEY.bit.WDKEY 0x55; EDIS; EALLOW; WdRegs.WDKEY.bit.WDKEY 0xAA; EDIS; }喂狗函数放在主循环里会掩盖一个问题如果程序死在某个中断服务函数里主循环不再执行但看门狗计数器依然走系统照样复位这是合理的保护。如果在中断里也喂狗就需要格外小心——一旦中断频繁触发主循环卡死时看门狗可能还一直被喂错误状态反而被隐藏了。blinky_dc 这类例程的典型做法是把喂狗放在主循环中断里只做采样和数据处理这样灯闪频率和喂狗节拍能相互印证程序是否活着。4. DA 信号链调参与典型坑dsp_watchpa5 暴露的复位与跳变问题名字里的 watchpa5 通常会让人联想到看门狗和 PA5 引脚的指示作用实际调 DA 回放的时候PA5 这个灯能帮你判断三类问题程序有没有复位、喂狗节奏是否正常、AD/DA 回放是否卡在等待结果。下面这套排查顺序是我调试带 AD/DA 闭环工程时最常用的。4.1 输出跳变与建立时间改采样窗口还是 DAC 负载寄存器DA 回放中最常见的故障是输出波形有毛刺或阶梯感。先确认是不是 ADC 读数本身波动大如果是优先加大 ACQPS 采样窗口如果波形整体滞后于输入问题在 DAC 的建立时间或者后级负载容性偏大。写 DACVALS 时要特别注意写入时机。如果数据在 PWM 中断里更新两次更新之间 DAC 输出会保持原值这是正常现象但如果希望输出平滑变化可以在主循环里多次写入中间值。硬件上用示波器探头点 DACAOUT 引脚时探头电容本身就会改变波形探头尽量用 10x 衰减挡。一个容易踩的坑是把 ADC 结果直接写进 DACVALS 后却发现满量程只到一半。这通常是左右对齐错位导致12 位 ADC 结果左移 4 位后是 16 位左对齐格式DACVALS 也按左对齐解释两者才能对上。另一种可能是参考电压不一致ADC 内部参考和 DAC 参考不是同一个电平回放增益就偏了。4.2 看门狗复位的判断PA5 闪灯节奏能告诉你什么看门狗复位之后程序从入口重新执行PA5 的初始翻转节奏会发生变化。如果代码里一开始把 PA5 置高进入主循环后才开始翻转那么复位发生后的第一段灯状态和正常运行有明显差异逻辑分析仪抓一下就能区分。现象可能原因排查方式PA5 常亮不再翻转主循环卡死看门狗未复位查中断里是否死循环PA5 规律闪但偶发停顿喂狗序列被更高优先级中断打断喂狗前后短暂关中断PA5 闪动频率变慢一半看门狗复位导致重新初始化外设抓复位引脚或读复位状态寄存器DA 输出与输入不对应对齐格式或参考电压不一致分别扫 0 到满量程输入看门狗复位还有一个隐蔽来源Power-on 后系统时钟还没稳定就打开了看门狗。时钟不稳定时看门狗计数器计数也不稳定表现为上电后偶尔直接复位。处理办法是先让系统时钟稳定并完成外设初始化最后再打开看门狗。4.3 用 CCS 的 Expressions 与 Graph 验证 AD/DA 闭环CCS 调试界面里有两类工具很适合这种验证Expressions 窗口看寄存器实时值Graph 工具把一段 ADC 数据画成波形。先把程序全速跑起来暂停后打开 Expressions添加 AdcaResultRegs.ADCRESULT0 和 DacaRegs.DACVALS 两个变量手动改变输入电压看这两个值是否同步变化。Graph 工具用来观察回放波形更直观。在代码里维护一个数组每采样一次就往数组里追加一个值连续采集几百个点后暂停程序Graph 选 Time/Frequency 模式地址填数组首地址长度填数组大小。这样能直接看到 ADC 原始序列的波动和示波器看到的 DAC 输出对照就能定位是采样噪声还是 DA 重建导致的失真。5. 收尾技巧把 blinky_dc 改造成可复用的 28377D 上电自检工具到这里最小的 AD/DA 闭环已经能跑接下来把它改成一块板子的快速体检工具。这样每次焊完新板不用反复烧写不同例程一个固件就能完成基础验证。5.1 用 PA5 输出三态状态正常、警告、复位把 PA5 的驱动方式从简单翻转改成带状态的软件编码。例如程序启动后先慢闪三下表示 ADC 初始化成功再快闪五下表示 DAC 输出正常之后进入每 50 ms 翻转一次的运行态。如果 ADC 读数为满量程或零且长时间不变直接让 PA5 常亮提示硬件链路有问题。void ShowStatus(int state) { int i; for (i 0; i state; i) { GpioDataRegs.GPADAT.bit.GPIO5 1; DELAY_US(80000); GpioDataRegs.GPADAT.bit.GPIO5 0; DELAY_US(80000); } }这里的 state 是闪灯次数100 ms 一个周期肉眼很容易分辨。把初始化结果映射成不同次数比在串口里打印日志更快因为点灯逻辑不依赖任何外设初始化结果哪怕时钟配错了也能通过 LED 看到现象。5.2 三种快速验证手段第一接一个电位器到 ADCINA0从低到高缓慢旋转DA 输出的电压应该同步变化PA5 闪灯频率不变。第二把 DA 输出端接回 ADCINA1建立一条模拟回环通过多次采样计算偏差能确认两个通道之间的一致性。第三在烧写外部 Flash 后重新上电观察第一次进入主循环前 PA5 是否先完成一组慢闪若没有基本可以断定程序没有从 Flash 正确启动。这套自检固件还有一个好处做硬件调试时不需要外接调试器只要电源和 LED 就能判断大半问题。等真正需要定位复杂故障时再挂上 CCS 和仿真器把之前靠闪灯判断的结论用寄存器数据复核一遍效率比一上来就打断点高不少。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价