ADC采样与模拟信号处理实践
本专题基于星球中 ADC 配置、ADC+DMA 协同与模拟前端相关的问答整理,覆盖从引脚前端到软件架构的完整采样链路。
一、三种转换模式要分清
STM32 ADC 的模式选择容易混淆,星主的梳理是(老师,请问ADC中如果连续装换模式和单次转换模式都失能,会发生什么,Jack):
- 连续转换模式(Continuous):对某一通道不停地转换,DR 寄存器数据持续更新、EOC 标志不断产生,可用轮询或中断持续取数。
- 单次转换(连续与非连续都失能):每个触发事件(如调用
HAL_ADC_Start())只执行一次转换,适合信号有建立时间、必须在特定时刻采样才精准的场景。 - 非连续转换模式(Discontinuous):把配置的通道序列分成若干小组(每组 1~8 个通道),每次触发只转换一个小组。例如 6 通道序列、Discontinuous Number = 2,则分成 3 组,需 3 次触发才能完成全部通道——适合控制系统中"每个控制周期只采部分通道"以减轻 CPU 负担。
另外两个常一起出现的概念:scan 模式指自动依次转换多个通道;注入通道与规则通道的区别与各自适用场景是常见疑问点(老师,adc 的注入通道和规则通道有什么区别,分别在什么场景下用,这是一个好听的id 提问)。
二、ADC + DMA 的配合机制
- DMA 循环模式的意义是"连续不断响应 ADC 的 DMA request"。不开 ADC 连续模式就没必要开 DMA 循环模式;每个(或每组)通道转换完成产生 EOC,即发出 request 通知 DMA 搬运(老师请问开启dma的循环模式必须配合adc的连续模式使用,Jack)。
- 使用
HAL_ADC_Start_DMA时,"ADC 转换完成回调"实际是嵌套在 DMA 传输完成回调里被调用的——能进回调就说明数据已搬完,可打断点观察内存验证(老师,还有一个问题,你们给的参考例程中,为什么这里使用adc转换完成的中断回调,Jack)。 - 多路 ADC 并行:在 ADC1 的转换完成回调里去启动 ADC2,各自 buffer 分开存放即可;DMA 不用特殊处理,绑定对应 ADC 后 request 会自动搬运(多路adc实现adc+dma并,Jack)。
- 双 buffer 切换风险:buffer 满了但还没来得及在中断里通知线程切换就出错。实践结论:测试时测出数据峰值,把 buffer 空间一次设足;嵌入式产品绝不在运行时 malloc(adc+dma,双buffer,我们在a线程进行切换的时候,Jack)。
三、模拟前端:为什么要加跟随器
电压采样不能拿分压电阻直接怼到 ADC 引脚:采样模块内部阻抗不够时,采样瞬间会有电流倒流回信号源,污染被测信号。加一级电压跟随器,一方面实现阻抗隔离,另一方面增强信号驱动能力,使 ADC 采集行为不影响原信号源(我想问,采样ad为什么要加跟随器,不能直接分压加到采样模块,Jack)。
四、软件架构:前端与后端
从架构层面,ADC/串口这类数据采集设备分为(软件架构层面来说: ADC:,Jack):
- 前端(靠近中断、最高优先级):做数据分发,分显式双 buffer 与隐式双 buffer;
- 后端:做解包,分原地解包与异地解包。
内核级优化方向包括中断延时优化、总线优化、中断向量表优化;中断上半部做"指针穿透、减少冗余判断",下半部落地为双 buffer 与流 buffer(详细展开见 数据缓冲与解包: 以串口为例,Jack)。把中断向量表重定位到 RAM 也是 ADC 这类高速应用提升整体性能的常用手段(重定位的用处: 1.进入用户空,Jack)。
五、工程思考:多通道多任务的采样任务设计
一个真实提问:ADC1 的 8 个通道分别测气压(3 路)、PT100 加热器温度(3 路)、气管流量(2 路),数据要滤波并分别提供给 3 个上层应用,是设计 1 个任务统一采 8 通道,还是 3 个任务各采各的?(大佬好,假设我ADC1里面8个通道都要用上,有3个通道用来测不同气管的压力,权 提问)
结合本目录的架构共识可推演:硬件上 8 通道共享同一个 ADC 序列(scan + DMA 循环搬运),软件上由一个 Handler 统一接收 DMA 数据,再按通道拆分、滤波后经队列分发给 3 个业务线程——即"前端统一采集、后端按业务解包分发",避免 3 个任务争抢同一 ADC 外设。
来源笔记
- 老师,请问ADC中如果连续装换模式和单次转换模式都失能,会发生什么 | Jack
- 老师,adc 的注入通道和规则通道有什么区别,分别在什么场景下用 | 这是一个好听的id
- 老师请问开启dma的循环模式必须配合adc的连续模式使用 | Jack
- 老师,还有一个问题,你们给的参考例程中,为什么这里使用adc转换完成的中断回调 | Jack
- 多路adc实现adc+dma并 | Jack
- adc+dma,双buffer,我们在a线程进行切换的时候 | Jack
- 我想问,采样ad为什么要加跟随器,不能直接分压加到采样模块 | Jack
- 软件架构层面来说: ADC: | Jack
- 数据缓冲与解包: 以串口为例 | Jack
- 重定位的用处: 1.进入用户空 | Jack
- 大佬好,假设我ADC1里面8个通道都要用上,有3个通道用来测不同气管的压力 | 权