www.z-linear.com
一个ADC原始值32768怎么变成"5.000V"?16位和24位怎么换算?两点校准的Y=MX+N怎么算?校正系数和零点偏移怎么作用?本文是D223 ADC值到工程量的完整数学链路。
一、转换链路全景
AD7606原始数据(16位补码)
↓ ① 大端转换 SWAP16
↓ ② 256点滑动平均滤波(16位→24位)
↓ ③ 量程选择(±5V/±10V系数)
↓ ④ 两点线性校准(Y=MX+N)
↓ ⑤ 校正系数×零点偏移
↓ ⑥ 单位缩放(×0.00001)
↓ ⑦ 显示+单位
→ "5.000 V"
二、① 大端转换
2.1 SWAP16
D223通信协议使用大端模式,C#使用小端模式。需要SWAP16转换字节序。
// 固件中
int16 adcData = SWAP16(_qspiAdcBuf.data[j][i]);
// C#上位机
public static UInt16 SWAP16(UInt16 value) {
return (UInt16)((value >> 8) | (value << 8));
}
示例:
原始字节: 0x7F 0xFF (大端)
直接读取: 0xFF7F (小端, C#) = 65407
SWAP16后: 0x7FFF (正确) = 32767
三、② 256点滑动平均
3.1 算法
// 256点滑动平均
u32 sumTotal = 0;
for(u16 j = 0; j < 256; j++)
sumTotal += _uadc.getAdc_Buf256[i][j];
_uadc.getAdcFilter16[i] = sumTotal / 256; // 16位均值
_uadc.getAdcFilter24[i] = sumTotal; // 24位累加和
3.2 精度提升原理
16位ADC: 范围 -32768~32767
256点累加: 范围 -32768×256~32767×256 = -8388608~8388607
= 24位有符号范围 (-2^23~2^23-1)
均值: sumTotal / 256 → 恢复16位量级
累加和: sumTotal → 保持24位精度
3.3 16位 vs 24位
| 16位 | getAdcFilter16 | ~16位 | 152.6μV |
| 24位 | getAdcFilter24 | ~20位 | ~9.5μV |
四、③ 量程转换
4.1 转换系数
根据量程选择转换系数。16位值转换为mV,24位值转换为μV。
if(_framDatas._adcParam.adcRange & 0x01) { // ±10V量程
// 16位: mV值
int16 adc16 = (int16)_uadc.getAdcFilter16[i] – 32768;
_modbus._inputReg.adc_mV_Data16[i] = adc16 / 3.2768; // mV
// 24位: μV值
int32 adc24 = (int32)_uadc.getAdcFilter24[i] – 8388608;
_modbus._inputReg.adc_uV_Data24[i] = adc24 / 0.08388608 / 10; // μV
}
else { // ±5V量程
// 系数相应调整
}
4.2 系数推导
±10V量程, 16位
ADC范围: 0~65535 (无符号) 或 -32768~32767 (补码)
对应电压: -10V~+10V (20V范围)
转换:
V = (adc_raw – 32768) / 32768 × 10
V = (adc_raw – 32768) / 3276.8 (V)
mV = (adc_raw – 32768) / 3.2768 (mV)
系数: 3.2768 = 32768 / 10000
±10V量程, 24位
ADC范围: 0~16777215 (无符号) 或 -8388608~8388607 (补码)
对应电压: -10V~+10V
转换:
V = (adc_raw – 8388608) / 8388608 × 10
μV = (adc_raw – 8388608) / 8388608 × 10000000
μV = (adc_raw – 8388608) / 0.8388608
系数: 0.8388608 = 8388608 / 10000000
4.3 ±5V量程系数
16位mV: (adc16 – 32768) / 6.5536 (系数 = 32768/5000)
24位μV: (adc24 – 8388608) / 1.6777216 (系数 = 8388608/5000000)
4.4 系数总表
| ±10V | 16位 | mV | (adc-32768)/3.2768 | 3.2768 |
| ±10V | 24位 | μV | (adc-8388608)/0.8388608 | 0.8388608 |
| ±5V | 16位 | mV | (adc-32768)/6.5536 | 6.5536 |
| ±5V | 24位 | μV | (adc-8388608)/1.6777216 | 1.6777216 |
五、④ 两点线性校准
5.1 Y=MX+N
两点标定假设整个量程都是线性的,数字量和实际模拟量关系为Y=MX+N。
Y = M × X + N
A点: (d1, a1) → a1 = M × d1 + N
B点: (d2, a2) → a2 = M × d2 + N
求解:
M = (a2 – a1) / (d2 – d1)
N = a1 – M × d1
5.2 校准函数
// C#上位机
double calc_adcCalibData(double data, double d1, double a1,
double d2, double a2) {
double result = ((data – d1) * (a2 – a1) / (d2 – d1)) + a1;
return result;
}
5.3 标定流程
A点标定(30%量程):
输入: 已知模拟量 a1 = 2.000V → 存储1500000(×10^6)
采集卡读取当前ADC数字量 d1
→ 存入FRAM: calibPointA_d1, calibPointA_a1
→ calibEnableA = 1
B点标定(70%量程):
输入: 已知模拟量 a2 = 7.000V → 存储7000000
采集卡读取当前ADC数字量 d2
→ 存入FRAM: calibPointB_d2, calibPointB_a2
→ calibEnableB = 1
校准后:
对任意ADC值X: Y = (X-d1)×(a2-a1)/(d2-d1) + a1
5.4 模拟量存储精度
2.000V → 存储1500000
25.00℃ → 存储25000000
101.325kPa → 存储10132500
读取: result × 0.00001
1500000 × 0.00001 = 15.0 → 这是×10^7存储还是×10^6?
模拟量以×100000的整数存储,保证6位小数精度。
六、⑤ 校正系数与零点偏移
6.1 校正公式
final_value = calib_value × correctFactor + calibZero
calib_value = 两点校准结果
correctFactor = 校正系数(增益微调)
calibZero = 零点偏移(直流偏移微调)
6.2 校正系数的作用
| correctFactor | 增益微调 | 1.000000 | 0.9~1.1 |
| calibZero | 零点微调 | 0.000000 | ±1V |
6.3 应用场景
两点校准消除: 初始精度误差(±5mV) + 大范围增益误差
校正系数微调: 温度漂移 + 长期漂移的小量补偿
示例:
ADC校准值 = 5.000V
实际偏大0.1% → correctFactor = 0.999
final = 5.000 × 0.999 = 4.995V
ADC零点偏移0.01V → calibZero = -0.01
final = 5.000 × 1.0 + (-0.01) = 4.990V
七、⑥ 单位缩放
7.1 ×0.00001
模拟量以×100000的整数存储,显示时乘以0.00001恢复。
double actualValue = storedValue * 0.00001;
// 示例
storedValue = 5000000 → 5000000 × 0.00001 = 50.0
storedValue = 25000000 → 25000000 × 0.00001 = 250.0
7.2 ×10^7 vs ×10^6
根据代码分析,部分值使用×10^7存储:
// 校准后值
_modbus._inputReg.adc_calibData[i] =
getCalibAdcDatas(3, i, _uadc.getAdcFilter24[i]) * 100000;
// 显示时
double displayValue = _modbus._inputReg.adc_calibData[i] * 0.00001;
×100000(105)存储和×0.00001(10-5)还原,净效果是原值。存储为整数避免浮点误差。
八、⑦ 电流型转换
8.1 电流型公式
// 电流型(240Ω取样电阻)
// 电压→电流: I = V / R
if(signalType == 0) { // 电压型
// 直接显示电压
} else { // 电流型
_modbus._inputReg.adc_uA_Data16[i] =
adc16 / 3.2768 / 240 * 1000; // μA
// V = adc16 / 3.2768 (mV, ±10V量程)
// I = V / 240Ω × 1000 (μA)
}
8.2 电流型系数
电压→电流: I(A) = V(V) / 240(Ω)
电压→电流: I(mA) = V(mV) / 240
电压→电流: I(μA) = V(mV) / 240 × 1000 = V(mV) × 4.1667
九、完整计算示例
9.1 示例1:电压测量
条件: ±5V量程, 电压型, 16位模式
AD7606原始值: 32768 (0V)
Step ① SWAP16: 32768 → 32768 (0x8000不变)
Step ② 256点平均: sumTotal/256 = 32768 (getAdcFilter16)
Step ③ 量程转换(±5V, mV):
adc16 = 32768 – 32768 = 0
mV = 0 / 6.5536 = 0 mV → 0.000V
Step ④ 两点校准(假设A: d1=0, a1=0; B: d2=32768, a2=5000000):
Y = (32768-0)×(5000000-0)/(32768-0) + 0 = 5000000
Step ⑤ 校正(系数=1.0, 偏移=0):
final = 5000000 × 1.0 + 0 = 5000000
Step ⑥ 单位缩放:
display = 5000000 × 0.00001 = 50.0
→ 但这不对! 0V应该显示0V
实际: ADC=32768对应0V(±5V量程)
adc16 = 32768 – 32768 = 0 → 0V
校准: Y = (0-d1)×(a2-a1)/(d2-d1)+a1
如果A点: d1=-32768(对应-5V), a1=-5000000
B点: d2=32767(对应+5V), a2=5000000
则Y = (0-(-32768))×(5000000-(-5000000))/(32767-(-32768))+(-5000000)
= 32768 × 10000000 / 65535 – 5000000
≈ 0
→ 显示0.000V ✓
9.2 示例2:24位精密测量
条件: ±5V量程, 电压型, 24位模式
256点累加和: 8388608 (0V中点)
Step ③ 量程转换(±5V, μV):
adc24 = 8388608 – 8388608 = 0
μV = 0 / 1.6777216 = 0 μV → 0.000000V
9.3 示例3:电流测量
条件: ±5V量程, 电流型(240Ω), 16位
ADC原始值: 32768 → 0V
电流: I = 0V / 240Ω = 0mA ✓
ADC原始值: 49152 → +2.5V (半量程)
电流: I = 2500mV / 240 × 1000 = 10417μA ≈ 10.42mA
十、公式汇总表
| 大端转换 | SWAP16(raw) | 0x0080→0x8000 |
| 256点平均 | sum/256 (16位) | 32768 |
| 256点累加 | sum (24位) | 8388608 |
| 16位→mV(±5V) | (adc-32768)/6.5536 | 0→0mV |
| 16位→mV(±10V) | (adc-32768)/3.2768 | 0→0mV |
| 24位→μV(±5V) | (adc-8388608)/1.6777216 | 0→0μV |
| 24位→μV(±10V) | (adc-8388608)/0.8388608 | 0→0μV |
| 两点校准 | (X-d1)×(a2-a1)/(d2-d1)+a1 | 线性插值 |
| 校正系数 | Y×factor+zero | 微调 |
| 单位缩放 | value×0.00001 | 整数→浮点 |
| 电流转换 | V/240×1000 (μA) | V→I |
十一、总结
D223的ADC值到工程量转换实现了:
| ① SWAP16 | 大端→小端 | 无 |
| ② 256点平均 | 16位→24位 | +4位ENOB |
| ③ 量程转换 | mV/μV系数 | 无 |
| ④ 两点校准 | Y=MX+N | 消除初始误差 |
| ⑤ 校正系数 | ×factor+zero | 微调补偿 |
| ⑥ 单位缩放 | ×0.00001 | 无 |
| ⑦ 显示+单位 | “5.000V” | — |
从AD7606的16位补码到最终显示的"5.000V",经过7步数学转换。256点平均提升4位精度到20位,两点校准消除初始误差,校正系数补偿温漂——每一步都有明确的数学公式和物理意义。
下篇预告:《D223定时器系统分配全表》
网硕互联帮助中心




评论前必须登录!
注册