STC 51单片机64——关于STC8H的ADC回程误差问题
所用单片机型号:STC8H1K08,具有10位ADC。用隔离放大器测量电源电压,发现问题:
电压从10V增到30V,与30V降到10V,得到的ADC值不一样,如图所示:
蓝线为电压逐渐增高测到的ADC值,星号是电压逐渐降低测到的值。发现ADC具有回程误差,神奇!下拐点为20.1V(ADC为282),上拐点为24.5V(ADC值为324)。之前拟合了老半天,误差总是很大,把每个电压点的数据都采集出来,才发现这个问题。
数据:
10,129,129
11,143,143
12,157,157
13,170,170
14,183,183
15,197,197
16,210,210
17,224,224
18,237,237
19,251,251
20,263,263
20.1,265,282
20.2,266,283
20.3,267,285
20.4,269,286
20.5,270,287
20.6,271,289
20.7,273,290
20.8,274,291
20.9,275,293
21,277,294
22,290,308
23,304,321
24,317,335
24.5,324,341
24.6,343,343
24.7,344,344
24.8,346,346
24.9,347,347
25,348,348
26,362,362
27,375,375
28,389,389
29,402,402
30,415,415
用代码进行分段拟合,分为下拟合曲线和上拟合曲线。Matlab代码:
temp=importdata('Data.txt');
%%
x=temp(:,1);
%电压从10V增到30V,与30V降到10V,得到的ADC值不一样,
%ADC具有回程误差,神奇!下拐点为20.1V(ADC为282),上拐点为24.5V(ADC值为324)
yIncrease=temp(:,2);
yDecrease=temp(:,3);
plot(x,yIncrease);
hold on;
plot(x,yDecrease,'*');
xlabel('Voltage');
ylabel('Adc');
legend('yIncrease','yDecrease');
%%
AdcUp=324;
AdcDown=282;
Ind1=find(yIncrease==AdcUp);
p = polyfit(yIncrease(1:Ind1),x(1:Ind1) , 1); % 1 表示线性拟合
a1 = p(1)
a2 = p(2)
Ind2=find(yDecrease==AdcDown);
p = polyfit(yDecrease(Ind2:end),x(Ind2:end) , 1); % 1 表示线性拟合
b1 = p(1)
b2 = p(2)
C51:
ouble VolForward=0.28;
double Vol=0;
u8 Dir=0; //0为电压升高,1为电压降低
u16 AdcUp=324;
u16 AdcDown=282;
void CalVoltage(u16 AdcV) //本次单片机电压为5.45V。
{
double Num=AdcV;
if(Dir==0){
if(AdcV<=AdcUp)
Vol = 0.0747 * Num + 0.3044; //下拟合曲线
else
Dir=1;
}
if(Dir==1){
if(AdcV>=AdcDown)
Vol = 0.0741 * Num - 0.7931; //上拟合曲线
else
Dir=0;
}
}
double GetVoltage(void)
{
SendString("Voltage is: ");
Show_double(Vol);
SendU8('\r');
SendU8('\n');
return Vol;
}