3、数据采集与AD转换:模拟量采集与转换的硬核实战
各位同学,咱们今天聊点实在的。数据采集和AD转换,说白了就是FTU的“眼睛”和“耳朵”。你算法写得再漂亮,如果前端采集的数据是错的,那后面全是白搭。我当年刚入行时,就吃过这个亏,以为软件滤波能搞定一切,结果现场信号一塌糊涂。
好,咱们直接进入正题。
3.1 模拟量采集:电压/电流互感器
FTU要采集的模拟量,主要是电压和电流。电网里的电压是10kV甚至更高,电流可能几百安培。你想想看,ADC芯片能直接承受吗?当然不能。所以我们需要互感器,把高电压、大电流变成低电压、小电流。
电压互感器(PT):把一次侧的高电压,比如10kV,变成二次侧的100V或57.7V。嗯,这里要注意,二次侧电压是标准的,方便后续处理。
电流互感器(CT):把一次侧的大电流,比如600A,变成二次侧的5A或1A。我个人习惯用1A的CT,因为功耗小,发热低。
但问题来了,ADC的输入范围通常是0~3.3V或0~5V。二次侧的100V或1A还是太大了。怎么办?
再加一级信号调理电路。说白了,就是电阻分压、运放跟随、电平抬升这些活儿。我建议你设计时留出余量,比如ADC是3.3V,那调理后的信号峰值最好控制在2.5V左右,别卡着上限跑。
核心要点:互感器的精度等级直接影响采集精度。0.2级和0.5级的互感器,价格差不少,但现场效果天差地别。我在项目中遇到过,用了0.5级的CT,结果保护动作老是误动,换了0.2级的就好了。
3.2 AD转换原理:逐次逼近型 vs Σ-Δ型
ADC芯片种类很多,但在FTU里,最常见的就是两种:逐次逼近型(SAR)和Σ-Δ型。它们各有各的脾气。
3.2.1 逐次逼近型(SAR ADC)
SAR ADC的工作原理,你可以想象成“猜数字”游戏。比如一个8位的ADC,它先猜中间值128,比较一下输入信号比128大还是小。如果大了,就猜192;小了,就猜64。如此反复,直到猜出最接近的值。
它的优点是:速度快,转换时间固定,适合多通道轮询采集。我早期做的一个FTU项目,需要同时采集三相电压和三相电流,一共6个通道,用的就是SAR ADC,采样率能跑到200kSPS,完全够用。
但缺点也很明显:分辨率做不高。16位以上的SAR ADC,价格就上去了,而且噪声控制比较难。
我的经验:如果你需要采集工频信号(50Hz/60Hz),每周期采32个点,那SAR ADC的采样率只要1.6kSPS就够了。别盲目追求高采样率,够用就行。
3.2.2 Σ-Δ型 ADC
Σ-Δ型ADC就有点“作弊”的味道了。它用很低的精度(比如1位),但用极高的采样率(过采样)来换取高分辨率。然后通过数字滤波,把噪声滤掉,得到高精度的结果。
它的优点是:分辨率极高,轻松做到24位。而且内部自带抗混叠滤波器,外部电路可以简化。
但缺点也明显:速度慢。转换一次可能需要几毫秒,而且有“建立时间”的概念。你切换通道后,要等一段时间才能读到稳定数据。
为什么会这样?因为Σ-Δ型ADC内部的数字滤波器有群延迟。我记得有一次,我用Σ-Δ型ADC做直流采样,结果发现每次切换通道后,前几个数据都是错的。后来查手册才发现,需要丢弃前10个采样点。
避坑指南:我曾经在项目里直接用Σ-Δ型ADC采集工频信号,结果相位滞后了整整一个采样周期。后来我改用同步采样+软件补偿,才解决了问题。记住,Σ-Δ型ADC不适合做高速多通道同步采样。
3.3 采样率与分辨率选择
这两个参数,是ADC选型时最让人纠结的。我直接给你一个实用的选择思路。
3.3.1 采样率怎么定?
根据奈奎斯特定理,采样率至少是信号最高频率的2倍。但实际工程中,我建议至少取4~8倍。
对于工频信号(50Hz),如果你要做谐波分析,需要分析到31次谐波(1550Hz),那采样率至少要3.1kSPS。我个人习惯取6.4kSPS,也就是每周期128个点,这样分析起来比较舒服。
| 应用场景 | 信号频率 | 推荐采样率 | 每周期点数 |
|---|---|---|---|
| 工频测量(基波) | 50Hz | 1.6kSPS | 32 |
| 谐波分析(31次) | 1550Hz | 6.4kSPS | 128 |
| 暂态录波 | 10kHz | 100kSPS | 10 |
3.3.2 分辨率怎么选?
分辨率决定了你能分辨多小的信号变化。12位ADC,满量程3.3V,理论分辨率是3.3V / 4096 ≈ 0.8mV。16位ADC,分辨率是3.3V / 65536 ≈ 0.05mV。
但别被理论值骗了。实际有效分辨率(ENOB)通常比标称值低1~2位。我见过有人用16位ADC,结果噪声太大,实际只相当于12位。
我的建议是:
- 保护类应用(过流、过压):12位就够了,反应快最重要。
- 测量类应用(电能计量、谐波分析):至少16位,推荐24位Σ-Δ型。
- 录波类应用(故障记录):14~16位,采样率要够高。
核心原则:采样率和分辨率是矛盾的。高分辨率往往意味着低采样率。你不可能用24位Σ-Δ型ADC去采100kHz的信号。反过来,高速SAR ADC也很难做到18位以上。选型时,先定采样率,再选分辨率。
3.4 实战代码:ADC初始化与数据读取
光说不练假把式。我写一段伪代码,展示一下FTU里ADC的初始化流程。假设我们用的是SAR ADC,12位,SPI接口。
// ADC初始化函数
void ADC_Init(void) {
// 1. 配置GPIO:CS、SCLK、MISO、MOSI
GPIO_Init(ADC_CS_PIN, GPIO_MODE_OUTPUT);
GPIO_Init(ADC_SCLK_PIN, GPIO_MODE_OUTPUT);
GPIO_Init(ADC_MISO_PIN, GPIO_MODE_INPUT);
GPIO_Init(ADC_MOSI_PIN, GPIO_MODE_OUTPUT);
// 2. 配置SPI:模式0,时钟频率1MHz
SPI_Config(SPI_MODE_0, 1000000);
// 3. 配置ADC:单端输入,内部参考电压
ADC_WriteReg(ADC_REG_CONFIG, 0x0010);
// 4. 校准(可选)
ADC_Calibrate();
printf("ADC初始化完成,采样率:6.4kSPS\n");
}
// 读取单通道数据
uint16_t ADC_ReadChannel(uint8_t channel) {
uint16_t data;
// 片选拉低
GPIO_Write(ADC_CS_PIN, 0);
// 发送通道选择指令
SPI_Transmit(0x80 | (channel << 3));
// 读取12位数据(左对齐)
data = SPI_Receive();
// 片选拉高
GPIO_Write(ADC_CS_PIN, 1);
// 转换为电压值(假设参考电压3.3V)
float voltage = (data >> 4) * 3.3 / 4096.0;
return data;
}
小技巧:实际项目中,我习惯在ADC读取函数里加一个“数据有效性检查”。比如连续读两次,如果差值超过某个阈值,就认为数据抖动,重新读取。这能有效避免偶发的SPI通信错误。
好了,这一章的内容就到这里。数据采集和AD转换,是FTU的根基。你把这个搞扎实了,后面的算法实现才能站得住脚。下一章,咱们聊聊数字滤波,那才是真正考验功力的地方。