ADC采集值计算

单片机ADC检测4-20mA电路,以及计算方法

1、手里有一个4-20mA输出的液位传感器,测量范围是0m到10m。单片机要做的就是采集到这个信号,而且计算出当前的水位深度。下面给大家一个参考。

2、4-20mA信号在工业上是非常常见的一种信号,应用在各种传感器的输出上,突出优点就是抗干扰能力强,大家都知道,串联电路中,电流处处相等,那么信号线再长(比如几十米)也不用担心内阻问题导致的压降了。我们只需要检测电流大小即可,单片机检测的和传感器发射的一定是相等的电流。

3、单片机有一个12Bit的高精度ADC,能够精确检测0V到3.3V的电压(这里的3.3V指的是ADC电路的参考电压,一般在单片机电路上设计)。也就是说,如果外部有一个电压是0V到3.3V之间变化的,那么单片机就可以把它转化为数字0到数字4096之间,而且这个关系是线性的。实际电路如下:

4、传感器只需要根据正负极,接到连接器P15上即可。当传感器接好后,会有4到20mA的电流,流过电阻R39,那么对应的电阻上面的电压变化范围就是

传感器量程 传感器输出 ADC采集值
0m 4mA 775
10m 20mA 3696

 

 

 

  4~20mA模拟量转换的公式为:‌(adc_data-ADC_MIN)/(ADC_MAX-ADC_MIN)×(20mA-4mA)+4mA‌。这个公式在工业自动化和过程控制领域非常常用,因为它能将各种输入信号(如电压、电阻等)转换为4~20mA的电流信号,从而实现远距离传输和精确控制。

  水位胜读转换公式:(adc_data-ADC_MIN)/(ADC_MAX-ADC_MIN)×(10m-0m)+0m

  原理简述:

‌    输入信号‌adc_data:代表待转换的物理量对应的电信号值。
‌    最小值ADC_MIN与最大值‌ADC_MAX:定义了输入信号的范围,是转换公式中的重要参数。
‌    20mA-4mA‌:表示4~20mA电流信号的范围,是转换后的电流信号能够表示的物理量的范围。
‌    +4mA‌:确保转换后的电流信号始终在4mA以上,避免了信号为零时可能引起的误判。
  应用示例:
  假设我们有一个0~5V的电压信号需要转换为4~20mA的电流信号,那么可以按照以下步骤进行:

  确定输入信号的最小值和最大值,这里最小值为0V,最大值为5V。
  将输入信号代入转换公式:(输入电压-0V)/(5V-0V)×(20mA-4mA)+4mA。
  假设输入电压为2.5V,则转换后的电流信号为:(2.5V-0V)/(5V-0V)×(20mA-4mA)+4mA=12mA。

#define ADC_MIN        775            //ADC最小值        即4mA对应的的ADC值为775
#define ADC_MAX      3695        //ADC终点值        即20mA对应的ADC值为3695

//模拟量数据
typedef struct ADC_DataTypeDef
{
  float adc_value_1;//ADC1
  float adc_value_2;//ADC2
  float adc_value_3;//ADC3
}ADC_DataTypeDef;


ADC_DataTypeDef ADC_DataStruct; //ADC采集

/************************************************************************************************
  * @ 函 数 名:EQUIP_SensorDataParsing
  * @ 功能说明:液位和负压传感器数据处理
  * @ 参    数:无
  * @ 返 回 值:无
************************************************************************************************/
static void EQUIP_SensorDataParsing(void)
{
    static uint8_t collect_count;        //采集计数
    
    static uint32_t adc_2_data_accumulated;//adc2多次采样求平均值
    static uint32_t adc_3_data_accumulated;//adc3多次采样求平均值
    
    if (collect_count < 20)//采集20次求平均值
    {
        adc_2_data_accumulated = adc_2_data_accumulated + adc_2_data;
        adc_3_data_accumulated = adc_3_data_accumulated + adc_3_data;
        
        collect_count++;
    }
    else
    {    
        if (adc_2_data_accumulated/20 >= ADC_MIN)
        {
            ADC_DataStruct.adc_value_2 = (float)(adc_2_data_accumulated/20 - ADC_MIN)/(ADC_MAX - ADC_MIN)*(10-0);//液位传感器取值范围0~10米
        }
        else
        {
            ADC_DataStruct.adc_value_2 = 0;
        }
        
        if (adc_3_data_accumulated/20 >= ADC_MIN)
        {
            ADC_DataStruct.adc_value_3 = (float)(adc_3_data_accumulated/20 - ADC_MIN)/(ADC_MAX - ADC_MIN)*(-100-0);//压力传感器取值范围-100~0KPa
        }
        else
        {
            ADC_DataStruct.adc_value_3 = 0;
        }


        adc_2_data_accumulated = 0;
        adc_3_data_accumulated = 0;
        
        collect_count=0;
    }
}    
    

 

posted @ 2022-04-25 19:53  孤情剑客  阅读(949)  评论(0)    收藏  举报