Tiva™ ADC采样序列与数字比较器配置详解及实战应用

发布时间:2026/7/23 15:58:37
Tiva™ ADC采样序列与数字比较器配置详解及实战应用 1. 深入解析Tiva™ ADC采样序列与数字比较器配置在嵌入式系统开发中模数转换器ADC是实现模拟信号数字化的核心外设。其工作原理是将连续的模拟电压信号通过采样、保持、量化和编码转换为微控制器可处理的数字值。ADC的技术价值在于为系统提供了感知物理世界的能力是实现智能控制、数据采集和信号处理的基础。在工程实践中高级ADC通常集成了采样序列器和数字比较器等复杂功能以提升转换效率和实时响应能力。采样序列器允许预先配置一系列采样操作而数字比较器则能实时判断转换结果是否超出预设阈值从而触发中断或事件。这些功能在Tiva™ TM4C123GE6PM等微控制器的ADC模块中得到了典型应用通过配置ADCSSOPn、ADCSSDCn等寄存器可以灵活地将采样结果路由至FIFO或数字比较器单元满足诸如电源监控、传感器阈值报警等多样化的应用场景需求。对于初次接触Tiva™ C系列微控制器的开发者来说面对多达数十个ADC相关寄存器尤其是采样序列操作ADCSSOPn和数字比较器选择ADCSSDCn这类寄存器往往会感到困惑。这些寄存器控制着采样数据流的最终去向——是进入FIFO等待软件读取还是直接送入数字比较器进行实时判决。理解并正确配置它们是解锁ADC高级功能、实现高效、可靠数据采集系统的关键。本文将基于Tiva™ TM4C123GE6PM的数据手册深入剖析ADC采样序列结果FIFO、状态寄存器以及采样序列操作与数字比较器选择寄存器的配置逻辑并结合实际代码示例分享我在多个工业传感项目中积累的配置心得与避坑指南。2. ADC采样序列结果FIFO与状态寄存器详解在深入配置数据流向之前我们必须先理解ADC转换结果的存放与状态管理机制。Tiva™的ADC模块为每个采样序列器Sequencer 0-3配备了一个专用的结果FIFOFirst In, First Out寄存器。这是ADC数据管道的终点站之一也是软件获取转换结果最常规的途径。2.1 结果FIFO寄存器ADCSSFIFOn工作机制根据数据手册ADC0和ADC1各有四个采样序列器对应四个结果FIFO寄存器ADCSSFIFO0偏移0x048、ADCSSFIFO1偏移0x068、ADCSSFIFO2偏移0x088和ADCSSFIFO3偏移0x0A8。这些寄存器都是只读的复位后值为未定义。每个FIFO寄存器宽度为32位但只有低12位位[11:0]的DATA字段有效用于存放12位的ADC转换结果。高20位是保留位读取时返回0并且在执行读-修改-写操作时必须保持其值不变这是为了与未来产品兼容。这里有一个至关重要的细节这些FIFO寄存器是“读敏感”的。这意味着每一次对该寄存器的读取操作都会影响FIFO的内部状态——具体来说会使内部的“尾指针”递增从而将下一个数据项移动到可读位置。你可以把它想象成一个自动售货机的出货口每读取一次相当于按一次出货按钮就有一瓶饮料一个转换结果被推出来。如果你读取的速度跟不上ADC转换并填充FIFO的速度就会发生“溢出”Overflow反之如果你在FIFO为空时还去读取就会发生“下溢”Underflow。这两种错误状态会分别记录在ADCOSTAT溢出状态和ADCUSTAT下溢状态寄存器中供软件查询。注意在实际编程中我强烈建议在启动ADC转换序列前先连续读取对应的FIFO寄存器直到其空以清空可能存在的旧数据。同时在中断服务例程或主循环中读取数据时务必先检查FIFO状态寄存器的EMPTY位避免下溢。这是一个非常容易忽略但会导致数据错乱的坑。2.2 FIFO状态寄存器ADCSSFSTATn的妙用仅仅有FIFO数据寄存器还不够我们还需要一个“仪表盘”来实时监控FIFO的状态。这就是ADC采样序列FIFO状态寄存器ADCSSFSTATn的作用。ADC0和ADC1各有四个这样的寄存器偏移地址分别为0x04C、0x06C、0x08C和0x0AC。该寄存器复位后的值是0x0000.0100。这个值很有讲究EMPTY位第8位为1表示FIFO为空FULL位第12位为0表示FIFO未满HPTR头指针位[7:4]和TPTR尾指针位[3:0]都为0表示读、写指针都指向索引0的位置。这清晰地定义了一个FIFO的初始空闲状态。FULL位12与EMPTY位8这两个位提供了FIFO容量状态的快速快照。FULL1表示FIFO已满新的转换结果将无法写入可能导致数据丢失。EMPTY1表示FIFO为空此时读取将获得未定义数据并触发下溢。在编写数据采集程序时我通常采用中断驱动方式配置采样序列在转换完成时触发中断在中断服务程序中循环读取FIFO直到EMPTY位变为1。这样可以确保一次性取走所有有效数据效率最高。HPTR头指针位[7:4]与TPTR尾指针位[3:0]这两个指针揭示了FIFO内部的详细状态。HPTR指向下一个将要被写入的位置写指针TPTR指向下一个将要被读取的位置读指针。它们的具体取值范围取决于采样序列器Sequencer 0FIFO深度为8因此HPTR和TPTR的有效范围是0x0到0x7。Sequencer 1 2FIFO深度为4有效范围是0x0到0x3。Sequencer 3FIFO深度为1有效值只能是0x0。通过比较HPTR和TPTR软件可以精确计算出FIFO中当前存有多少个未读数据项。公式为数据项数 (HPTR - TPTR) (FIFO深度 - 1)。例如对于深度为8的FIFO0如果HPTR5TPTR2则未读数据项为(5-2)73个。这个功能在实现DMA直接存储器访问传输或需要精确控制数据缓冲区的应用中非常有用。3. 采样序列操作寄存器ADCSSOPn配置解析理解了数据存放的“仓库”和“仪表盘”后我们来到第一个决策点采样得到的数据到底要不要放进这个仓库这就是ADC采样序列操作寄存器ADCSSOPn要解决的问题。它决定了每次转换的结果是存入对应的FIFO还是被“劫持”并发送到数字比较器单元。3.1 寄存器结构与位域定义Tiva™为四个采样序列器分别提供了操作寄存器ADCSSOP0偏移0x050、ADCSSOP1偏移0x070、ADCSSOP2偏移0x090和ADCSSOP3偏移0x0B0。它们的结构类似但支持的采样点数不同这与其对应的采样序列器能力相匹配。以功能最全的ADCSSOP0控制Sequencer 0支持最多8个采样为例其位域定义非常清晰S0DCOP(位0): 控制第一个采样点的操作。S1DCOP(位4): 控制第二个采样点的操作。S2DCOP(位8): 控制第三个采样点的操作。S3DCOP(位12): 控制第四个采样点的操作。S4DCOP(位16): 控制第五个采样点的操作。S5DCOP(位20): 控制第六个采样点的操作。S6DCOP(位24): 控制第七个采样点的操作。S7DCOP(位28): 控制第八个采样点的操作。每个SnDCOP位只有两种设置0该次采样的转换结果保存到对应的采样序列FIFO中例如Sequencer 0的结果存入ADCSSFIFO0。这是最常规的模式软件后续可以从FIFO中读取该值。1该次采样的转换结果不进入FIFO而是被直接发送到由ADCSSDCn寄存器指定的数字比较器单元进行处理。这是一个关键点一旦设置为1这个采样值对软件就“不可见”了除非你通过数字比较器触发的事件间接知道它。对于ADCSSOP1和ADCSSOP2控制Sequencer 1和2各支持最多4个采样它们只有S0DCOP到S3DCOP这四个控制位分别对应第一个到第四个采样点。 对于ADCSSOP3控制Sequencer 3只支持1个采样则只有S0DCOP这一个控制位。3.2 应用场景与配置策略这个寄存器的配置直接体现了“数据路由”的思想。在实际项目中我主要遇到两种典型应用模式模式一纯数据采集模式这是最常见的情况。你需要连续、稳定地获取多个通道的ADC值比如循环采集4个温度传感器的数据。此时将所有SnDCOP位都设置为0。配置好采样序列通过ADCSSMUXn选择通道ADCSSCTLn配置采样属性并触发后所有结果都会按顺序存入FIFO软件只需按序读取即可。这种模式逻辑简单可靠性高。模式二混合模式FIFO存储 比较器触发这是发挥Tiva™ ADC高级功能的关键。例如在一个电池监控系统中你可能需要持续采集电池电压通道0结果存入FIFO用于计算平均电压和电量。同时你需要实时监控电池电压是否超过安全上限比如4.2V一旦超过必须立即触发保护动作这个响应速度要求是微秒级的。这时你就可以这样配置Sequencer 0假设使用8序列模式采样0S0配置为采集电池电压通道0S0DCOP 0结果存入FIFO0。采样1S1同样配置为采集电池电压通道0但S1DCOP 1并将ADCSSDC0寄存器中的S1DCSEL字段设置为指向一个已配置好上限值对应4.2V的数字码的数字比较器单元比如Comparator 0。这样每次序列执行时第一个采样值进入FIFO供软件处理第二个采样值则直接送给数字比较器0。如果电压超限比较器会立即产生中断或触发信号系统可以极快地响应。而软件仍然可以从FIFO中获取常规采样数据实现了监控与数据记录的解耦。实操心得在配置ADCSSOPn时一定要和ADCSSCTLn采样控制寄存器中的END位序列结束位配合好。END位标记了序列的终点。假设你在一个8步序列中第5步S4设置了END1那么即使你为S5、S6、S7配置了DCOP位这些步骤也不会被执行。因此确保你的DCOP配置只在有效的采样步骤上生效。4. 采样序列数字比较器选择寄存器ADCSSDCn配置解析当你在ADCSSOPn寄存器中将某个采样点的SnDCOP位设置为1后紧接着就必须回答下一个问题这个采样值要送给哪一个数字比较器这就是ADC采样序列数字比较器选择寄存器ADCSSDCn的职责。4.1 寄存器结构与位域映射与ADCSSOPn寄存器一一对应我们有ADCSSDC0偏移0x054、ADCSSDC1偏移0x074、ADCSSDC2偏移0x094和ADCSSDC3偏移0x0B4。以ADCSSDC0为例它为Sequencer 0的8个采样点分别指定了目标比较器S0DCSEL(位[3:0]): 为第一个采样点当S0DCOP1时选择数字比较器单元。S1DCSEL(位[7:4]): 为第二个采样点选择数字比较器单元。S2DCSEL(位[11:8]): 为第三个采样点选择数字比较器单元。S3DCSEL(位[15:12]): 为第四个采样点选择数字比较器单元。S4DCSEL(位[19:16]): 为第五个采样点选择数字比较器单元。S5DCSEL(位[23:20]): 为第六个采样点选择数字比较器单元。S6DCSEL(位[27:24]): 为第七个采样点选择数字比较器单元。S7DCSEL(位[31:28]): 为第八个采样点选择数字比较器单元。每个SnDCSEL字段是一个4位值其编码直接对应8个数字比较器单元之一0x0到0x7。每个数字比较器单元都有一套独立的控制寄存器ADCDCCTLn和比较值寄存器ADCDCCMPn用于设置比较条件如大于、小于、在范围内等和阈值。ADCSSDC1和ADCSSDC2寄存器则只包含S0DCSEL到S3DCSEL字段对应Sequencer 1和2的4个采样点。ADCSSDC3只包含S0DCSEL字段对应Sequencer 3的单个采样点。4.2 配置逻辑与多路复用技巧这个寄存器的配置逻辑相对直接但其中蕴含了强大的灵活性。一个采样序列中的不同采样点可以路由到同一个数字比较器也可以路由到不同的比较器。这允许你实现复杂的监控逻辑。举个例子假设你用Sequencer 0实现一个多通道监控系统采样0通道0电池电压S0DCOP0存入FIFO。S0DCSEL值无关因为DCOP0。采样1通道0电池电压S1DCOP1S1DCSEL0x0送给数字比较器0设置过压阈值如4.2V。采样2通道1充电电流S2DCOP1S2DCSEL0x1送给数字比较器1设置过流阈值。采样3通道2环境温度S3DCOP0存入FIFO。采样4通道2环境温度S4DCOP1S4DCSEL0x2送给数字比较器2设置高温报警阈值。这样在一个自动执行的采样序列中你同时完成了对电池电压和环境温度的常规采集存入FIFO。对电池电压的实时过压监控通过比较器0。对充电电流的实时过流监控通过比较器1。对环境温度的实时高温监控通过比较器2。任何一项超标对应的数字比较器都会立即产生中断系统响应延迟极低。而常规数据则按部就班进入FIFO供后台任务进行更复杂的分析和记录。重要提示ADCSSDCn寄存器的配置仅在对应的ADCSSOPn寄存器中SnDCOP位为1时才生效。如果SnDCOP0那么SnDCSEL字段的值会被硬件忽略。在初始化时一个良好的习惯是即使你计划将所有采样都存入FIFO所有DCOP0也最好将ADCSSDCn寄存器清零以避免任何意外的未定义行为。5. 采样序列输入与控制的联动配置要构建一个完整的采样序列除了决定数据的去向ADCSSOPn/ADCSSDCn还必须定义数据的来源和采集方式。这涉及到另外两组寄存器采样序列输入多路选择器ADCSSMUXn和采样序列控制寄存器ADCSSCTLn。它们与操作/选择寄存器共同构成了采样序列的完整配置。5.1 输入多路选择器ADCSSMUXn配置ADCSSMUXn寄存器负责为序列中的每一个采样点选择具体的模拟输入通道。Tiva™ TM4C123GH6PM有两个ADC模块ADC0和ADC1每个ADC有最多12个外部模拟输入通道AIN0-AIN11以及内部温度传感器等信号源。以支持4个采样点的ADCSSMUX1Sequencer 1为例它是一个32位寄存器但只使用低16位每4位一个“半字节”控制一个采样点的输入选择MUX0(位[3:0]): 选择第一个采样点的模拟输入。值0x0对应AIN00x1对应AIN1以此类推。特定值用于选择内部传感器如温度传感器。MUX1(位[7:4]): 选择第二个采样点的模拟输入。MUX2(位[11:8]): 选择第三个采样点的模拟输入。MUX3(位[15:12]): 选择第四个采样点的模拟输入。对于支持8个采样的Sequencer 0其ADCSSMUX0寄存器使用全部32位每4位控制一个采样点MUX0到MUX7。而对于只支持1个采样点的Sequencer 3其ADCSSMUX3寄存器仅使用最低4位MUX0。配置示例假设你想用Sequencer 1循环采集三个电位器的电压分别在AIN2, AIN3, AIN4上并采集一次内部温度传感器。你可以这样配置ADCSSMUX1MUX0 0x2// 采样点0 - AIN2MUX1 0x3// 采样点1 - AIN3MUX2 0x4// 采样点2 - AIN4MUX3 0x?// 采样点3 - 温度传感器具体值需查数据手册例如可能是0xE5.2 采样控制寄存器ADCSSCTLn核心位解析ADCSSCTLn寄存器为序列中的每个采样点提供了精细的控制。每个采样点对应寄存器中的4个控制位对于4采样点序列器使用低16位8采样点序列器使用全部32位。这4个位是Dn (差分输入选择)置1表示对该采样点使用差分输入模式。此时对应的ADCSSMUXn字段应设置为差分对编号i例如0对应AIN0和AIN1这对差分输入。重要限制当同时启用温度传感器TSn1时Dn位必须为0因为温度传感器不支持差分模式。ENDn (序列结束标志)这是必须正确设置的关键位。在一个采样序列中你必须且只能在一个采样点将ENDn置1以标记序列的终点。硬件在转换完带有ENDn1的采样点后就会停止该序列即使后面定义了更多的采样点也不会执行。这允许你动态改变序列长度。IEn (中断使能)置1后当该采样点的转换完成时ADC模块会置位原始中断标志。如果ADC中断屏蔽寄存器ADCIM中对应的位也被使能则会向NVIC产生中断。一个序列中的多个采样点都可以使能中断这在需要精确知道每个采样点转换完成的时刻时非常有用。TSn (温度传感器选择)置1表示该采样点采集内部温度传感器电压而非ADCSSMUXn选择的引脚。此时MUXn和Dn位的配置应符合温度传感器的要求通常MUXn需设为特定值Dn必须为0。联动配置示例延续上面的多路选择器示例我们配置ADCSSCTL1来控制Sequencer 1的四个采样点采样点0 (AIN2)D00单端,END00,IE00不单独中断,TS00- 控制字0x0采样点1 (AIN3)D10,END10,IE10,TS10-0x0采样点2 (AIN4)D20,END20,IE20,TS20-0x0采样点3 (温度传感器)D30必须,END31序列结束,IE31转换完成时产生中断,TS31- 控制字0xE(二进制1110即D0, END1, IE1, TS1)因此写入ADCSSCTL1寄存器的值应为(0xE 12) | (0x0 8) | (0x0 4) | 0x0 0xE000。这样每次触发Sequencer 1它会依次采集AIN2、AIN3、AIN4最后采集温度传感器并在温度传感器转换完成后产生中断。在中断服务程序中你可以从ADCSSFIFO1中按顺序读取四个结果。6. 数字比较器复位与初始化关键操作在灵活运用采样序列将数据路由至数字比较器后我们必须关注数字比较器单元本身的初始状态管理。ADC数字比较器复位初始条件寄存器ADCDCRIC偏移0xD00就是为此而生的一个特殊寄存器。它是一个只写WO寄存器任何读取操作都返回0。6.1 寄存器功能与位域说明ADCDCRIC寄存器的功能非常专一将指定的数字比较器中断或触发逻辑复位到其初始条件。它包含两组控制位DCINT0 - DCINT7 (位[7:0])分别对应数字比较器单元0到7的中断逻辑复位。向某一位写入1会复位对应比较器的中断状态机清除任何挂起的比较条件。复位完成后该位由硬件自动清零。DCTRIG0 - DCTRIG7 (位[23:16])分别对应数字比较器单元0到7的触发逻辑复位。向某一位写入1会复位对应比较器的触发状态机。同样复位完成后硬件自动清零。6.2 为什么必须进行复位初始化数据手册中明确警告“Because the digital comparators use the current and previous ADC conversion values to determine when to assert the trigger/interrupt, it is important to reset the digital comparator to initial conditions when starting a new sequence so that stale data is not used.”这是理解数字比较器工作的一个核心要点。许多数字比较器模式例如“窗口比较”、“变化率检测”可能需要用到当前值与前一次值的比较。如果不在开始一个新的监控任务前复位比较器那么残留在其内部状态机中的“上一次转换值”可能是来自完全无关的、很久之前的某次转换这会导致首次比较逻辑错误可能产生误触发或漏触发。一个真实的踩坑案例在一个电机电流监控项目中我使用数字比较器0来检测过流大于阈值。系统上电初始化后我配置好了比较器阈值和模式并启动了ADC采样序列。但在系统启动后的第一次采样电流明明正常却立即触发了过流中断。排查良久才发现问题就在于我没有在启动采样序列前复位数字比较器。比较器内部残留的“前次值”是一个随机数与第一次采样的正常电流值进行比较恰好满足了触发条件。在添加了ADCDCRIC (1 0); // 复位比较器0中断逻辑这行代码后问题消失。6.3 正确的复位操作流程配置前复位在配置数字比较器控制寄存器ADCDCCTLn和比较值寄存器ADCDCCMPn之前建议先复位对应的比较器单元。这确保了你在一个干净的状态下进行配置。序列开始前复位在每次启动或重新启动一个会将数据路由至数字比较器的ADC采样序列之前必须复位所有将要使用到的比较器单元。这是防止使用陈旧数据的关键。操作方式复位操作是通过向ADCDCRIC寄存器的对应位写1完成的。由于这是只写寄存器且硬件会自动清零所以你无法通过回读来检查复位是否完成。标准的做法是执行写入操作后插入一个短暂的延时例如几个NOP指令以确保硬件有足够时间完成复位操作。// 假设要使用数字比较器0和1 HWREG(ADC0_BASE ADC_O_DCRIC) (1 0) | (1 1); // 复位比较器0和1的中断逻辑 HWREG(ADC0_BASE ADC_O_DCRIC) (1 16) | (1 17); // 复位比较器0和1的触发逻辑 // 简短延时 SysCtlDelay(3); // 接下来配置比较器或启动ADC序列注意SysCtlDelay(n)函数会产生大约n * 3个CPU周期的延时。对于这种硬件复位操作一个很小的延时就足够了。7. 完整配置流程与实战代码示例将上述所有寄存器知识串联起来我们来看一个完整的实战场景使用ADC0的采样序列器1Sequencer 1实现一个双通道交替采集与实时监控系统。通道0(AIN2): 监控电源电压常规采集存入FIFO同时其值送数字比较器0进行欠压检测3.0V。通道1(AIN3): 监控负载电流常规采集存入FIFO同时其值送数字比较器1进行过流检测1.5A。采用序列器1的4步采样模式在第4步采集后结束序列并触发ADC中断。在中断服务程序中读取FIFO数据并检查数字比较器中断状态。以下是基于TivaWare驱动库的配置代码示例及详细解析#include stdint.h #include stdbool.h #include inc/hw_memmap.h #include inc/hw_types.h #include driverlib/adc.h #include driverlib/gpio.h #include driverlib/pin_map.h #include driverlib/sysctl.h #include driverlib/interrupt.h // 假设电压、电流与ADC值的换算关系已定义 #define ADC_VREF 3.3f #define ADC_MAX_CODE 4095 #define UNDER_VOLTAGE_THRESHOLD (int)((3.0f / ADC_VREF) * ADC_MAX_CODE) // 3.0V对应的数字码 #define OVER_CURRENT_THRESHOLD (int)((1.5f / ADC_VREF) * ADC_MAX_CODE) // 1.5A对应的数字码(假设1A1V) void ADC1_Seq1_Config(void) { // 1. 使能外设时钟 SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // 假设AIN2/AIN3在PE端口 while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0)); // 2. 配置GPIO引脚为模拟输入 GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2 | GPIO_PIN_3); // 3. 复位并初始化数字比较器关键步骤 // 先复位比较器0和1的中断与触发逻辑清除陈旧状态 HWREG(ADC0_BASE ADC_O_DCRIC) (1 0) | (1 1); // 复位中断逻辑 HWREG(ADC0_BASE ADC_O_DCRIC) (1 16) | (1 17); // 复位触发逻辑 SysCtlDelay(10); // 短暂延时确保复位完成 // 4. 配置数字比较器单元0用于欠压检测 // 设置比较值当ADC结果 UNDER_VOLTAGE_THRESHOLD 时触发 ADCComparatorConfigure(ADC0_BASE, 0, ADC_COMP_TRIG_NONE, ADC_COMP_INT_ALWAYS, ADC_REF_INT); ADCComparatorRegionSet(ADC0_BASE, 0, 0, UNDER_VOLTAGE_THRESHOLD); // 低阈值设为0高阈值设为欠压阈值 // 配置为“小于”模式结果 高阈值 时满足条件 ADCComparatorConfigure(ADC0_BASE, 0, ADC_COMP_TRIG_NONE, ADC_COMP_INT_ALWAYS, ADC_COMP_INT_LOW_HIGH); // 5. 配置数字比较器单元1用于过流检测 // 设置比较值当ADC结果 OVER_CURRENT_THRESHOLD 时触发 ADCComparatorConfigure(ADC0_BASE, 1, ADC_COMP_TRIG_NONE, ADC_COMP_INT_ALWAYS, ADC_REF_INT); ADCComparatorRegionSet(ADC0_BASE, 1, OVER_CURRENT_THRESHOLD, ADC_MAX_CODE); // 低阈值设为过流阈值高阈值设为满量程 // 配置为“大于”模式结果 低阈值 时满足条件 ADCComparatorConfigure(ADC0_BASE, 1, ADC_COMP_TRIG_NONE, ADC_COMP_INT_ALWAYS, ADC_COMP_INT_LOW_HIGH); // 6. 配置采样序列器1Sequencer 1 ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0); // 处理器触发优先级0 // 配置采样步骤0AIN2存入FIFO并路由至比较器0 ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH2 | ADC_CTL_D0 ); // D00: 存入FIFO // 注意TivaWare库的ADCSequenceStepConfigure函数默认将结果存入FIFO。 // 要路由到比较器需要额外配置ADCSSOP和ADCSSDC寄存器。 // 配置采样步骤1AIN2不存FIFO路由至比较器0用于欠压实时比较 ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH2 | ADC_CTL_D0 ); // 配置采样步骤2AIN3存入FIFO ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH3 | ADC_CTL_D0 ); // 配置采样步骤3AIN3不存FIFO路由至比较器1用于过流实时比较并结束序列、使能中断 ADCSequenceStepConfigure(ADC0_BASE, 1, 3, ADC_CTL_CH3 | ADC_CTL_D0 | ADC_CTL_IE | ADC_CTL_END); // 7. 手动配置ADCSSOP1和ADCSSDC1寄存器实现步骤1和3的路由 // 步骤1 (S1) 路由到比较器0步骤3 (S3) 路由到比较器1 // ADCSSOP1: 设置S1DCOP1, S3DCOP1. 寄存器偏移0x070. // Bit4对应S1DCOP, Bit12对应S3DCOP. HWREG(ADC0_BASE ADC_O_SSOP1) (1 4) | (1 12); // ADCSSDC1: 设置S1DCSEL0 (比较器0), S3DCSEL1 (比较器1). 寄存器偏移0x074. // Bits[7:4]对应S1DCSEL, Bits[15:12]对应S3DCSEL. HWREG(ADC0_BASE ADC_O_SSDC1) (0x0 4) | (0x1 12); // 8. 使能ADC序列器1中断 ADCIntEnable(ADC0_BASE, 1); IntEnable(INT_ADC1SS0); // 序列器1的中断向量是INT_ADC1SS0 IntMasterEnable(); // 9. 使能序列器1 ADCSequenceEnable(ADC0_BASE, 1); } void ADC1_Seq1_ISR(void) { uint32_t status; uint32_t adc_values[4]; // 存储从FIFO读取的值 int i 0; // 获取中断状态并清除 status ADCIntStatus(ADC0_BASE, 1, true); ADCIntClear(ADC0_BASE, 1); if(status ADC_INT_SS1) { // 序列器1中断 // 读取FIFO中所有有效数据 while(!ADCSequenceDataGet(ADC0_BASE, 1, adc_values[i]) i 4) { // ADCSequenceDataGet在FIFO为空时返回false i; } // 此时adc_values[0]是步骤0的AIN2值adc_values[1]是步骤2的AIN3值。 // 步骤1和3的值被送往比较器不在FIFO中。 // 检查数字比较器中断状态 uint32_t dc_status ADCComparatorIntStatus(ADC0_BASE, 0); ADCComparatorIntClear(ADC0_BASE, 0, dc_status); // 清除已触发的中断 if(dc_status ADC_COMP_INT_ID0) { // 比较器0中断欠压 // 执行欠压保护动作如关闭负载、报警等 HandleUnderVoltage(); } if(dc_status ADC_COMP_INT_ID1) { // 比较器1中断过流 // 执行过流保护动作如切断电源、报警等 HandleOverCurrent(); } // 处理采集到的常规数据 adc_values[0], adc_values[1]... ProcessADCValues(adc_values, i); // 重新触发序列器1开始下一次采集如果是单次触发模式则需软件重新触发 ADCProcessorTrigger(ADC0_BASE, 1); } }代码关键点解析与避坑指南复位顺序代码中先复位数字比较器再对其进行配置。这是一个好习惯确保了配置前状态机是干净的。库函数与直接寄存器操作结合TivaWare库提供了便捷的函数如ADCSequenceStepConfigure来配置采样步骤但它主要面向将结果存入FIFO的常规场景。对于“路由到数字比较器”这个高级功能库函数没有直接封装因此我们必须通过直接写ADCSSOP1和ADCSSDC1寄存器来实现。这是混合编程的典型例子。中断处理中断服务程序ISR中我们首先读取FIFO数据。由于步骤1和3的结果被路由到比较器它们不会出现在FIFO中所以实际读到的数据量可能小于4。然后我们检查并清除数字比较器的中断标志。务必先读取FIFO数据再重新触发序列以避免数据覆盖或丢失。阈值计算UNDER_VOLTAGE_THRESHOLD和OVER_CURRENT_THRESHOLD的计算基于参考电压和ADC分辨率。在实际项目中需要考虑传感器的变比、放大电路增益等因素进行校准。比较器模式配置ADCComparatorConfigure和ADCComparatorRegionSet的调用顺序和参数设置需要仔细对照数据手册。示例中配置了比较器0为“值小于高阈值”触发比较器1为“值大于低阈值”触发。通过这样一个完整的配置我们实现了一个高效的监控系统常规数据通过FIFO进入主循环或后台任务处理关键的报警条件通过数字比较器实现硬件级实时响应极大地提高了系统的可靠性和响应速度。这正是Tiva™ ADC采样序列与数字比较器联动配置的核心价值所在。

相关新闻

最新新闻

日新闻

周新闻

月新闻