项目开发中有一些工业传感器输出信号为0-20mA或者4-20mA的电流信号,例如压力变送器,使用这类传感器时往往利用到单片机的ADC采集功能,通过欧姆定律将采集到的电压值和采样电阻的阻值进行计算,得出电流值。
一、硬件实现
方法一:
采样电阻直接测量,如下图所示,采样电阻选择100Ω,如果输出为0-20mA的电流那么单片机ADC采到的电压值范围为0-2V,选用STM32系列单片机能够检测该电流,采用ADC测量到采集的电压值后,电流=采集电压/采样电阻。
模拟图中采样电阻为100Ω,采集的电压为1.585v,1.585v/100Ω=0.01585A,与下方设备的电流相同。
方法二:
采用放大电路将采集的电压放大,并通过滤波器进行滤波,使得测量更精准,电路如下:
在该电路中左侧为差分放大电路,右侧为低通滤波电路,采样电阻为10Ω。图中H1为跳线帽,断开后可用万用表测量实际电流。
1.差分放大电路
采样电阻选用10Ω,采集电流为0-20mA,ADC采集的电压范围0-0.2v,利用差分放大器,放大10倍为0-2v方便采集技术。
差分放大计算公式:
本次设计中R5=R6=4.99k,R4=R7=49.9k,V1=0v,简化为:
最终采集到的电压为实际电压放大10倍。
2.低通滤波电路
电路设计
二、软件实现
本次选用STM32G030F6P6芯片,使用HAL库开发。
1.使用CubeMx建立ADC工程
注意:需要使能离散转换模式,没有使能会导致ADC多通道采集顺序混乱,使能后转换顺序按照Rank1-4进行转换
2.代码编写
uint16_t ADC_value[4] = {0}; //AD转换值
float Real_value1 = 0.0; //实际电压值
float Real_value2 = 0.0; //实际电压值
float Real_value3 = 0.0; //实际电压值
float Real_value4 = 0.0; //实际电压值
float ele1 = 0.0;//电流值
float ele2 = 0.0;//电流值
float ele3 = 0.0;//电流值
float ele4 = 0.0;//电流值
int main(void)
{
while (1)
{
for(int i=0;i<4;i++)
{
HAL_ADC_Start(&hadc1);
HAL_Delay(5);3
HAL_ADC_PollForConversion(&hadc1,0xffff);
ADC_value[i]=HAL_ADC_GetValue(&hadc1);
}
HAL_ADC_Stop(&hadc1);
/*计算电压 V*/
Real_value1 = (float)(ADC_value[0]&0xFFF)*3.3/4096;
Real_value2 = (float)(ADC_value[1]&0xFFF)*3.3/4096;
Real_value3 = (float)(ADC_value[2]&0xFFF)*3.3/4096;
Real_value4 = (float)(ADC_value[3]&0xFFF)*3.3/4096;
/*计算电流 A*/
//PA7_ADC1_IN7
ele4 = Real_value4/100*1000;
printf("PA7:%.2f \r\n",ele4);
//PA6_ADC1_IN6
ele3 = Real_value3/100*1000;
printf("PA6:%.2f \r\n",ele3);
//PA5_ADC1_IN5
ele2 = Real_value2/100*1000;
printf("PA5:%.2f \r\n",ele2);
//PA4_ADC1_IN4
ele1 = Real_value1/100*1000;
printf("PA4:%.2f \r\n",ele1);
HAL_Delay(1000);
}
}
三、实现效果
方法一效果
方法二效果
小结
经过比较采用方法二通过放大器和滤波电路采集的电流更为准确,同样成本较高,如果采用方法一电阻直接采集通过大量数据进行标定后也能更加精准。