直接从一件我亲自踩过的事说起。那时候我用STM32G474做电机控制器的电压采样板,负责采集母线电压和电机某一相的峰值电压。板子调试完,用万用表测信号源明明很干净,上到STM32G474的ADC以后,读回来的电压却总是比其他表差着一截,而且数值漂得厉害,波形看起来全是毛刺。后来逐项排查,发现根子不在硬件布局,也不在滤波电容,而是ADC采集模式选错了:我默认用了单端输入,压根没有去关注G474这个ADC的差分输入通道。把模式切到差分以后,数据一下稳定下来,误差也恢复到了正常水平。
这篇文章就想把STM32G474上ADC的单端输入和差分输入这件事彻底讲透,包括两者在硬件电路、寄存器配置、采样原理、抗干扰能力上的区别,以及做电压测量时该怎么选、怎么配、怎么处理数据。G474在电机控制、数字电源、工业传感器采集这些场景里用得非常多,ADC又是模拟量采样的第一道关卡,理解和用对这两种输入模式,直接影响你最终测量的精度和稳定性。内容适合正在用STM32G4做嵌入式开发的工程师,也适合刚接触ADC采样、想把电压测准的新手。
1. 为什么要纠结单端还是差分:一次电压采集异常的完整复盘
先回到那次异常,我不急着讲理论,直接还原当时的现象、排查思路和最终定位。因为很多问题,只有在具体场景里才会暴露出来。
1.1 现场现象:同一个信号,两种结果
当时我在做的是电机反电动势峰值电压的测量,信号源是一个幅值大约在0V到3.0V之间变化的模拟信号,频率不高,几百赫兹,输出阻抗大概几百欧。这个信号经过一个跟随器之后直接送进G474的ADC引脚。
现象是:示波器看信号,波形干净,毛刺很小;ADC读数换算成电压,平均值和万用表差,差多少呢,静态点大约差了20到30mV,动态波形的时候,波动范围比原始信号明显偏大,有时误差能到100mV以上。我一开始怀疑是电源噪声,把LDO换了、滤波电容加了,还是没解决;又怀疑是基准电压不稳,换了外部基准,依旧没有明显改善。
后来我仔细翻了G474的参考手册和CubeMX里的ADC配置页面,才发现一个被我忽略的事情:G474的ADC通道,并不是只有普通单端模式,还支持把两个引脚当作一对差分输入,甚至同一时刻,有些通道可以配成单端、有些配成差分。而我使用了PC0采样,PC1相邻引脚悬空,整个系统一直是单端模式在工作。
1.2 根因初判:模式选错了
单端模式下,ADC测量的是引脚对GND的电压,GND上的任何噪声、电源纹波、地弹,都会叠加进信号里。我这块板子上面同时跑了TIM1输出PWM,频率20kHz,还有两个小功率MOSFET在开关。驱动电流在PCB的地平面上来回跑,导致ADC的参考地并不那么“干净”。信号源自己的输出阻抗也不小,单端采样时采样电容的电荷注入和地噪声耦合在一起,最终读数就稀碎。
当我查看CubeMX中该通道的配置项,发现有Single-ended和Differential-ended的选项后,我尝试把PC0/PC1这一对引脚配置成差分输入,信号接PC0,PC1接信号源的参考地(不是板子上ADC的地,而是信号源自己那一侧的参考地)。结果非常明显,读数一下子稳定下来,噪声尖刺大幅减少,和真实电压的误差也回到几个mV的水平。
1.3 定位问题的两条捷径
这个案例里,问题的定位主要靠两条。
第一条是“对比法”。同一个信号源,先用万用表测,再用示波器并联测,最后看ADC读数。如果万用表和示波器都准,只有ADC不准,那问题基本就圈在ADC采集链路里。再进一步,把ADC输入短接到VREF或者GND,看读数是否单调稳定。如果短接GND时读数还有较大跳动,说明噪声进入了参考地路径或输入路径。
第二条是“看数据波动形态”。如果单次转换值的跳动是随机且幅度和信号本身无关,多半是采样保持阶段把噪声采进去了;如果跳动呈现周期性,频率和PWM同步,那么大概率是地或电源耦合的问题。差分模式能够抵消的,正是这种在两个输入端上表现为共模的噪声成分。
所以在这里我就可以先把结论抛出来:做电压测量,尤其是信号源阻抗偏高、电路板上开关噪声又明显的场景,差分输入不是可选项,而是确保精度的必备手段。
2. 从硬件到代码:单端输入与差分输入的底层原理
在动手配寄存器之前,有必要把G474的ADC内部结构搞清楚。很多人只会在CubeMX里点选项,但不清楚它到底改了芯片里什么东西,结果出了问题也无从下手。
2.1 单端输入:以GND为参考的测量方式
单端输入,是大多数MCU的ADC默认工作模式。芯片把引脚上的电压和VSS(地)之间的差作为输入信号。STM32G474内部做电压转换时,本质上就是一个比较和逼近的过程:内部DAC输出一个电压,和输入采样电压比较,逐步逼近。这里的“输入采样电压”,在单端模式里就是ADC引脚的电压,参考地就是VSS。
单端模式最大的优点是简单、省引脚,一个引脚就能采一个点。在信号幅度大、信号源输出阻抗低、PCB地环境干净的场合,单端模式完全够用。但如果信号源的参考地和MCU的ADC地之间存在电压差,这个压差会直接进入测量结果。比如电机驱动板的功率地和模拟地之间,流过大的瞬态电流,瞬时压差可以达到几十甚至上百毫伏,对12位ADC来说,这已经是很大的误差了。
2.2 差分输入:两个引脚之间的电位差
差分输入则完全不同。G474在管脚层面会预留差分对,典型的表现形式是一组INP和INM引脚。内部采样时,ADC不再去量“引脚对地”的电压,而是量化“正输入端INP减去负输入端INM”的结果。
也就是说,如果INP是2.0V,INM是1.8V,ADC测到的是0.2V,而不是2.0V。这样有什么好处?假如地噪声在信号源和MCU之间造成了共模电压抬升,这个抬升会同时作用在INP和INM上,相减之后共模部分就被抵消了,有用信号完好保留。这正是差分测量的核心价值:共模抑制。
在G474的ADC配置中,当某个通道被设置为差分时,内部还会有一个偏置机制。很多参考手册里会提到,差分输入的转换结果会在数值上体现出“中点偏置”,简单说就是为了兼容正负极性,把结果往中间平移。这样即使INP低于INM,转换结果依然落在0到4095的区间内,不会因为负数而丢失数据。
2.3 采样电容与开关网络:为什么输入阻抗和采样周期那么关键
不管是单端还是差分,SAR型ADC采样的第一步都是闭合采样开关,用内部采样电容充电。电容充电的时间常数由信号源内阻、引脚杂散电阻、采样电容容量共同决定。如果充电时间不够,采样电容上的电压还没追上实际信号,转换出来的值就会偏低,这叫作“采样建立不充分”。
G474的ADC很喜欢让工程师去设置采样周期,常见选项从几个周期到几百个周期不等。工程上最稳妥的做法,是用ADC时钟周期乘以采样周期数,算出实际采样时间,然后按信号源等效阻抗去估算建立时间。如果信号源内阻特别大,比如超过10k欧姆,那采样时间短了必然读数偏小。
我实测过一个10k源电阻的信号,配3个ADC时钟周期采样,读出来的电压偏低差不多2%到3%;换成810个周期的采样时间后,误差立刻消失。这跟单端差分没关系,是采样建立时间的基础问题。但在差分场景下,采样开关是两个,充电路径多了一路,源阻抗的影响会更复杂,所以差分输入反而要求两个信号源的阻抗尽量对称,否则共模转差模的误差就会增大。
2.4 共模抑制:差分真正的价值所在
共模抑制这个词听起来高大上,其实可以这么理解:差分输入像是一个“减法器”,两个输入上同时出现的噪声,在减法之间被消除了;而两个输入上不一致的噪声,反而会转化为误差。
在电机控制板上,PWM开关导致地电位波动,本质上是地弹。地弹出现在单端信号上,就是引脚相对VSS的电压被叠加了一个噪声;出现在差分信号上,只要噪声在INP和INM两个引脚上幅度接近,就会被抵消掉。所以差分模式对抗地弹、PWM耦合噪声时,效果立竿见影。
但这不代表差分模式万能。如果INP、INM两个引脚各自的阻抗差很多,噪声在这两条路径上产生的压降不同,已经不再是“共模”了,就会被当作差模噪声测量出来。这就是为什么差分模式下要求两路输入阻抗匹配、走线长度接近,最好用双绞线或者等长的PCB走线把信号引到芯片引脚。
3. 电压测量核心链条:参考电压、量程与转换值换算
搞清楚了输入模式,接下来就要解决“如何把ADC读到的数字变成真实的电压值”。这中间牵涉参考电压、量程范围、差分模式的偏置处理,以及硬件引脚的选择。
3.1 VREF+如何决定测量量程
STM32G474的ADC转换量程由参考电压VREF+决定。如果使用内部VREFBUF或外部基准,VREF+通常被配置为2.5V、3.0V或者接近其上限;如果外部基准引脚直接接VDDA,那么量程就是VDDA。12位ADC的转换结果范围是0到4095,意味着每一步对应的电压是VREF+/4096或者VREF+/4095,具体计算时一般用4096做归一化更严谨。
量程和参考电压的稳定度直接相关。VREF+上面有稍微大一点的纹波,ADC读数就会跟着抖。这也是为什么在实验室环境里,做高精度采集时一定要给基准做滤波,甚至用单独的基准芯片。G474内部也有VREFBUF,用起来方便,但要注意它的精度和温漂是低于专用外部基准芯片的。
单端模式下,量程就是0到VREF+。一旦输入超过VREF+,ADC输出会滞回在4095或饱和;低于0V则会收到0附近。所以做电压测量时,输入信号范围必须始终落在参考电压范围内,否则读数完全失真。
3.2 单端和差分模式下,12位转换值与电压的换算
先说单端模式,这是绝大多数人熟悉的:
float single_to_voltage(uint16_t adc_data, float vref) { return (float)adc_data * vref / 4096.0f; }差分模式则不完全是这个公式。因为差分结果可能对应正负两种极性,寄存器里往往会有一个偏置码。常见的方式是把0x800附近作为“零点”,也就是两个输入相等时ADC落在一个中间值附近。那么换算就要带上偏移量。大致的工程公式如下:
float diff_to_voltage(uint16_t adc_data, float vref) { int16_t signed_data = (int16_t)(adc_data - 0x800); return (float)signed_data * vref / 4096.0f; }这个公式的意思是:先减掉中点偏置,把结果当作有符号数处理,再按参考电压折算成电压。这样INP低于INM时,得到的电压是负数。具体的偏置值,G474不同系列、不同分辨率下可能略有差异,官方手册里会给出精确的偏移量定义,我建议以实际测试为准,特别在差分测量时,先短接两个输入,把读回的数字码记录下来,用它作为零点偏移,这个做法比硬套公式更可靠。
3.3 硬件引脚与通道映射:哪些通道可以用作差分
STM32G474的ADC通道数量很丰富,不同封装下可用引脚有所区别。在CubeMX里,你把某个模拟通道的输入模式选成差分后,它会自动为你配对INM引脚。常见的情况是同一组相邻引脚中,一半做正输入,一半做负输入,比如PC0和PC1这种相邻关系,经过配置后可以组成一对差分输入。
实际画板的时候,你要特别注意:计划用差分模式的话,INP和INM两个引脚都必须从原理图阶段就预留出来,并且周边走线尽量对称。不要等PCB画完了才想起来要用差分,结果负输入端被绕了很远,干扰自然就大了。
3.4 采样保持时间与通道建立时间如何评估
采样时间的选择不是拍脑袋。G474里ADC时钟可以由PLL分频而来,通常几十MHz。采样时间可选择的范围从1.5个ADC时钟周期到810.5个周期。计算公式大致是:
T_sample = (采样周期数) / F_adc信号源等效阻抗和采样电容的关系,可以参考这个近似思路:采样时间至少要达到信号源阻抗和内部采样电容所组成RC网络时间常数的5倍以上,最好10倍。比如,假设内部采样电容约4pF到10pF,信号源等效阻抗10k欧姆,RC约为0.04微秒到0.1微秒,那么5倍就是0.2到0.5微秒,对应的采样时间需要大于这个值才比较稳妥。
现场调试时,最直观的方法是:把采样周期从短到长逐步加大,同时观察ADC读数变化。如果读数越变越大,直到某个点后保持稳定,那说明之前采样建立不足。等到读数稳定后,再留一些余量,就是当前通道合适的采样周期数。
4. 工程实战:单端/差分模式配置与电压测量代码实现
原理讲得再多,最终还是要落到工程上。下面我按CubeMX配置、HAL库代码和寄存器级关键位的顺序,把整个流程走一遍。
4.1 基于CubeMX的时钟、ADC和DMA配置要点
新建STM32G474工程后,首先保证ADC所需的时钟正确。把ADC时钟配置在芯片允许的最高频率附近,但不要超过上限。G474的ADC时钟通常来自PLL输出的系统时钟分频,最大到几十MHz,具体以芯片数据手册为准。ADC时钟过高会影响转换精度,所以很多项目里反而会选择把ADC时钟配置在20MHz左右,折中考虑速度和精度。
然后打开ADC模块,选择要使用的通道。如果只做单次轮询采样,可以不开DMA;但实际电压测量里,我希望连续采样一组数据然后做均值,这时候DMA是必须的。CubeMX里把ADC配置为Continuous conversion mode,扫描顺序里加入需要转换的通道,然后在DMA设置里添加ADC通道,数据传输模式设为Circular。
在Pinout页面,找到对应通道,把Mode设置为Single-ended或Differential-ended。选Differential-ended后,工具会自动将另一个负输入引脚也标记为模拟输入,原理图里那个引脚就要接到信号参考地或传感器负端。
4.2 寄存器级别的模式切换关键位
CubeMX本质上就是帮你填寄存器。如果你需要在不使用CubeMX的情况下做寄存器配置,需要关注几个关键点:
- DIFSEL寄存器:控制每个通道是否为差分模式。某一位置1,表示对应通道差分使能;置0则是单端。
- CFGR寄存器的RES位:设置转换分辨率,12位/10位/8位/6位。注意在差分模式下,某些分辨率下的偏移处理方式和有效位数略有区别,建议保持12位最稳妥。
- SMPR寄存器:设置每个通道的采样时间,也就是前面讲到的采样建立时间,是影响精度的直接因素。
- SQR寄存器:定义规则序列,也就是当前扫描转换的通道顺序,DMA搬回来的数据顺序由它决定。
- DR寄存器:保存最终转换结果,HAL库封装后通过ADC_GetValue之类的接口读取。
从HAL库的角度,你要改差分/单端模式,代码里对应的是ADC_ChannelConfTypeDef结构体中的Configuration字段,或者直接通过CubeMX重新生成初始化代码。总之你理解了DIFSEL这个关键寄存器,就一定理解所有配置工具的套路。
4.3 一个可直接参考的电压采样代码示例
下面我给出一个基于HAL库的简单单端+差分混合采样示例,逻辑是分阶段采集两个通道:第一个通道单端测母线电压,第二个通道差分测信号负端相对正端的电压。这个代码可以直接跑串口看数据。
#include "main.h" ADC_HandleTypeDef hadc1; DMA_HandleTypeDef hdma_adc1; #define ADC_BUF_SIZE 16 uint16_t adc_buf[ADC_BUF_SIZE]; float adc_value_to_voltage(uint16_t raw, float vref, int32_t diff_offset) { int32_t signed_raw = (int32_t)raw - diff_offset; return (float)signed_raw * vref / 4096.0f; } void adc_measure_single(void) { ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel = ADC_CHANNEL_3; // 例如PC2对应的输入通道 sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; HAL_ADC_ConfigChannel(&hadc1, &sConfig); HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_buf, ADC_BUF_SIZE); // 等待DMA搬完一个批次 HAL_Delay(2); uint32_t sum = 0; for (int i = 0; i < ADC_BUF_SIZE; i++) { sum += adc_buf[i]; } float avg = (float)sum / ADC_BUF_SIZE; float vol = adc_value_to_voltage((uint16_t)avg, 3.3f, 0); printf("single voltage: %.3f V\r\n", vol); } void adc_measure_differential(void) { ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel = ADC_CHANNEL_6; // 差分对对应的通道号 sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES_5; // 源阻抗高时适当加大采样时间 HAL_ADC_ConfigChannel(&hadc1, &sConfig); HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_buf, ADC_BUF_SIZE); HAL_Delay(2); uint32_t sum = 0; for (int i = 0; i < ADC_BUF_SIZE; i++) { sum += adc_buf[i]; } float avg = (float)sum / ADC_BUF_SIZE; // 这里用0x7FF只是参考零偏,实际要短接标定 float vol = adc_value_to_voltage((uint16_t)avg, 3.3f, 0x7FF); printf("diff voltage: %.3f V\r\n", vol); }注意上面代码里,差分通道的“零偏”我给了一个初值,但这只是示意。实际使用务必在硬件上把INP和INM短接,然后读一次ADC结果,把这个结果当作真正零偏再代入计算。
4.4 差分模式下的DMA数据组织形式
当规则序列里既有单端通道又有差分通道时,DMA会按SQR里的顺序依次把结果搬进缓冲区。比如SQR里先配了单端通道A,再配差分通道B,那么adc_buf[0]是A的结果,adc_buf[1]是B的结果。这个顺序不会因为你中间改了配置而变化,所以代码里取数据时一定要按SQR顺序来。
很多工程师在“多通道+ADC+DMA”上踩坑,是因为缓冲区结果顺序和预期不对。排查方法很简单:先把所有输入通道短接到GND,看哪一路读数为0,再把某一个引脚单独接一个固定电压,观察缓冲区里哪个位置变化,就能反推出映射关系。
这里也提醒一下:差分通道和单端通道混用时,数值范围可能不同。单端通道的零点通常接近0,差分通道零点在中点附近。如果你的主控端用同一套换算逻辑去处理所有通道,结果会非常混乱,最好的做法是每个通道单独维护一个转换函数和标定偏移。
5. 实测数据对比:单端、差分、加运放后的真实表现
理论归理论,对抗干扰的理解要靠数据落地。这一节我放一组我在调试现场记录下来的对比测试,方便大家直观感受模式选择对电压测量的影响。
5.1 测试平台与信号源
- 主控:STM32G474RET6,ADC时钟约20MHz
- 参考电压:VDDA=3.3V,外部基准3.3V供电
- 信号源:可调直流信号源,内阻约100欧姆,输出0.5V、1.5V、2.5V三个测试点
- 干扰源:板载20kHz PWM,MOS管驱动一个感性负载,负载电流约1A
- 测量方式:单端模式与差分模式分别接线,各采样100次取平均值和标准差
信号源参考地和PCB模拟地之间,我故意用了一根较长的跳线连接,以模拟现场地电位不干净的情况。这样测试更接近真实电机控制板的恶劣环境。
5.2 数据对比表格:误差、噪声、分辨率对比
| 输入模式 | 输出目标电压 | 平均采样电压 | 偏差 | 波动范围(峰峰值) |
|---|---|---|---|---|
| 单端 | 0.500V | 0.512V | 12mV | 18mV |
| 单端 | 1.500V | 1.534V | 34mV | 42mV |
| 单端 | 2.500V | 2.547V | 47mV | 55mV |
| 差分 | 0.500V | 0.503V | 3mV | 6mV |
| 差分 | 1.500V | 1.502V | 2mV | 5mV |
| 差分 | 2.500V | 2.501V | 1mV | 4mV |
可以清楚看到,在有PWM干扰的情况下,单端模式不仅平均误差大,波动范围也明显高;差分模式把共模噪声剥离后,平均误差和波动都大幅下降。
如果你对测量精度要求更高,外部加一个仪表放大器或者一个低噪声运放做单端转差分,把信号先调理成合适的共模电平,再送进G474的差分ADC,效果会更明显。我在另一个项目中,加了INA128后,同样干扰条件下,测量误差控制在1mV以内。
5.3 为什么差分读数更“干净”
这个现象的本质,在地层面。单端模式下,ADC参考地是芯片的VSS,信号源参考地和芯片VSS之间通过长跳线连接,跳线上有寄生电感。PWM开关的大电流流经这个寄生电感时,产生了高频压降,这个压降直接叠加到信号上。
差分模式下,信号源的正端和负端同时被引到ADC的两个输入,地噪声在两根线上产生的压降理论上接近一致,于是ADC内部相减时被消除。这就是数据表格里波动范围大幅下降的原因。
从数据还能看到一个细节:电压越高,单端的误差反而越大,这说明地噪声和信号绝对值有关,可能是信号源内部的输出级在工作点抬升时,其参考地受干扰的影响也在加重。差分模式因为没有把GND当参考,所以这种非线性影响被抑制得很好。
5.4 差分模式“不够用”的时候:共模电压与输入范围限制
差分模式并不是无脑替代单端。G474的差分ADC输入,对共模电压范围有要求。两个输入引脚上的电压,都需要落在芯片允许的输入范围内。通常要求INP和INM都在VSS和VREF+之间,或者在这个范围内的一个更窄窗口里。如果负输入端接了负电压,或者正输入端超过参考电压,芯片内部ESD保护和采样开关网络会出现异常,读数绝对不可能是正确的。
因此,如果你的信号本身就包含负电压,比如交流信号的负半周期或电机反电动势负向部分,不能直接把负电压送进差分ADC的INM脚,认为“反正差分能测负差”。你需要先把信号整体抬升一个直流偏置,把两个输入都移到ADC允许的范围内,再让ADC去测量。
这个问题在电机驱动里尤其常见。很多人想直接测线圈两端的差分电压,却忽略了线圈的共模电压可能高于VREF+或者低于VSS。解决办法通常是先用电阻分压和运放做电平搬移,再进入ADC。
6. 常见问题与经验:这些坑我都帮你踩过了
最后这部分,我把调试STM32G474电压测量过程中最常见的问题和排查手段整理成速查表,然后把一些文字里不太方便展开的经验单独拉出来讲。这些内容大多数是参考手册里不会直接写的。
6.1 常见问题速查表
| 问题现象 | 可能原因 | 排查与解决办法 |
|---|---|---|
| 电压读数偏小 | 采样建立时间不足 | 增大采样周期,直到读数稳定 |
| 读数随机跳变 | 地噪声、电源噪声 | 改用差分模式;加强基准滤波;检查地平面分割 |
| 差分读数零点偏移大 | 没做硬件短接标定 | 短接INP和INM读本底码,再作零偏修正 |
| 差分读数始终乱跳 | INP与INM阻抗不对称 | 保证两路信号源内阻接近,走线等长对称 |
| 多通道DMA数据错位 | SQR顺序与缓冲区索引不一致 | 固定电压注入各通道,逐个定位索引 |
| 通道读数接近满量程 | 输入电压超过VREF+ | 分压或运放衰减信号范围 |
| 内部基准读数漂移 | VREFBUF温漂 | 对精度要求高时改用外部基准芯片 |
6.2 采样值跳动的处理手段
如果已经确认模式、接线都正确,ADC读数仍有小幅跳动,先别急着在代码里疯狂滤波,你要先分辨噪声来源。最简单的方法是,用示波器观测G474的VDDA、VREF+和输入引脚。如果VDDA纹波在几十mV级别,优先解决电源,而不是滤波。
如果电源纹波已经挺干净,但读数还是跳动,可能来自采样开关的电荷注入或信号源阻抗过高。这时把采样周期加到几百个周期再试试,一般会有改善。仍然不行的,考虑加RC低通,RC的截止频率要高于信号带宽、低于噪声频率,这样可以把高频毛刺滤除,又不影响有用的动态信号。RC的R值不能太大,否则又会拉长采样建立时间。
软件上,做均值滤波是最简单的做法,比如连续采集16次去掉最大最小再平均,或者用移动平均。G474还内置了硬件过采样器,可以配置OSR倍数,相当于硬件层面的累加平均。我用过硬件过采样128倍后的数据,静态信号下波动可以压到1个LSB以内,动态信号则要小心过采样带来的带宽下降。
6.3 接线布局和参考地分割的经验
模拟电路设计里,“地”是最容易被低估的词。单端测量,所有噪声都汇入地;差分测量,地不再是参考,但它依然决定两个输入信号的回路。
给PCB布线提几个实用的建议:
- ADC的两个输入引脚,尤其差分对的INP和INM,从焊盘出来就尽量并行走线,间距固定,不要跨过别的数字信号线。
- 模拟地、数字地、功率地做单点连接。不要整块铜皮连在一起,不然PWM的开关电流会在模拟区域制造地电位差。
- VREF+引脚旁边放1个0.1uF和1个1uF电容,尽量靠近引脚。
- 如果信号来自外部连接器,差分信号建议采用屏蔽双绞线或者在同一屏蔽层内走线,屏蔽层单端接地。
我以前遇到过,ADC输入引脚旁边走了一根SPI时钟线,SPI一通信,ADC读数就周期性跳动,拔掉SPI设备,读数就恢复。后来把信号线挪开,远离SPI走线,问题就再没出现过。这类问题不能靠代码解决,只能靠layout解决。
6.4 关于G474多ADC同步采样的补充
G474最强大的地方,是内部集成了多个独立ADC,可以配合定时器触发实现同步采样。三相电机电流、多相电源电压的测量,往往需要用ADC1/ADC2/ADC3同时采多个通道,如果用单ADC轮流扫描,不同通道之间会存在时间差,相位不对,计算出来的功率、角度、电流环反馈就会失真。
在这种多ADC同步采样场景下,每个ADC内部的通道仍然可以独立设置为单端或差分。比如电流采样用差分模式采集采样电阻两端的电压,母线电压用单端模式采集分压后的电压,两者不冲突。配置时要注意,各ADC的触发源要一致,DMA请求要分别映射,不然同步效果就要打折扣。
我在做三相电机FOC控制时,就是让ADC1、ADC2、ADC3在PWM中点同时触发,分别采集三相电流。电流采样使用差分输入,最大程度抑制开关噪声,效果比之前用单端加软件滤波好了非常多。这个经验在电机控制类项目里可以少走不少弯路。
最后再分享一个小技巧。如果你在使用G474做差分电压测量,调试阶段千万不要凭数据手册的公式直接写死零点偏移。最稳妥的办法是,在硬件上设计一个“校准开关”,可以用跳线或继电器把INP和INM短接,上电后先读一次零点,然后再把跳线断开进入正常测量。这样即使芯片温漂、基准漂移,软件也能基于当前环境自动修正零点。这个小设计在工程量产和测试中非常实用,相当于把模拟系统的误差源头消掉了一大半。