简介:STM32F373 SDADC开发资料包,面向以STM32F373为主控的嵌入式开发者,针对该芯片独有的16位逐次逼近型SDADC外设,提供从驱动初始化到多通道同步采集的完整参考工程。压缩包共159个文件,约3.16MB,以c源码、h头文件及axf/hex编译输出为主,并含uvproj工程配置、map映射表与lst列表文件,可直接在MDK环境中打开查看运行结果。资源详细覆盖启动转换、采样保持、逐次逼近比较及结果读取等关键流程,支持独立模式、双模式与多通道模式,并附自动校准与噪声抑制配置思路,便于快速移植到传感器读取、工业数据采集等项目中。已有1866人学习下载,适合正在调试SDADC精度或需要双通道同步采样方案的工程师参考。
1. 直接切入:STM32F373 SDADC 解决的是高精度小信号测量的最后一公里
STM32F373 的 SDADC 是内置的 16 位 Sigma-Delta 模数转换器,和普通 MCU 上的 12 位 SAR ADC 完全是两个物种。它面向的是毫伏级甚至微伏级的小信号:称重传感器、电桥、电流采样电阻两端压降、热电偶冷端补偿这类场景。很多人一听到高精度就跑到外部挂一颗专用 ADC 芯片,其实 F373 内部这三路 SDADC 足以把信号采到 16 位有效分辨率,前提是配置对了。这篇文章不兜圈子,直接讲清楚它是怎么工作的、代码怎么写、数据怎么算、哪些地方容易踩坑。适合做传感器变送器、仪表和电池检测的开发者,也适合想从外部 ADC 省回成本和面积的老手。
2. SDADC 的原理与选型:同样是 ADC,为什么这颗芯片能省掉外部调理芯片
2.1 Sigma-Delta 的过采样与噪声整形:看着慢,其实赢在精度
传统 SAR ADC 的精度由内部比较器和分压电阻阵列决定,分辨率做到 16 位以上,成本、面积和功耗都会很难看。Sigma-Delta 是另一条路子:先用很低的精度(比如 1 位)对模拟量做高频采样,再把大量原始采样点做数字滤波,从而换回高分辨率。这个过程有两个关键词:过采样和噪声整形。过采样把所有量化噪声均匀摊到很宽的频谱里,噪声整形再把其中的大部分推到高频段,最后经过数字低通滤波器,留在信号频带内的噪声就非常小了。
这个原理带来一个直接结果:SDADC 的有效位数高,但输出速率慢。F373 内部 SDADC 的 16 位分辨率并不是每个转换周期都能读出一个满 16 位有效数字,而是靠持续累加的过采样结果换来的。所以把它当成“高速采集器”用基本会失望,但当成“精密称重传感器采集器”则刚好合适。这一点在做选型时必须先有这个预期。
和普通 ADC 相比,SDADC 还天然适合差分输入。差分结构抑制共模干扰的能力极强,现场有电机、继电器、开关电源的环境里,信号线稍微长一点,单端测量很容易被共模噪声拉偏,差分测量则稳得多。F373 的 SDADC 每个通道都可以配置成单端或差分,这比很多外置高精度 ADC 需要单独搭前端运放和差分电路灵活不少。
从噪声角度看,Sigma-Delta 的调制器对时钟抖动比较敏感,所以 SDADC 的时钟一定要干净。这里说的干净不是格外的低抖动晶振,而是避免让数字总线的翻转边沿直接耦合到 SDADC 时钟线。很多开发者把 SDADC 当作一个大号普通 ADC 用,忽略了时钟域的隔离,结果有效位数比数据手册标称低不少,还不容易定位。调试时可以用示波器看 SDADC 时钟波形,观察上升沿是否有明显毛刺。
Sigma-Delta 还有个容易被忽略的点:它存在“建立时间”的概念。因为输出是数字滤波器对一串采样的累积结果,信号突变后要经过若干次采样,读数才会稳定到新值上。应用层不能像读普通 ADC 那样读一次就认为实时,特别是做连续采集并用来做阈值判断时,要留出足够的收敛时间。这个特性也让 SDADC 更适合慢变信号,而非阶跃响应要求苛刻的控制回路。
2.2 F373 的 SDADC 单元结构与通道:三个独立 ADC 能怎么用
F373 一共有 3 个独立的 SDADC 单元,编号 SDADC1、SDADC2、SDADC3。每个单元有 8 个外部输入引脚和 1 个内部通道,内部通道可以把基准电压引出来做自测,这个功能在产线自检和精度验证时非常好用。三个单元之间是真正独立的,可以并行采集三路通道,也可以配成互不干扰的三组传感器测量。
通道本身支持单端和差分两种连接,差分时两个引脚一对儿。信号进入调制器之前会经过可编程增益级,常见的配置是 1、8、16、32 倍这几个档。这一点非常关键:外部信号如果是 5V 电桥缩下来的几 mV 电压,直接用增益 1 去采,分辨率会浪费大半,用 32 倍把信号放大到接近参考电压的摆幅,才能把 16 位分辨率吃满。
工程师选择用 F373 的 SDADC,最常见理由就是省掉外部仪表放大器。因为 PGA 和 ADC 在同一个芯片里,前端只需要一个抗混叠 RC 滤波,外加必要的低输出阻抗驱动,信号链路就成立了。相比外挂 24 位 Sigma-Delta ADC 芯片还要配 SPI 解码、隔离和调理电路,F373 的方案在 BOM 成本和板子面积上都有明显优势。代价是它的绝对精度和低温漂参数不如专业计量级 ADC,但大多数工业传感器场景,16 位有效分辨率已经足够。
三个 SDADC 是各自独立的时钟和采样配置,不是三个共享一个时序。这个独立性意味着你可以同时运行三种不同的增益、采样速率和滤波配置,比如一路采电桥低速信号,另一路采振动传感器相对高速信号,这在应用层非常灵活。要注意的是,三个单元虽然独立,但参考电压和供电是共用的。如果某一路的前端有大信号干扰,会在电源和基准上影响到其他路,所以模拟电源平面和基准走线仍然要按整体信号链来设计。
内部通道是另一个值得优先了解的资源。它不需要外部引脚,直接把内部基准电压连接到调制器输入端,可以用于运行时自检和精度评估。比如开机时测量内部基准,判断值是否落在理论区间,如果偏差大就说明芯片或电源异常。这个通道的增益配置和外部通道一致,用起来没有额外门槛,稍后文章里我会演示如何用它验证整块板子的有效位数。
2.3 选型对比:什么时候用 F373 SDADC,什么时候外挂 24 位 ADC
有时候不是 F373 不好,而是普通 ADC 更合适。做一个简单的选型对比:
| 维度 | F373 SDADC | 普通 12 位 SAR ADC | 外挂 24 位 Sigma-Delta ADC |
|---|---|---|---|
| 分辨率 | 16 位 | 12 位 | 24 位 |
| 集成度 | 内置 PGA + 差分输入 | 低,通常需要外部运放 | 部分自带 PGA,但需额外芯片和通信接口 |
| 输出速率 | 慢,适合低频 | 快,适合高速采样 | 慢,类似 F373 SDADC |
| 低温漂和长稳 | 中等 | 中等 | 更优 |
| 成本 | 较低 | 较低 | 高,多了芯片和布板成本 |
| 典型场景 | 传感器变送器、电桥、电池检测 | 电机电流、高速波形 | 计量级仪器、称重仪表 |
从这张表看,F373 SDADC 的优势区间不在“绝对精度最高”,而在“够用精度 + 高集成度”。如果产品目标是工业仪表,精度要求 16 位足够,那么用 F373 能省掉一整颗外部 ADC 和相关外围,同时减少 SPI 通信的数据解析工作。如果目标是贸易计量秤,要求低温漂和长时间稳定度,就应该上外部 24 位方案,这时 F373 的 SDADC 反而属于浪费功夫。
选型时还有一个容易忽视的点:供电和参考电压。SDADC 的性能与参考电压的干净程度强相关。如果板子上只有一个通用的 3.3V 电源,没有单独的模拟基准,那么即便 SDADC 硬件再好,最终精度也不会高。不要把 ADC 芯片的“16 位”和系统端“能稳定采集到 16 位”直接画等号,电源噪声和参考源漂移都会吃掉有效位数。
选型完成后,下一步就会进入工程配置。这部分看似简单,但 SDADC 的外设初始化顺序和普通 ADC 差异很大,下面的篇幅我会把它从引脚到读值的完整链路拆开讲。
3. 用 SDADC 跑通一路高精度采集:初始化、校准与读取的最小工程
3.1 引脚与时钟配置:模拟通道不是随便连的
首先要把 GPIO 配置成模拟模式。很多人习惯把所有引脚初始化成复用推挽或者开漏,到了 SDADC 就会出现采样值乱跳或者通道串扰。模拟模式意味着输入缓冲和施密特触发器都被禁用,引脚呈现高阻模拟输入,这样才能让外部模拟信号完整地进入采样网络。
时钟方面,SDADC 和普通 ADC 共用一个总线时钟还是各自独立,需要看图工具里 SDADC 时钟树的默认连接。我一般会让 SDADC 时钟工作在厂商建议的频率范围内,这个范围在数据手册的“SDADC characteristics”表里写得非常清楚。时钟高了噪声变大,低了输出速率变慢,把模块时钟配到上限附近再结合过采样率来控制最终数据率,是常用的思路。
引脚布局上还要注意:差分输入的通道对是固定搭配的,不能用任意两根引脚拼一对。想换引脚就得换通道号,而不是靠代码硬配。这点容易在画板时忽略,导致最后只能飞线。画 PCB 前就把 SDADC 通道和引脚绑定关系放在原理图标注里,能省掉后续很多麻烦。
模拟通道之间也存在串扰风险。如果两个相邻通道一个接的是微弱信号,另一个接的是快速翻转的脉冲,布局上没能拉开距离,微弱信号那一通道的读数就会周期性跳动。这种问题在代码层几乎无解,只能回到板卡布局上处理,比如把干扰通道放到另一个 SDADC 单元去。
3.2 代码实现:校准之后再启动转换,顺序别搞反
拿到一个干净的工程后,第一步不是读数据,而是校准。F373 的 SDADC 内置线性校准和偏移校准两个步骤,校准顺序不能反过来,一般流程是先做线性校准,再做偏移校准,都完成后才开始转换。很多刚上手的开发者跳过校准直接读,读出来的数据确实有“东西”,但零点偏差可能达到几百个 LSB,看起来像芯片坏了。
下面这段是常见做法,基于厂商 HAL 库,函数名以你所用的库包为准:
/* SDADC1 配置示例:单端输入,增益8,通道0 */ SDADC_HandleTypeDef hsdadc1; SDADC_ChannelConfTypeDef sConfig; hsdadc1.Instance = SDADC1; /* 公共模式必须和需求对应,这里用单端模式 */ hsdadc1.Init.CommonMode = SDADC_COMMON_MODE_SINGLE_END; /* 增益8,适合几十mV量级信号 */ hsdadc1.Init.Gain = SDADC_GAIN_8; HAL_SDADC_Init(&hsdadc1); sConfig.Channel = SDADC_CHANNEL_0; sConfig.Differential = SDADC_DIFFERENTIAL_DISABLE; HAL_SDADC_ChannelConfig(&hsdadc1, &sConfig, 0); /* 第一步:线性校准 */ HAL_SDADC_CalibrationStart(&hsdadc1); HAL_SDADC_PollForCalibration(&hsdadc1, 1000); /* 第二步:偏移校准 */ HAL_SDADC_CalibrationStart(&hsdadc1); HAL_SDADC_PollForCalibration(&hsdadc1, 1000); /* 校准完成后启动单次转换并读取 */ uint16_t raw; HAL_SDADC_Start(&hsdadc1); HAL_SDADC_PollForConversion(&hsdadc1, 1000); raw = HAL_SDADC_GetValue(&hsdadc1);这段代码的逻辑是先初始化外设结构体,把 SDADC1 设置成单端输入和 8 倍增益,然后配置通道。通道配置函数里那个最后的参数,在部分 HAL 版本里代表超时或优先级,具体要看库的注释。校准调用两次,代表线性校准和偏移校准,每次等到校准完成的标志位置位后再进行下一步。
参数说明上,单端模式和差分模式直接影响满量程电压范围,单端时输入相对引脚之间是正值,差分时允许双极性负值。增益 8 意味着输入信号被放大 8 倍后再进入调制器,等效满量程变为参考电压除以 8,因此小信号也能占用较大数字码范围。如果你手里是 100mV 量级信号,增益 8 是合理起步值;如果是 1V 级信号,用增益 1 就好。
读出来的 raw 值是原始码,还不是物理电压。单端模式下,把它乘上参考电压再除以满量程码,才能换算成实际电压。数据格式上,SDADC 的输出默认是二进制补码,负输入会读出负数数值,转换为有符号数时要用 int16 类型,而不是 uint16。这一点在下一章细说。
HAL_SDADC_GetValue 返回值宽度取决于具体库的设计,有的版本返回 24 位右对齐,有的版本返回 16 位有效数据。拿到数据后先打印原始值,改变输入电压看数值是否跟着单调变化,确认方向正确,再做换算,这是我在调试时必做的第一件事。
3.3 从参考电压和增益推导满量程:数值计算别靠猜
很多人在代码跑通后卡在“读回的数不知道对应多少伏”。其实这个关系很简单:单端输入的满量程电压等于参考电压除以增益。如果你用的参考电压是固定的,那么增益越大,满量程越小,同样一个 100mV 信号在增益 8 时占的码值范围会大很多。
举个例子:参考电压 Vref 为 2.5V,增益 1 时满量程是 2.5V,一个 50mV 信号只占满量程的 2%,对应 16 位码值里只有大约 1300 个码;同一信号在增益 32 时,等效满量程约 78mV,50mV 信号占满量程 64%,码值一下增加到 42000 左右,精度表现完全不同。所以当外部信号摆幅非常小,优先提高增益而不是怀疑 ADC 坏了。
推导满量程时还要注意差分模式。差分输入的正负摆幅是围绕某个公共电压展开的,最大正输入和最小负输入之间的总范围是满量程。很多人在做电桥测量时选了差分,却用单端的公式去算,结果换算出来的电压偏了一半。建议把通道模式和增益写进配置结构体,在换算代码里同时带上这两个参数,避免算法和配置脱节。
4. 把精度榨出来:增益、采样率、数据换算与滤波
4.1 增益档位与量程设计:小信号和大信号用同一套代码会翻车
很多照着配置能跑通的人,最后发现测量精度远低于标称值,问题十有八九出在增益选错。增益 1 时满量程可能覆盖 0 到好几伏,你把一个最大只有 20mV 的信号直接送进去,ADC 只会用一个很小的码区表示它,有效位数被白白丢掉了。反过来,增益 32 时信号放大器饱和,大电压输入会把前端削顶,读数变成一块平整的直线。
选增益的正确思路是让被放大后的信号峰峰值占到满量程的 70% 到 90%。以 16 位分辨率为例,如果满量程是 4096mV,信号是 20mV,用增益 1 时信号只占约 0.5% 的码空间,等效有效位数只有 8 位左右;用增益 32,信号放大到 640mV,占满量程 15% 以上,精度明显改善。但增益越大,前端噪声也被放大,所以不是倍增档,而是要结合传感器输出阻抗和噪声水平做权衡。
不同档位的偏移误差也不同。校准是在选定增益后进行的,一旦运行中动态切换增益,原先的校准值可能不适用了。我见过有个开发者在一次测试里来回切增益,读数越来越飘,最后发现是没在切换后重新校准。如果你确实需要多档增益,建议要么做成手动切换并每次重启校准,要么为每个增益档位保存校准值,需要时重新写入。
采样率设置也要和增益匹配。Sigma-Delta 的过采样率越高,截止频率越低,对前端噪声的抑制越好,但输出数据率越低。低速高增益场景(比如称重传感器)通常用高过采样率,换来的有效分辨率会高很多。如果追求速度,有效位数会下降,这是数据手册里列出的对应关系,设计前应先确定需要的信号带宽,再反推采样率和增益组合。
4.2 数据换算与格式:16 位不是直接读出来的数字
SDADC 输出的原始值要换算成物理量,需要区分数据格式和参考电压。F373 的 SDADC 数据寄存器是 24 位,但有效分辨率不是直接等于 24 位。实际有效位数,也就是 ENOB,是测出来的,不是看位数标称。读出的原始码可能是左对齐或右对齐,取决于你配置的数据格式。代码里如果用 unsigned short 接收,很容易把负数补码读成很大的正数,导致换算结果完全错误。
单端模式下的换算公式,我一般写作:
voltage = (raw_signed / 32768.0) * (Vref / Gain)这里的 raw_signed 是把读取值强制转换为 int16 位或 int32 位后的有符号数,Vref 是当前参考电压,Gain 是实际生效的增益。差分模式时,满量程范围变成正负 Vref/Gain,所以公式里 FSR 换成全摆幅,其余逻辑一样。这样算出电压后再交给漂移补偿和工程量换算逻辑,数据链路就完整了。
强调一个低级但常见的坑:读取结果寄存器的指针类型。如果库函数返回的是 uint32_t 指针指向的寄存器值,千万不要直接赋值给 unsigned short 再按“原始值”用。SDADC 的 24 位数据在寄存器里可能靠左或靠右存放,具体看参考手册里的 SHIFT 位。按错了移位方向,零点和满量程附近都会出问题。稳妥做法是先用已知电压校准一下,观察换算值是否线性。
4.3 数字滤波的落地实现:在 MCU 端再做一层平滑
Sigma-Delta 调制器输出的码流经过片内数字滤波器后已经有一定平滑效果,但实际应用中我还是建议在 MCU 端再做一次滑动平均或一阶低通。原因在于读数往往含有低频波动的成分,只靠片内滤波滤不干净。滑动平均适合信号变化慢的场景,比如温度、应变,窗口长度选 4 到 16 个点,效果立竿见影。
/* 简单滑动平均滤波器,窗口长度为 8 */ #define FILTER_WINDOW 8 static int32_t samples[FILTER_WINDOW]; static uint8_t index = 0; static int32_t sum = 0; int32_t moving_average(int32_t new_value) { sum -= samples[index]; /* 去掉最旧的值 */ samples[index] = new_value; /* 存入新值 */ sum += new_value; /* 累加当前窗口 */ index = (index + 1) % FILTER_WINDOW; return sum / FILTER_WINDOW; /* 返回平均结果 */ }这段代码的逻辑是一个标准的环形缓冲滑动平均。每进来一个新采样值,就把当前窗口里最旧的那个值从累加和中减掉,再加进新值,最终除以窗口长度 8 得到平均值。这个滤波器能显著压低随机噪声,对阶跃信号则会产生固定延时,窗口越长延时越大。
参数上,窗口长度 8 是我在传感器采集里常用的起点。窗口太长会拖慢响应,窗口太短滤波效果不明显。如果你的信号是 10Hz 以内变化,ADC 输出速率在 1kSPS 左右,窗口 8 到 16 点可以接受。如果你要拿这个数据做快速过流保护,窗口 8 都嫌多,这时更应该靠模拟硬件滤波来扛噪声,而不是软件一味平滑。
滤波也会影响控制回路的稳定性。如果你后面还要做 PID 闭环,过重的滤波会引入相位延迟,轻则控制超调,重则系统震荡。我通常先把原始数据录下来,离线用不同滤波长度对比信噪比和上升时间,再敲定一个合适的滤波器参数。别一上来就套 IIR 低通,后面调试时会非常被动。
5. SDADC 使用避坑:从启动失败到数据飘的 5 条血泪经验
5.1 启动与校准相关的坑:复位之后先校准再使能,否则数据是歪的
现象:把 SDADC 按普通 ADC 的流程初始化后直接读,每次上电读到的零点都不一样,差值能有几十到几百个码,而且把输入短接后仍然有读出随机值。
原因:SDADC 内部有模拟校准电路,上电后校准寄存器里的值不是默认有效状态。不执行校准就启动转换,零点偏移和线性误差都没有被修正,数据自然不靠谱。
解决:上电初始化后先执行线性校准,再执行偏移校准,等待校准完成标志位后再启动转换。如果代码里跳过了某个校准步骤,补齐即可。注意校准必须在设定好通道配置之后做,因为校准值依赖当前增益和通道配置。还有一种更隐蔽的坑:代码在 main 函数里先启动了转换,之后才调校准函数,等于校准后启动、校准前已经转换,最终读数时好时坏。
现象:切换增益档位后读数持续漂移,稳定不下来。
原因:不同增益档位的内部失调不同,校准值并不能跨增益共用。在运行中切换增益后,寄存器里的校准结果已经不是当前增益对应的值了。
解决:任何增益切换之后都应该重新跑一遍校准流程,不要觉得“开关一下就没问题”。如果应用需要频繁切增益,建议把校准做成状态机的一部分,每次切换后阻塞校准完成,再放行数据读取。
现象:SDADC 转换完成标志位一直不置位,程序卡死在等待函数里。
原因:最常见的是时钟配置错误。SDADC 的时钟没有被正确开启,或者时钟分频选到了超出工作范围的值,导致片上数字滤波器没有运转。其次是通道编号越界或通道配置函数被调用两次,把内部状态改乱了。
解决:先检查 RCC 里 SDADC 外设时钟是否使能,再检查时钟树的最终输出频率是否在手册规定范围内。把配置流程打印出来,逐一核对初始化顺序:时钟、GPIO、SDADC 基础参数、通道参数、校准、启动。任何一个环节失败,后面都会卡住。
5.2 信号调理相关的坑:低输入阻抗和高增益是两回事
现象:裸测 SDADC 时读数正常,接上传感器后读数偏低,而且传感器和 ADC 之间的连接线一碰读数就跳。
原因:SDADC 的采样网络是开关电容结构,等效输入阻抗比较低。传感器如果是高输出阻抗(比如某些压电传感器或高阻电桥),信号会在内部采样电容上被“吃掉”一部分,导致衰减。增益越高,等效阻抗越低,这和高精度外部 ADC 的设计完全不同,很多人想当然地把它和常见的逐次逼近 ADC 前端混为一谈。
解决:在传感器和 SDADC 之间加一级低输出阻抗的缓冲放大器。单位增益运放就可以,重点是把源阻抗降下来。如果不想加运放,应优先选高增益档,并通过 RC 滤波把高频阻抗影响降到最低。还有一种方法是用差分输入,把传感器输出端接成差分对,共模干扰会被抑制,衰减也会对称一些。
现象:SDADC 读数毛刺很多,波形上时常出现单个点跳变,而且看起来没什么规律。
原因:最常见的是布线引入的开关噪声,或者是模拟地与数字地没有分开,驱动 GPIO 翻转时产生的电流尖峰耦合到了模拟输入。另一个常见原因是 SDADC 的时钟没有做去抖,板子上时钟走线过长或穿过数字区域。
解决:把 SDADC 的模拟输入引脚远离晶振引脚和高频数字线,模拟地单点连接,采样信号线加 RC 低通滤波,截止频率放在信号带宽的 3 到 5 倍。另外,关闭不需要的 GPIO 翻转干扰,或者在采样窗口内避免切换数字引脚,也能显著减少毛刺。
现象:两个 SDADC 单元同时工作时,互相之间出现串扰,一路信号跳变会带动另一路读数跳几下。
原因:虽然三个 SDADC 是独立单元,但如果共用了同一个参考电压或同一个电源引脚,内部模拟公用通路上的耦合就会显现出来。尤其是它们的采样时钟不同步时,调制器会在不同时刻抽取电流,在电源网络上形成竞态。
解决:尽量让两路 SDADC 使用相同配置和采样时钟,这样电流抽取节奏一致,耦合干扰变成共模,影响较小;或者将两路采集错开时间,让一路转换期间另一路保持空闲。对时钟频率不同的场景,可以在电源引脚旁各加一个 0.1uF 和 4.7uF 电容的组合,降低高频串扰。
6. 进阶:用内部基准通道验证 ENOB,顺便把三路 SDADC 一起用上
如果你已经把单路 SDADC 跑通,接下来的功课是验证它到底能采多准。最简单的方法是配置内部通道,把内部基准电压直接当成输入来测量。F373 的 SDADC 内部有一个固定连接到基准电压的通道,配置它就像配普通通道一样。把增益设为 1,用标准采样参数读出一段时间的数据,统计均值和标准差。标准差比较低,说明这个板子的噪声水平好;标准差偏高,就说明电源或参考源有可优化的空间。
有人问内部基准通道不能作为绝对参考,怎么用来验精度?它做不到绝对校准,但能做一致性验证。同一批板子,如果内部基准读数都落在同一小范围内,说明各板卡的转换通道工作正常;如果某一块读数偏离明显,就要回头查那块板子的电源纹波或焊接问题。这个方法在产线上非常实用,成本几乎为零。
三路 SDADC 一起用也不是难题。把 SDADC1、SDADC2、SDADC3 都初始化成同样的结构,只是句柄和通道不同,然后按同样的流程启动转换。如果你需要它们同步采样,可以利用 DMA 把多组结果块搬到内存,配合转换完成中断来做数据对齐。我习惯的做法是建立一个小型采集状态机,每个 SDADC 的转换完成中断里把数据压入环形缓冲区,再由主循环统一换算和滤波。这样三个通道的代码逻辑一致,调试时只要修一个地方。
最后分享一个习惯:无论 SDADC 还是普通 ADC,我都会在固件里加一个自检步骤,把内部基准通道的测量值打印出来。如果一个批次里某块板子的基准读数偏离平均值超过几个 LSB,就说明它的供电或者模拟前端有问题,趁早拦截,不要在用户现场出问题再返修。这种自检做起来成本极低,但能避免很多看起来像“玄学”的现场故障。希望帮到你。
本文还有配套的精品资源,点击获取