AD端口的漏电流对采集信号的影响
01 PWM 电流闭环
一、前言
这块电流与电压控制板上有一个开关恒流源。 在之前对此进行过测试。 通过软件闭环, 形成恒流输出。 这是它的功率PWM 功率输出部分, 现在核心控制MCU 使用的是 STM32F373。 下面对该恒流源电路进行硬件和软件调试。
AD\XQWF\2024\CLDesign\Ver5\CL
ARM\Keil\STM32\Test\2024\June\XQWFCLF373\MDK
二、调试的结果
1、PWM基本特性
首先测试一下 PWM输出的基本特性。 设置此时PWM占空比为50%。 可以测量此时PWM输出波形, 频率为 143.7kHz, 这是 72MHz的系统视频频率经过 501 分频之后的频率。 黄色波形是输出滤波电感之前的方波, 青色波形是滤波电感之后的电压波形。 负载电阻为 25欧姆的功率电阻, 电流采样电阻为 5欧姆的标准电阻。 电流采样电压为 0.927V。 这个电压的产生, 和电源电压, PWM占空比, 负载电阻、采样电阻、分压比有关系。 按照现在测试, 采样电压应该为 1V, 大于实际测量的 0.927V。 这是因为, PWM 波形虽然是 50% , 但实际上输出有死区, 输出的电压只有 11.3V。 由此, 测量了PWM输出的基本特性。
-
PWM基本参数:
-
频率
:143.7kHz=72MHz/501
ARR
:500
设置PWM从 0% 到99% 变化, 对应的 单片机中的 CCR 数值从 0 到499 变化。 测量对应的电流采样电压。 查看不同的PWM的占空比下的输出电流。 整体上呈现非常完美的线性关系。 在开始的部分, 有一点非线性, 这可能是单片机AD输入端口漏电流在输入电阻上的电压, 在占空比比较大的时候, 也出现了较大的失真, 具体原因不详。
▲ 图1.2.1 PWM与采集电压值
2、PWM零点
PWM 零点对于测量非常关键。 电流采样电压经过 R13, R14分压。 输入到单片机的ADC端口。 为什么会出现偏压 , 要么是D11 漏电流所致, 要么是从 单片机模拟端口输出的漏电流产生的电压。 如果将分压电阻从 10k欧姆 降低到 510欧姆, 也许就可以减少因为单片机的输出电流造成的零点偏移。 的确, 修改成 510欧姆之后, 比起之前的 73mV的偏压, 现在降低到3.48mV。 这个偏压的确与分压电阻有关系。 那么, 下面还需要对单片机的漏电流进行排查。
重新测试PWM的占空比与分压后的电压。 可以看到前面还是有非线性的情况。 如果直接测量电流采样电阻上的电压与分压后的电压, 他们之间是线性关系。 只是这个线性关系不通过 原点。 这个偏移是因为单片机 AD 端口的漏电流在分压电阻上产生的。
▲ 图1.2.2 分压电阻修改为510欧姆对应的PWM与电压之间的关系
from headm import *
from tsmodule.tsstm32 import *
from tsmodule.tsvisa import *
dm3068open()
pwm = linspace(0, 100, 100)
pdim = [int(p) for p in pwm]
vdim = []
for p in pdim:
stm32cmd("pwm %d\r"%p)
time.sleep(1.5)
v = dm3068vdc()
vdim.append(v)
printff(p,v)
plt.plot(pdim, vdim, lw=3)
plt.xlabel("PWM(%)")
plt.ylabel("Voltage(V)")
plt.grid(True)
plt.tight_layout()
plt.show()
▲ 图1.2.3 采样电阻电压与分压电压
from headm import *
from tsmodule.tsvisa import *
from tsmodule.tsstm32 import *
pdim = list(range(50))
vdim = []
v2dim = []
dm3068open()
for p in pdim:
stm32cmd("pwm %d\r"%p)
time.sleep(2)
meter = meterval()
vdim.append(meter[0])
o = dm3068vdc()
v2dim.append(o)
tspsave("measure", pdim=pdim, vdim=vdim, v2dim=v2dim)
printff(p, o, meter)
plt.plot(vdim, v2dim, lw=3)
plt.xlabel("Voltage(V)")
plt.ylabel("V2(V)")
plt.grid(True)
plt.tight_layout()
plt.show()
▲ 图1.2.4 采样电阻与ADC数值
pdim=[0.0000,1.0000,2.0000,3.0000,4.0000,5.0000,6.0000,7.0000,8.0000,9.0000,10.0000,11.0000,12.0000,13.0000,14.0000,15.0000,16.0000,17.0000,18.0000,19.0000,20.0000,21.0000,22.0000,23.0000,24.0000,25.0000,26.0000,27.0000,28.0000,29.0000,30.0000,31.0000,32.0000,33.0000,34.0000,35.0000,36.0000,37.0000,38.0000,39.0000,40.0000,41.0000,42.0000,43.0000,44.0000,45.0000,46.0000,47.0000,48.0000,49.0000]
vdim=[0.0000,0.0000,0.0197,0.0308,0.0349,0.0479,0.0555,0.0610,0.0676,0.0735,0.0807,0.0875,0.0951,0.1024,0.1098,0.1172,0.1245,0.1320,0.1393,0.1467,0.1541,0.1616,0.1690,0.1764,0.1838,0.1912,0.1987,0.2061,0.2135,0.2209,0.2283,0.2357,0.2431,0.2505,0.2579,0.2653,0.2727,0.2802,0.2876,0.2950,0.3024,0.3098,0.3172,0.3246,0.3320,0.3394,0.3468,0.3542,0.3616,0.3690]
v2dim=[0.0045,0.0045,0.0143,0.0198,0.0218,0.0283,0.0321,0.0348,0.0381,0.0410,0.0446,0.0480,0.0518,0.0554,0.0591,0.0628,0.0664,0.0701,0.0738,0.0775,0.0811,0.0848,0.0885,0.0923,0.0960,0.0996,0.1033,0.1070,0.1107,0.1144,0.1181,0.1217,0.1254,0.1291,0.1328,0.1365,0.1402,0.1439,0.1476,0.1513,0.1550,0.1587,0.1623,0.1660,0.1697,0.1734,0.1771,0.1808,0.1845,0.1881]
adcdim=[-31987.0000,-31974.0000,-31646.0000,-31433.0000,-31406.0000,-31197.0000,-31045.0000,-30996.0000,-30864.0000,-30739.0000,-30659.0000,-30525.0000,-30406.0000,-30314.0000,-30167.0000,-30056.0000,-29951.0000,-29796.0000,-29706.0000,-29582.0000,-29432.0000,-29334.0000,-29215.0000,-29072.0000,-28972.0000,-28850.0000,-28708.0000,-28613.0000,-28491.0000,-28342.0000,-28248.0000,-28121.0000,-27974.0000,-27880.0000,-27754.0000,-27607.0000,-27526.0000,-27379.0000,-27237.0000,-27153.0000,-27026.0000,-26874.0000,-26789.0000,-26653.0000,-26505.0000,-26426.0000,-26294.0000,-26155.0000,-26073.0000,-25924.0000]
▲ 图1.2.5 不同PWM下对应的采样电阻和ADC的数值
from headm import *
from tsmodule.tsvisa import *
from tsmodule.tsstm32 import *
dm3068open()
pdim = list(range(100))
adc = []
vdim = []
for p in pdim:
stm32cmd("pwm %d\r"%(p*4))
time.sleep(2)
stm32cmd("CLEAR")
time.sleep(.5)
stm32cmd("adc\r")
time.sleep(.5)
stm32cmd("COPY")
time.sleep(.5)
s = clipboard.paste().split('\r\n')
a = int(s[-1])
adc.append(a)
v = dm3068vdc()
vdim.append(v)
tspsave("adc", pdim=pdim, adc=adc, vdim=vdim)
printff(p, a)
plt.plot(vdim, adc, lw=3)
plt.xlabel("Voltage(V)")
plt.ylabel("ADC")
plt.grid(True)
plt.tight_layout()
plt.show()
这里给出了不同PWM输出的情况下, 在采样电阻上的电压与 单片机的 Sigma Delta ADC 读取的数值, 可以看到他们是线性的。 中间的这些变化, 估计是测量时, 电压探针接触不良造成的。
※ 总 结 ※
本文记录了对PWM 电流控制板的调试过程。 测量的输出PWM 波形的基本特征, 频率为 143kHz。 输出的电流通过分压之后到单片机的AD端口。 发现, 单片机的 AD端口会有反向输出漏电流。 造成电压零点的漂移。 这个可以通过减少输入电阻减少零点漂移。 不过, 这个电压是叠加在待测量电压基础上, 可以通过后期矫正来消除单片机 AD 漏电流的影响。 今天的调试工作就到这里了。
补充测量
下面是重新进行的补充测量,但是奇怪的是, 总是 有一段数值出现了莫名其妙的问题。
▲ 图2.1.1 重新测量的数据
pdim=[0.0000,1.0000,2.0000,3.0000,4.0000,5.0000,6.0000,7.0000,8.0000,9.0000,10.0000,11.0000,12.0000,13.0000,14.0000,15.0000,16.0000,17.0000,18.0000,19.0000,20.0000,21.0000,22.0000,23.0000,24.0000,25.0000,26.0000,27.0000,28.0000,29.0000,30.0000,31.0000,32.0000,33.0000,34.0000,35.0000,36.0000,37.0000,38.0000,39.0000,40.0000,41.0000,42.0000,43.0000,44.0000,45.0000,46.0000,47.0000,48.0000,49.0000,50.0000,51.0000,52.0000,53.0000,54.0000,55.0000,56.0000,57.0000,58.0000,59.0000,60.0000,61.0000,62.0000,63.0000,64.0000,65.0000,66.0000,67.0000,68.0000,69.0000,70.0000,71.0000,72.0000,73.0000,74.0000,75.0000,76.0000,77.0000,78.0000,79.0000,80.0000,81.0000,82.0000,83.0000,84.0000,85.0000,86.0000,87.0000,88.0000,89.0000,90.0000,91.0000,92.0000,93.0000,94.0000,95.0000,96.0000,97.0000,98.0000,99.0000]
adc=[-32021.0000,-31449.0000,-30904.0000,-30448.0000,-29970.0000,-29471.0000,-29004.0000,-28513.0000,-28013.0000,-27550.0000,-27056.0000,-26566.0000,-26097.0000,-25568.0000,-25076.0000,-24602.0000,-24110.0000,-23630.0000,-23152.0000,-22662.0000,-22172.0000,-21702.0000,-21213.0000,-20719.0000,-20254.0000,-19782.0000,-19289.0000,-18812.0000,-18332.0000,-17839.0000,-17364.0000,-16882.0000,-16387.0000,-15914.0000,-15435.0000,-14934.0000,-14465.0000,-13985.0000,-13486.0000,-13024.0000,-12546.0000,-12039.0000,-11573.0000,-11096.0000,-10595.0000,-10134.0000,-9649.0000,-9152.0000,-8687.0000,-8201.0000,-7703.0000,-7246.0000,-6752.0000,-6265.0000,-5812.0000,-5329.0000,-4826.0000,-4367.0000,-3884.0000,-3387.0000,-2926.0000,-2442.0000,-1948.0000,-1487.0000,-1006.0000,-514.0000,-57.0000,429.0000,932.0000,1381.0000,1865.0000,2363.0000,2818.0000,3299.0000,3797.0000,4248.0000,4728.0000,5225.0000,5673.0000,6152.0000,6650.0000,7100.0000,7583.0000,8074.0000,8524.0000,9002.0000,9496.0000,9949.0000,10429.0000,10912.0000,11366.0000,11843.0000,12330.0000,12782.0000,13255.0000,13746.0000,14195.0000,14668.0000,15155.0000,15604.0000]
vdim=[0.0000,0.0352,0.0680,0.0953,0.1247,0.1543,0.1840,0.2137,0.2433,0.2729,0.3026,0.3322,0.3618,0.3936,0.4234,0.4530,0.4824,0.5119,0.5415,0.5710,0.6004,0.6300,0.6595,0.6891,0.7186,0.7473,0.7768,0.8064,0.8359,0.8655,0.8950,0.9245,0.9540,0.9835,1.0130,1.0425,1.0720,1.1015,1.1309,1.1603,1.1898,1.2193,1.2487,1.2781,1.3075,1.3369,1.3662,1.3956,1.4249,1.4543,1.4836,1.5128,1.5421,1.5714,1.6000,1.6294,1.6587,1.6880,1.7173,1.7465,1.7758,1.8051,1.8343,1.8636,1.8927,1.9219,1.9511,1.9803,2.0095,2.0385,2.0676,2.0967,2.1258,2.1503,2.1706,2.1811,2.2420,2.2710,2.3000,2.3290,2.3580,2.3870,2.4159,2.4448,2.4737,2.5025,2.5314,2.5602,2.5890,2.6177,2.6465,2.6751,2.7039,2.7326,2.7613,2.7900,2.8187,2.8473,2.8760,2.9046]
▲ 图2.1.2 重新测量的数值
pdim=[0.0000,1.0000,2.0000,3.0000,4.0000,5.0000,6.0000,7.0000,8.0000,9.0000,10.0000,11.0000,12.0000,13.0000,14.0000,15.0000,16.0000,17.0000,18.0000,19.0000,20.0000,21.0000,22.0000,23.0000,24.0000,25.0000,26.0000,27.0000,28.0000,29.0000,30.0000,31.0000,32.0000,33.0000,34.0000,35.0000,36.0000,37.0000,38.0000,39.0000,40.0000,41.0000,42.0000,43.0000,44.0000,45.0000,46.0000,47.0000,48.0000,49.0000,50.0000,51.0000,52.0000,53.0000,54.0000,55.0000,56.0000,57.0000,58.0000,59.0000,60.0000,61.0000,62.0000,63.0000,64.0000,65.0000,66.0000,67.0000,68.0000,69.0000,70.0000,71.0000,72.0000,73.0000,74.0000,75.0000,76.0000,77.0000,78.0000,79.0000,80.0000,81.0000,82.0000,83.0000,84.0000,85.0000,86.0000,87.0000,88.0000,89.0000,90.0000,91.0000,92.0000,93.0000,94.0000,95.0000,96.0000,97.0000,98.0000,99.0000]
adc=[-32017.0000,-31445.0000,-30920.0000,-30444.0000,-29994.0000,-29494.0000,-29013.0000,-28536.0000,-28036.0000,-27562.0000,-27083.0000,-26582.0000,-26118.0000,-25652.0000,-25147.0000,-24660.0000,-24196.0000,-23699.0000,-23216.0000,-22746.0000,-22248.0000,-21764.0000,-21295.0000,-20788.0000,-20309.0000,-19840.0000,-19329.0000,-18854.0000,-18375.0000,-17890.0000,-17411.0000,-16928.0000,-16440.0000,-15958.0000,-15478.0000,-14983.0000,-14509.0000,-14023.0000,-13530.0000,-13057.0000,-12578.0000,-12084.0000,-11616.0000,-11133.0000,-10633.0000,-10165.0000,-9687.0000,-9188.0000,-8720.0000,-8243.0000,-7748.0000,-7277.0000,-6802.0000,-6309.0000,-5840.0000,-5357.0000,-4864.0000,-4397.0000,-3914.0000,-3421.0000,-2963.0000,-2484.0000,-1985.0000,-1530.0000,-1046.0000,-555.0000,-95.0000,390.0000,883.0000,1343.0000,1825.0000,2321.0000,2782.0000,3260.0000,3758.0000,4213.0000,4689.0000,5184.0000,5639.0000,6118.0000,6616.0000,7071.0000,7548.0000,8041.0000,8494.0000,8970.0000,9463.0000,9912.0000,10386.0000,10878.0000,11333.0000,11805.0000,12294.0000,12749.0000,13220.0000,13710.0000,14164.0000,14636.0000,15119.0000,15572.0000]
vdim=[0.0000,0.0347,0.0669,0.0946,0.1239,0.1533,0.1829,0.2125,0.2420,0.2715,0.3011,0.3306,0.3600,0.3895,0.4192,0.4488,0.4783,0.5079,0.5376,0.5672,0.5968,0.6264,0.6560,0.6856,0.7152,0.7449,0.7745,0.8039,0.8334,0.8628,0.8923,0.9218,0.9513,0.9808,1.0103,1.0398,1.0693,1.0988,1.1282,1.1577,1.1871,1.2165,1.2459,1.2753,1.3047,1.3341,1.3635,1.3928,1.4221,1.4514,1.4807,1.5100,1.5393,1.5686,1.5979,1.6272,1.6565,1.6858,1.7150,1.7443,1.7731,1.8023,1.8316,1.8608,1.8900,1.9146,1.9278,1.9777,2.0069,2.0307,2.0414,2.0115,2.1212,2.1080,2.1128,2.1293,2.1433,2.1483,2.1676,2.3267,2.3557,2.3846,2.4136,2.4425,2.4715,2.5004,2.5291,2.5580,2.5869,2.6157,2.6445,2.6733,2.7020,2.7307,2.7594,2.7881,2.8168,2.8454,2.8739,2.9026]
from headm import *
from tsmodule.tsvisa import *
from tsmodule.tsstm32 import *
dm3068open()
pdim = list(range(100))
adc = []
vdim = []
for p in pdim:
stm32cmd("pwm %d\r"%(p*4))
time.sleep(2)
stm32cmd("CLEAR")
time.sleep(.5)
stm32cmd("adc\r")
time.sleep(.5)
stm32cmd("COPY")
time.sleep(.5)
s = clipboard.paste().split('\r\n')
a = int(s[-1])
adc.append(a)
v = dm3068vdc()
vdim.append(v)
tspsave("adc", pdim=pdim, adc=adc, vdim=vdim)
printff(p, a)
plt.plot(vdim, adc, lw=3)
plt.xlabel("Voltage(V)")
plt.ylabel("ADC")
plt.grid(True)
plt.tight_layout()
plt.show()
■ 相关文献链接:
● 相关图表链接: