1. 项目概述
这个基于单片机的电流电压采集系统是一个典型的嵌入式数据采集应用,通过可变电阻器模拟实际场景中的电压和电流变化,实现信号的实时采集与处理。我在工业自动化领域工作多年,这种基础但实用的采集系统是很多复杂项目的基础模块。
系统核心由三部分组成:信号模拟部分(两个可变电阻器)、信号调理电路、单片机处理单元。其中可变电阻器用于模拟传感器输出,单片机通过内置ADC(模数转换器)采集信号,最终实现电压电流值的数字化处理。这种设计在工业仪表、环境监测、设备状态监控等场景都有广泛应用。
2. 系统设计与核心组件
2.1 硬件架构解析
系统硬件设计遵循典型的嵌入式采集系统架构:
-
信号输入部分:
- 使用10kΩ多圈精密电位器作为可变电阻
- 电压信号:直接分压输入
- 电流信号:通过精密采样电阻转换为电压
-
信号调理电路:
- 电压跟随器(运放TL081)消除阻抗影响
- 二阶低通滤波器(截止频率100Hz)抑制高频噪声
- 信号幅值调整电路匹配ADC输入范围
-
核心控制器:
- 选用STM32F103C8T6单片机
- 内置12位ADC,采样率1MHz
- 内置基准电压源(2.5V±1%)
-
人机交互:
- 0.96寸OLED显示实时数据
- 三个按键用于参数设置
提示:实际工业应用中,建议使用隔离放大器(如ISO124)实现信号隔离,避免地环路干扰。
2.2 软件架构设计
系统软件采用分层架构:
c复制/* 软件架构伪代码 */
void main() {
hardware_init(); // 硬件初始化
adc_calibrate(); // ADC校准
while(1) {
adc_sample(); // 采集数据
data_filter(); // 数字滤波
value_convert(); // 工程值转换
display_update(); // 刷新显示
key_scan(); // 按键处理
}
}
关键处理流程:
- ADC采样使用定时器触发(1kHz)
- 采用滑动平均滤波算法(窗口大小16)
- 工程值转换使用查表法+线性插值
- 显示刷新率控制在30Hz避免闪烁
3. 核心电路实现细节
3.1 电压采集通道设计
电压采集采用经典分压电路:
code复制Vin --[R1 10k]--+--[R2 10k]--GND
|
ADC_IN
计算关系:
Vadc = Vin × (R2/(R1+R2))
实际电路需要考虑:
- 输入阻抗匹配(≥100kΩ)
- 分压电阻精度(建议0.1%)
- 输入保护(TVS二极管)
3.2 电流采集通道设计
电流采集使用采样电阻方案:
code复制Iin --[Rsense 0.1Ω]--+--[Load]
|
ADC_IN
关键参数:
- 采样电阻功率:P = I²×R(需留3倍余量)
- 信号放大倍数:G = 1 + Rf/Rg
- 共模抑制比(CMRR)≥80dB
3.3 PCB布局要点
- 模拟区域与数字区域严格分离
- ADC参考电压引脚加π型滤波
- 信号走线避免直角转折
- 地平面分割处理:
- 模拟地(AGND)
- 数字地(DGND)
- 单点连接(磁珠或0Ω电阻)
4. 软件实现关键代码
4.1 ADC配置代码
c复制void ADC_Config(void) {
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
4.2 数字滤波实现
c复制#define FILTER_LEN 16
uint16_t filter_buf[FILTER_LEN];
uint8_t filter_idx = 0;
uint16_t moving_average_filter(uint16_t new_val) {
static uint32_t sum = 0;
sum = sum - filter_buf[filter_idx] + new_val;
filter_buf[filter_idx] = new_val;
filter_idx = (filter_idx + 1) % FILTER_LEN;
return (uint16_t)(sum / FILTER_LEN);
}
5. 系统校准与测试
5.1 校准流程
-
零点校准:
- 短路输入端子
- 记录ADC读数作为零点偏移值
-
满量程校准:
- 施加标准信号(如2.5V)
- 调整增益系数使显示值匹配
-
线性度测试:
- 以10%间隔测试全量程
- 计算非线性误差:ε = (Vdisplay - Vstandard)/FS ×100%
5.2 典型测试数据
| 输入电压(V) | 显示电压(V) | 误差(%) |
|---|---|---|
| 0.00 | 0.002 | 0.08 |
| 0.50 | 0.498 | -0.40 |
| 1.00 | 1.003 | 0.30 |
| 1.50 | 1.502 | 0.13 |
| 2.00 | 1.997 | -0.15 |
| 2.50 | 2.503 | 0.12 |
6. 常见问题与解决方案
6.1 ADC读数不稳定
可能原因:
- 参考电压噪声
- 解决方法:增加LC滤波电路
- 地线干扰
- 解决方法:优化接地布局
- 电源纹波
- 解决方法:增加稳压芯片(如TPS7A4700)
6.2 测量值漂移
温度漂移补偿方案:
c复制float temp_compensate(float raw, float temp) {
// 温度系数补偿公式
return raw * (1 + 0.0005*(25 - temp));
}
6.3 多通道串扰
优化措施:
- 增加通道切换延时
c复制void ADC_Channel_Switch(uint8_t ch) { ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_55Cycles5); Delay_us(20); // 通道稳定时间 } - 采用差分输入方式
- 增加RC滤波(R=100Ω, C=100nF)
7. 系统优化方向
-
精度提升:
- 改用外部基准源(如REF5025)
- 采用过采样技术(16倍→增加2位分辨率)
-
抗干扰增强:
- 增加数字隔离(ADuM3151)
- 实施软件看门狗
-
功能扩展:
- 增加RS485通信接口
- 实现Modbus RTU协议
- 添加SD卡数据存储
我在实际部署中发现,这种基础采集系统最关键的三个要素是:稳定的参考电压、干净的PCB布局、合理的数字滤波。处理好这三点,系统精度通常能达到0.5%FS以上。对于需要更高精度的场合,建议采用24位Σ-Δ型ADC(如ADS1256),配合自动校准算法。