一部のDACチップにはAD5764などのキャリブレーションレジスタ(オフセット、ゲイン)がありますが、ads8689などの一部のADCチップにはないため、手動キャリブレーションが必要です。実際、ads8689の直線性は依然として非常に良好です。
キャリブレーション中、DACチップはDACチップの出力を測定するために必要であり、フィードバック結果はテーブルに記録されます。また、Excelの折れ線グラフで線形性を比較し、Pythonまたは他の言語を使用して単項線形回帰を実行し、kとbの値を見つけることもできます。
adc列は未校正の測定データ、meter列は高精度マルチメータの測定データ(これによる)、dac列は校正済みオフセットおよびゲインレジスタの出力電圧です。これで、インターセプトを使用してpythonを介して傾斜します。式は最小二乗法です。
import pandas as pd
import os
X = []
Y = []
def get_data(file_name):
global X, Y
data = pd.read_csv(file_name)
X = data['adc'].values
Y = data['meter'].values
if __name__ == '__main__':
proj_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) # 获取上级路径,这里根据个人需求自行修改
file_path = proj_path + r'\Fluke8845A_V1\dist\LCC1_Volt_Test Thu Sep 3 10_34_49 2020.csv'
get_data(file_path)
Xsum = 0.0
X_2sum = 0.0
Ysum = 0.0
XY = 0.0
n = len(X)
for i in range(n):
Xsum += X[i]
Ysum += Y[i]
XY += X[i] * Y[i]
X_2sum += X[i]**2
k = (Xsum * Ysum / n - XY) / (Xsum**2 / n - X_2sum)
b = (Ysum - k * Xsum) / n
print('y = %f*x + (%f)' % (k, b))
最後に、kとbをadcチップの測定機能に組み込むだけです。
float ADS8689_Analog_Digital(void)
{
static uint16_t temp;
static double x;
const float w = 3.0;
if (mutex == 0)
{
memset(receive, 0, sizeof(receive));
VOLT_OR_TEMP = 1;
CLK_SysTickDelay(100);
ADS8689_ReadWrite(ADS8689_NOP, 0x00, 0x0000);
ADS8689_ReadWrite(ADS8689_NOP, 0x00, 0x0000);
temp = ((uint16_t)receive[0] << 8) + receive[1];
x = (float)((((temp - 32768) * range) * reference_voltage) / 65536);
x *= w;
if (PD10 == 1) // channel A
{
x = ((x * 0.999232) - 0.000520363);
}
else
{
x = ((x * 0.999240) - 0.000354834);
}
VOLT_OR_TEMP = 0;
mutex = 1;
}
return x;
}
最後に、校正後のadcとメーター間の誤差は非常に小さく、校正なしの場合よりも効果がはるかに優れていることがわかります。(ここのユニットはすべてmvです)