























作为核心部件,我找了几款容易购买的运放芯片做为候选。
| 参数 | OPA2277 | SGM8552 | AD8666 |
|---|---|---|---|
| 单电源供电 | -- | 2.5 V 到 5.5 V | 5 V 到 16 V |
| 双电源供电 | ±2 V 至 ±18 V | -- | ±2.5 V 到 ±8 V |
| 输入失调电压 | ±10 μV | 4 μV | 最大2.5 mV |
| 输入偏置电流 | ±0.5 nA | 10 pA | 最大1 pA |
| 开环增益 | 134 dB | 145 dB | 未提供 |
| 共模抑制比(CMRR) | 140 dB | 105 dB | 100dB |
| 电源抑制比(PSRR) | 130 dB | 110 dB | 115dB |
| 带宽 | 1MHz | 1.53MHz | 4MHz |
| 输入电压 | (V-) + 2 V ~ (V+) - 2 V | 轨到轨 | -0.1 V ~ V - 2 |
| 输出电压 | (V-) + 0.5 V ~ (V+) - 1.2 V | 轨到轨 | 轨到轨 |
| 静态电流(每放大器) | ±790 μA | 930 μA | 1.1 mA |
| 优信价格 | ¥ 2.4 | ¥ 2.8 | ¥ 6.9 |
从上面的表格,我决定使用 SGM8552 作为主选,OPA2277 作为备选。所以电路设计上,会使用双电源方案,其中负电源是专门给 OPA2277 选配的。负电源输出保留一个 0 Ω 电阻,如果使用 SGM8552,则不贴。
根据上面的选型,我选择使用 USB-PD 方案输入供电,电压在 +5 V ~ + 12 V。这样能为 OPA2277 提供 12V 的供电。如果使用 SGM8552,则只索要 5V 电压。负电压电源使用电荷泵从正电压电源生成。
为了能支持 12V 的电压输入,选择了 USB-C 母口作为电源输入接口。后续通过 USB PD 协议进行电压选择。
由于电子负载内部有敏感的模拟电路,所以特地在输入端口附近增加 LC 滤波电路,目的是滤除高频干扰。
作为系统主要芯片的供电电压,使用支持 40 V 输入电压的 LDO SY6345。SY6345 输出的电压可调,非常适合本次项目的功能验证。这是因为这路电源将会限制 DAC 和 ADC 的参考电压范围。
计划使用 MCU 内置的参考电压源。
目前有四种情况:
上面这几种情况,是用来做功能验证的。等验证完再决定后续使用哪个方案。
除了接地外,运放的正负电源输入端与电源都连接了一个 10 Ω 电阻,以降低电源的噪声。
ICL7660、ICL7660A 是一款电荷泵芯片,电荷泵其中一个功能就是产生一个与电源幅值相同但极性相反的电压。
ICL7660 支持 10V 的电源,而 ICL7660A 支持 12V 的电源,所以本项目使用的是 ICL7660A。
由于负电压电源是提供给运放的,所以增加了个磁珠及额外的电容器,以改善纹波噪声。
STM32G431CBU6 有两个 ADC,但是很多地方需要用到 ADC,出于整体性能考虑,我将一个 ADC 用于负载电压采集,另一个用于电流、温度采集。
其中,电压和电流的采集使用了差分输入,理论上有助于抵抗干扰。
本次的项目准备实现本地电压采集和远端电压采集,但是受限 ADC 数量的不足。本着不浪费的原则,使用一个四刀双掷的模拟开关来切换电路连接,目前准备使用的型号是 CH445P。
CH445P 导通电阻大概 7 Ω,似乎有一点大,但本菜鸡认为影响不大。
研究了一下,准备使用和前面同型号运放实现一个电压跟随器差分放大器。因为有近端和远端之分,所以正好能用掉两路运放。电源和之前的也一样,直接连接。负载电源正极首先经过电阻分压网络,所以不会超过运放输入限制。
为了降低检流电阻的功耗,我们需要选择低阻值的电阻。但是 MCU 的 VREF 最低也得 1.71V。假设使用 100 mΩ 采样电阻,我们以 5A 的最大设计电流为例,电阻的功耗为:
W=I2⋅R=52⋅0.1Ω=2.5WW = I^2 \cdot R = 5^2 \cdot 0.1 \Omega = 2.5 W
产生的分流电压为:
Vshunt=I⋅R=5⋅0.1Ω=0.5VV_{shunt} = I \cdot R = 5 \cdot 0.1 \Omega = 0.5 V
可以说非常低了。有一种方案是将 DAC 输出的电压进行分压后再输入到运放,这样会失去一些抗干扰的能力。另一方面,ADC 采集电流时,精度也因为检流电阻的分压太低而造成精度下降。
如此看来,应该选择对采样电流的分压进行增益。INA193 提供了 20V/V 的增益,具有 500KHz 带宽,理论上可以响应了微秒级的电流变化。设 VREF+V_{REF+} = 2.9V,,I_{max} = 5 A$,理想的电阻最大值是:
VREF+=20⋅ImaxR=2.9⋅5⋅0.025Ω=2.9VV_{REF+} = 20 \cdot I_{max} R = 2.9 \cdot 5 \cdot 0.025 \Omega = 2.9 V R=VREF+÷20Imax=2.9V÷205A=0.029ΩR = \frac{V_{REF+} \div 20}{I_{max}} = \frac{2.9 V \div 20}{5 A} = 0.029 \Omega
根据计算,25 mΩ 的合金采样电阻是个不错的选择。
R=0.025ΩR = 0.025 \Omega,满量程 Vmaxshunt=2.9VV_{max_shunt} = 2.9 V:
Vmaxshunt=20⋅Ilimit⋅R=20⋅5.8⋅IlimitΩ=2.9VV_{max_shunt} = 20 \cdot I_{limit} \cdot R = 20 \cdot 5.8 \cdot I_{limit} \Omega = 2.9 V Ilimit=Vmaxshunt÷20R=2.9V÷200.025Ω=5.8AI_{limit} = \frac{V_{max_shunt} \div 20}{R} = \frac{2.9 V \div 20}{0.025 \Omega} = 5.8 A W=Ilimit2⋅R=5.82⋅0.025Ω=0.841WW = I_{limit}^2 \cdot R = 5.8^2 \cdot 0.025 \Omega = 0.841 W
计算可得在满量程的情况下,功耗为 0.941W,选择 2W 功率的电阻即可。
首先我先考虑 STM32,看到 STM32G4 系列似乎是与电源相关领域有关的,再加上 Arm® Cortex®-M4 带有浮点加速单元,感觉很合适。
然后直接看淘宝买不买得到,发现 STM32G431CBU6 价格很美丽,目前正经店铺七八元人民币就能包邮带走。
根据STM32G431的数据手册,这个微控制器具有以下ADC配置:
ADC数量: STM32G431有2个ADC(模数转换器)。
ADC特性:
ADC通道:
工作模式:
其他特性:
这两个ADC可以独立工作,也可以配置为交错模式以提高总体采样率。有了这两个ADC,您可以同时采样多个模拟信号,满足各种应用需求。
STM32G431配备了2个DAC。
每个DAC有2个输出通道。
DAC特性:
工作模式:
其他功能:
性能:
STM32G431CB 支持 USB Power Delivery,所以我们不需要额外购买 USD PD Sink 芯片。如果使用 5V 供电,也能劲剩两个电阻 😜。是的,对应引脚默认有下拉。
哈哈哈哈我人傻了,只有默认的那对 CC 引脚是 DBCC,其他的几对并不支持死电池模式,没有默认的下拉。下个版本修复。
STM32G431CBU6 DAC 数量和精度都很符合项目要求,ADC 确实不够用,我看了下 G4 系列其他芯片,高端点的就不太能随随便便买了,而且还贵不少。所以 ADC 部分只能牺牲一下采样频率,让电压采集专用一个 ADC,其他的全部连到另一个 ADC 上,通过配置采样序列来分时采样。
电压检测电路使用双端输入,所以连接到 ADC 上会有一对差分线。当然根据设计,后续使用单端检测也是没问题的。
目前电压检测在电路设计上使用了远端检测和近端检测,两路检测信号拥有独立的前端处理电路。这两路电压信号可以有主副之分,通过模拟开关来交换连接到主、副 ADC 进行采样。
每路电压信号通过一个差分放大器(减法器)来提升输入阻抗并抑制共模电压。本来是准备实现电压跟随器的,但是我参考开源项目中,有一个使用了看起来更复杂的电路,我感觉那个靠谱些就先抄了过来,电路就是比电压跟随器多了几个阻容。后面有时间了研究了下才知道是这是差分放大器。

图中的电路增益倍数是 10124≈0.0806\dfrac{10}{124} \approx 0.0806。目前测试下来,其中一路的输出误差偏大,我怀疑是电阻精度的问题,目前使用的是 1% 的厚膜贴片电阻,接下来:

这里使用了四刀双掷的模拟开关 CH445P,用了个有点凌乱的连接方法实现了交换连接的功能。切换信号的输入引脚加了个下拉电阻,想着避免开发过程避免代码没实现到控制部分,这边信号不确定的问题。

这是版本 2 的电路图。右侧是低端采样的检流电阻,将信号通过 INA193 放大 20 倍后分别输出给控制负载 N-MOS 的运放芯片作为负反馈信号,和 MCU ADC 采样电路。
Grok 2 告诉我低通滤波应该放在 INA193 之后,我感觉似乎有道理:
采样电阻上的信号主要是低频信号,不会包含大量的高频噪声和干扰。而INA193的输出信号是经过放大的信号,放大过程中会将采样电阻上的微小噪声和干扰放大,同时INA193本身和电源也会引入额外的噪声和干扰。因此,INA193的输出信号中会包含高频噪声和干扰,而采样电阻上的信号则不会有明显的高频噪声和干扰。
根据 INA193 的功能框图可知其内部已经有相关的电阻了。

我使用了低阻值的采样电阻,这主要是为了降低发热量。降低发热量能从源头降低温漂影响,也能避免多处理一处发热量,顺便避免使用大功率电阻而占用过多空间。
用于采样电阻是低阻值的。根据前面的选型,使用的是 25 mΩ 的合金采样电阻,其两端电压大概是 VShunt=Imax×Rshunt=5A×25mΩ=125mVV_{Shunt} = I_{max} \times R_{shunt} = 5 A \times 25 \mathrm{m\Omega} = 125 \mathrm{mV}
负载电流读取
我将通过控制 DAC 输出的电压作为与增益后的电流采样分压对比的参考电压,通过运放控制 N-MOS 的导通程度使参考电压与实际采样转换后的电压一致,从而实现硬件恒流模式 。
初始化 DAC 后,要求 DAC 输出在 0 ~ 40 mV 是失调状态,实际输出一直是 40 mV 没变化,直到超过 40 mV 才正常。数据手册上说:

通过直接读取 DAC_DORx 寄存器上的数据,看起来是正确的。
根据 ST 论坛内容,似乎问题出在启用了内置的缓冲器上。看起来确实是这样,默认是启用的,禁用掉就正常了,下面是代码。手册上似乎没有提到这个问题,我还以为内部运放都是轨到轨的,草率了,哈哈。
let dac1 = Dac::new(p.DAC1, p.DMA1_CH2, p.DMA1_CH3, p.PA4, p.PA5);
let (mut dac1_ch1, mut dac1_ch2) = dac1.split();
dac1_ch1.set(dac::Value::Bit12Right(0));
dac1_ch2.set(dac::Value::Bit12Right(0));
// Disabling the buffer allows the voltage to be set to zero.
dac1_ch1.set_mode(dac::Mode::NormalExternalUnbuffered);
dac1_ch2.set_mode(dac::Mode::NormalExternalUnbuffered);
dac1_ch1.enable();
dac1_ch2.enable();

此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。