尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

CD74HC4067扩展16路ADC采集:原理、接线与调试避坑指南

CD74HC4067扩展16路ADC采集:原理、接线与调试避坑指南 刚把一块板子的16路模拟量采集调通趁热把CD74HC4067这套方案和调试过程中踩到的两个坑记录下来。这个标题看起来简单但真正从原理图到稳定采样中间有不少容易被忽略的细节。如果你正在为MCU原生ADC通道不够用发愁或者已经接了CD74HC4067但发现数据不稳定这篇笔记应该能帮你省下不少时间。1. 为什么需要扩展ADC通道以及为什么选中CD74HC4067很多做嵌入式的小伙伴第一次遇到模拟量采集不够用是在项目原型阶段。MCU自带ADC通道看着不少比如STM32F103有16个外部通道听起来完全够用但真正布局下来一部分通道要分给电压监测一部分要留给电流采样再算上温度传感器、电位器校准、外部模拟信号输入通道数很快就捉襟见肘了。更麻烦的是有些MCU的ADC引脚和以太网、USB、定时器PWM引脚是复用的一旦功能冲突只能被迫舍弃某个采集点。用通道扩展芯片来解决问题是从硬件层面一次性扩充模拟输入数量比换MCU型号、重新画板子成本低得多。CD74HC4067是一颗16通道模拟多路复用器/多路分配器英文名叫16-Channel Analog Multiplexer/Demultiplexer。它的核心理念很朴素芯片内部有16个模拟开关S0到S3四个引脚上的二进制组合决定哪一个开关接通把对应的输入通道连接到公共输出端。这颗芯片同时支持双向信号传输既可以做16选1的采集切换也可以反过来做1到16的信号分配灵活性很强。相比用多个CD4051拼出通道数直接用CD74HC4067一个片子就能搞定16路外围器件少控制逻辑也简单。选型的时候有几个关键参数让我比较放心。首先是供电范围CD74HC4067的工作电压是2V到6V3.3V和5V系统都能直接用不需要额外电平转换。其次是导通电阻Ron典型值在5V供电下只有几十欧姆级别远低于早期CD4067的几百欧姆在分压电路、传感器信号输出这类场景中带来的阻性误差小很多。还有一个容易被忽略的点是它的开关时间tON和tOFF大概在几十纳秒量级虽然理论上可以快速切换但实际应用中必须考虑后级电路的稳定时间这个后面讲第一个坑的时候细说。对比一下其他方案可能更容易理解这颗芯片的定位。第一种方案是直接用带多路ADC的高端MCU比如STM32F4系列内部ADC有19个通道但通道之间共享采样保持电路大量通道高速采集时依然存在调度问题而且换MCU意味着整套代码和硬件都动。第二种方案是外挂独立ADC芯片比如ADS1115虽然精度高但价格是CD74HC4067的好几倍而且I2C接口速率限制了采样率。第三种方案就是用CD74HC4067这类模拟开关做前端切换保留MCU原始ADC的采样能力成本低、控制灵活十几路信号每秒采几十次完全够用这也是它在工业采集板上很常见的原因。2. 硬件接线和电路设计里的关键细节CD74HC4067的引脚排列非常规整市面上常见的是SOIC-24或者TSSOP-24封装。核心引脚分成三组模拟输入输出组是Y0到Y15共16个引脚连接到你要采集的各路模拟信号通道选择组是S0到S3四个引脚接MCU的四个GPIO另外还有使能引脚EN低电平有效。公共端引脚叫Z这个引脚直接接到MCU的ADC输入引脚上。VCC接电源正极GND接地这是基础接线。实际接线中有一个细节我吃过亏就是Y0到Y15这16个引脚内部是等价的不用管谁是“输入”谁是“输出”信号可以双向流动。当你把它当16选1使用时16个引脚接外部信号Z引脚接ADC即可。但如果你只用了其中几路比如只接8路传感器剩下的Y8到Y15引脚不能悬空不管悬空引脚在切换时会把不确定的电平耦合到公共端导致采样数据跳动。最稳妥的办法是把未用的输入引脚直接接地或者通过100kΩ电阻下拉到地避免浮空输入引入噪声。电源和去耦电路是另一个容易出问题的地方。CD74HC4067的VCC引脚旁边必须放一个0.1μF的陶瓷电容尽量靠近芯片引脚放置这是模拟开关稳定工作的基础。如果电路板上还有其他数字信号在频繁翻转比如PWM输出、SPI通信线它们产生的电源纹波会通过VCC耦合到芯片内部的开关驱动电路最终体现在ADC采样值的抖动上。所以模拟区域和数字区域的电源最好用磁珠隔开或者至少在4067的VCC引脚附近加一个10Ω电阻和10μF电容组成的RC滤波实测对采样稳定性的提升非常明显。还有一个思维定势要打破很多人把4067的公共端Z直接拉到MCU的ADC引脚就结束了但这时ADC引脚的对地电容、走线寄生电容会和4067内部的开关沟道电容共同构成一个RC网络。当切换通道后ADC引脚上的电压需要一段时间才能稳定到新通道的真实值。走线越长、引脚电容越大稳定时间越长。所以Z引脚到MCU ADC引脚的走线要尽量短粗一点更好中间不要穿过过孔太多也不要加上拉电阻旁路电容这类会拖慢电压建立的元件。至于EN引脚如果只用一个4067可以直接接地让芯片始终使能。但如果设计上支持多片4067扩展成32路甚至更多EN就该接到MCU的GPIO通过使能控制选择哪一片芯片工作此时要重点检查GPIO的默认输出状态上电瞬间必须保证EN处于高电平关闭状态否则所有芯片的公共端会同时输出信号轻则采样错误重则两个ADC引脚互相灌电流这个逻辑说起来简单但上电时序和MCU引脚默认电平的配合很容易被忽视。3. 软件控制逻辑通道切换、时序和采样稳定软件层面的第一件事是初始化四个控制引脚S0到S3为推挽输出模式。代码很简单但有一个原则必须遵守这四个引脚的初始电平要清晰定义不要在初始化阶段出现不确定状态否则4067的通道会随机打开接通到一个未知的模拟源上。比如用STM32的HAL库可以先写一个四级管脚初始化再把四个引脚同时拉低这时芯片默认选中Y0通道。通道选择的对应关系本质上就是一个0到15的二进制码S0是最低位S3是最高位。假设你的四根控制线分别接到了MCU的PC0到PC3引脚那么选择第n个通道时把n的低四位填到这四个引脚上就行了。很多人的第一反应是用switch语句逐个写这当然没错但更优雅的方式是直接用一个GPIO寄存器赋值语句把通道号取低4位映射到对应的ODR寄存器位一行代码搞定16路切换。真正决定采样质量的是通道切换完成后到启动ADC采样之间的稳定时间。很多人写代码是这样的切换4067通道立刻调用ADC采集函数拿到结果然后切换到下一个通道循环往复。这种做法在低速信号上问题不大但如果你采集的是精密参考电压、电桥差分信号、或者传感器经过长线传输过来的弱信号很可能会发现相邻通道之间的采样值相互串扰。原因就在于模拟开关切换后信号链路里的寄生电容需要时间充放电新通道的电压必须等到整个链路稳定后才是真实的。经验上通道切换后至少留出10μs到100μs的稳定时间具体取决于你后级电路的阻抗和电容。我在实际项目中习惯加一个50μs的延时然后连续采样两次丢弃第一次结果取第二次作为有效值这种方法成本低、逻辑简单实测效果很好。如果你对实时性要求更高可以用定时器触发ADC精确控制切换时刻和采样时刻之间的延时但对大多数传感器采集场景来说微秒级的延时微不足道。另外一个值得提的采样技巧是在扫描16个通道的过程中刻意把切换动作和ADC采样的关系错开。比如在定时器中断里先切换通道返回主循环做其他事情等到下一次中断到来时启动ADC采样采样完成后立刻切换下一个通道这样就天然地给了通道切换足够的稳定时间而且不需要死等延时。这种“边切换边工作”的思路在实时性要求较高的系统里非常实用。代码逻辑的完整流程可以总结为设置S0到S3输出对应通道号延时等待信号稳定启动ADC采集等待转换完成读取结果存入数组通道号加1继续下一轮。整个过程在任何一款带ADC的MCU上都能实现不依赖特定平台。如果你用的是带DMA的ADC还可以考虑用DMA循环采集多个通道的数据但要注意DMA的触发频率要低于通道切换频率否则会把上一次切换的残余电压采进去。4. 调试坑一通道切换后采样值乱跳问题出在稳定时间不够我最初调试这块板子的时候表现的现象非常典型只采集一路信号时ADC数据稳定得很漂亮纹波不超过几个LSB但只要启动16路循环扫描某些通道的数据就开始明显跳变尤其是相邻通道信号电压差异大的情况下前一个通道是高电压、后一个通道是低电压后一个通道读到的值会明显偏高而且这种偏高不是固定的和扫描速度有关。第一反应怀疑控制引脚接线错误或通道选择逻辑写错了仔细检查S0到S3的电平组合和真值表完全对得上用万用表测量4067的Y引脚和Z引脚之间的导通情况发现切换到某一路时对应的开关确实导通了逻辑上没有任何问题。既然硬件连接和通道选择都没错那问题大概率出在时间维度上。我用示波器同时抓了Z引脚的电压波形和ADC采样触发信号终于看清了问题全貌。通道切换后Z引脚的电压并不是立刻跳到新值而是出现了明显的指数充电过程从旧电压过渡到新电压需要一段时间如果ADC在这段时间内触发采样采到的自然不是最终稳定值。具体有多严重取决于切换前后两路信号的电压差和后级电路的RC时间常数信号差越大、电容越大需要的稳定时间越长。当时我采用的修复方案其实也简单在通道切换后插入一个自适应延时函数先用一个相对较大的延时值让信号稳定然后连续读取两次ADC结果第一次丢弃第二次作为最终值。这个方案的逻辑依据是第一次读取的过程实际上也是在给Z引脚上的寄生电容充电等到第二次采样时Z引脚电压已经被第一次采样前的延时和第一次采样动作充得差不多了第二次采到的值就非常接近真实电压。实测下来切换后延时50μs再连续采两次16路数据全部恢复到正常范围内的波动水准。这里额外提醒一句ADC本身的采样时间也要注意。很多低功耗MCU的ADC采样电容只有几皮法但通过4067的开关沟道和走线电容等效到ADC输入端的源阻抗会比直接连接传感器时高不少。此时如果把ADC采样周期配得特别短比如ST芯片配置成1.5个ADC时钟周期内部采样电容来不及充满就开始转换也会造成读数偏小。解决的思路是适当增大ADC采样周期配置ADC时钟在合理范围内尽可能满足采样电容的充电时间整体数据质量会有显著提升。这个坑的本质其实是RC充电时间和ADC采样时刻的匹配问题不只在CD74HC4067上会遇到任何模拟多路切换电路都会遇到。理解了这一点后续调试其他型号的模拟开关、多路复用器时排查思路可以完全复用。5. 调试坑二模拟开关导通电阻带来的分压误差读数系统性偏小第二个坑是调了大半天才定位到的和第一坑的表象截然不同数据不是乱跳而是非常稳定地偏小。比如用两个电阻分压得到1.65V的电压送到4067的Y0通道MCU读回来只有1.60V稳定地少了0.05V。一开始以为是ADC参考电压的问题或者分压电阻精度不够但用万用表直接测量分压点电压确实是1.65V而MCU读出来的就是不对。问题的根源在于CD74HC4067的导通电阻Ron而不是芯片坏了。模拟开关在导通状态下并不是理想的零电阻通路内部存在一个几十欧姆的导通电阻。如果你的信号源输出阻抗也很高信号经过4067时就会和导通电阻形成分压到ADC输入端的电压就不是原始信号电压了。现代数字万用表输入阻抗高量分压点电压几乎不引入误差但ADC的采样电路在采样阶段会从源端吸收电流电流流过Ron时产生的压降就会让读到的电压偏低。在下拉电阻偏大的场景里这个问题特别明显。比如光敏电阻直接接4067而不加缓冲光敏电阻在暗处的阻值可能高达数百千欧此时和Ron分压误差很容易超过1%。又比如用高阻值电位器输出的电压信号接4067电位器内阻本身几十千欧串上Ron片内几十欧看起来占比不大但如果信号源是微弱的pH电极、高阻抗电桥这类输出阻抗极高的源误差就不能忽视了。修复手段有硬件和软件两个方向我在实际项目中是两者结合。硬件上的首选方案是加一级运算放大器缓冲把高阻信号转成低阻信号再接4067。运放跟随器的输出阻抗通常在1Ω以下Ron的几十欧与之相比完全不影响。如果项目的BOM成本卡得紧、通道数量又多不可能每路都加运放那就尽量把分压电阻的阻值设计得低一些比如两个10kΩ分压比两个100kΩ分压在同样的Ron下分压误差缩小到十分之一。软件方案则是做一次性校准用精密基准源接到每一个通道记录ADC读数与标准值的偏差生成修正系数存到Flash里实际运行时按系数修正这种方法对接高内阻源特别实用。考虑到多路模拟开关切换应用中经常会碰到串扰问题我再用一个小经验补充说明。如果某路信号没有使用它的输入引脚虽然物理上存在但没有任何驱动源切换到这个通道时Z引脚上的电压会受前一个通道残存电荷和外部噪声的共同影响而波动进而污染后续通道的采样值。最直接的解决办法是给未使用的输入引脚加下拉电阻到地并在软件扫描时跳过这些通道不要浪费时间去采集没用的输入。配合前面提到的稳定延时这个坑也能顺带规避大半。6. 最终稳定运行的代码结构以及几个能提升采样质量的补充细节经过上述两个坑的修复我的16路ADC采集最终采用的代码结构比较清晰核心部分可以分成三段GPIO初始化、通道切换延时、ADC采样。GPIO初始化代码不复杂关键是四个通道控制引脚初始化为推挽输出并拉低通道切换延时用一个for循环实现简单的微秒级延时ADC采样则直接调用HAL库的ADC转换函数并对结果做一次简单的软件滤波。软件滤波的选择上针对传感器信号我用的是递推平均滤波保留最近5次采样值每来一个新值就去掉最旧的一个再取平均。这种滤波方式对周期性的噪声抑制效果不错响应速度也够。如果你的信号变化较快可以缩短滤波窗口到3次或者改成加权平均让新数据的权重更高。关键是要知道滤波不是万能的它只能减小随机噪声对于系统性的分压偏小还是要靠硬件校准来修正。采样周期的规划也值得多写几句。假设你最终需要4路信号有实时性要求每路每秒采集100次剩下12路只需要每秒5次的低速采样此时不必让所有通道都按最高频率扫描。合理的做法是把4路高速通道排在前面12路低速通道排在后面每轮扫描快到低速通道时加一个较长的空闲等待或者干脆每十轮扫描才做一次低速通道更新。这样CPU占用率会大幅下降ADC的数据质量反而更好因为通道切换次数变少了留给每一路信号稳定的时间更充分了。另外建议在正式量产前把每一路ADC通道接上标准电压记录实际读数并画出误差曲线。很多传感器模块本身带有分压电阻和线性稳压器不同通道之间的误差曲线差异可能相当大通过标定建立的修正表能明显提高系统的整体精度。我这次做校准的方式是在板子上留了一个可切换的基准电压源接口用继电器切到每一路输入通道逐一记录ADC读数最后生成一个16维的修正数组效果非常直接。最后补充一个与ADC配置相关的点如果你用的是STM32系列MCUADC触发方式建议选择定时器触发而不是软件连续触发。软件触发模式下采样时刻受主循环代码执行时间的波动影响可能与4067的通道切换时序产生不可控的相位关系。定时器触发可以把采样时刻固定下来和通道切换延时程序配合形成稳定的时序基准这在采集周期性变化的信号时尤其重要。回到CD74HC4067这颗芯片本身它虽然不新但在工业采集板、电池管理系统、环境监测终端这些需要多路模拟量输入的场合依然是非常高效的方案。两颗芯片并联还能扩展到32路控制引脚共享S0-S3只增加一个EN引脚扩展成本极低。实际使用中只要把导通电阻、通道稳定时间、未用引脚处理和软件时序这四件事想清楚16路ADC采集调起来会非常顺畅。
返回列表