基于GD32单片机的50kg压力采集系统,附带源码和原理图

1,静止状态下采集的各项数值:

上位机监测到的ADC采集到的数据,该处采集的电压值是3.287mv,电压及压力值如下图:

 示波器采集的电压值:3.26V,与上述单片机采集的数值基本一致

 2,施加一定压力下采集的各项数值:

上位机监测到的ADC采集到的数据,该处采集的电压值是2.454mv,电压及压力值如下图:

 示波器采集的电压值:2.50V,与上述单片机采集的数值基本一致

 3,我们来看看其原理图,VCC这里接的是3.3V,U4便是我们的待测压力传感器,使用PA1的ADC0通道一进行检测:

4,源码,这里面加了均值滤波,电压,压力转换函数,用户只需要调用Get_Frc()接口函数即可,源码如下:

bsp_adc.c文件

#include "bsp_adc.h"
#include "bsp_usart.h"
#include "stdio.h"

/*********************************FSRADC*************************************************/
#define PRESS_MIN 20   // 最小量程 20g
#define PRESS_MAX 49999 // 最大量程 50kg  以具体型号的数据手册为准

#define VOLTAGE_MIN 1150 // 有效电压范围 可调节 这里指的是1.33V到3.28V
#define VOLTAGE_MAX 3280

long PRESS_AO = 0;
/**********************************************************
 * 函 数 名 称:adc_config
 * 函 数 功 能:ADC初始化
 * 传 入 参 数:无
 * 函 数 返 回:无
 * 作       者:
 * 备       注:无
 **********************************************************/
void adc_config(void)
{
    // 使能引脚时钟
    rcu_periph_clock_enable(RCU_GPIOC);
    // 使能ADC时钟
    rcu_periph_clock_enable(RCU_ADC0);
    // 配置ADC时钟
    adc_clock_config(ADC_ADCCK_PCLK2_DIV4);

    // 配置引脚为模拟输入模式
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);

    // 配置ADC为独立模式
    adc_sync_mode_config(ADC_SYNC_MODE_INDEPENDENT);

    // 使能扫描模式
    adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);

    // 数据右对齐
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);

    // ADC0设置为12位分辨率
    adc_resolution_config(ADC0, ADC_RESOLUTION_12B);

    // ADC0设置为规则组  一共使用 1 个通道
    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);

    // ADC外部触发禁用, 即只能使用软件触发
    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, EXTERNAL_TRIGGER_DISABLE);

    // ADC0使能
    adc_enable(ADC0);

    // 开启ADC自校准
    adc_calibration_enable(ADC0);
}

/**********************************************************
 * 函 数 名 称:Get_ADC_Value
 * 函 数 功 能:读取ADC值
 * 传 入 参 数:ADC_CHANNEL_x=要采集的通道
 * 函 数 返 回:测量到的值
 * 作       者:LiangXia
 * 备       注:无
 **********************************************************/
unsigned int Get_ADC_Value(uint8_t ADC_CHANNEL_x)
{
    unsigned int adc_value = 0;
    // 设置采集通道
    adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_x, ADC_SAMPLETIME_15);
    // 开始软件转换
    adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
    // 等待 ADC0 采样完成
    while (adc_flag_get(ADC0, ADC_FLAG_EOC) == RESET)
    {
        ;
    }
    // 读取采样值
    adc_value = adc_regular_data_read(ADC0);
    // 返回采样值
    return adc_value;
}

/**********************************************************
 * 函 数 名 称:map
 * 函 数 功 能:ADC函数处理
 * 传 入 参 数:待测值 x,   输入最大最小值:in_min,in_max,    输出最大最小值:out_min,out_max
 * 函 数 返 回:处理后的值
 * 作       者:LiangXia
 * 备       注:无
 **********************************************************/
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

/**********************************************************
 * 函 数 名 称:Get_Adc_Average
 * 函 数 功 能:均值滤波
 * 传 入 参 数:通道
 * 函 数 返 回:均值滤波处理后的值
 * 作       者:LiangXia
 * 备       注:无
 **********************************************************/
uint16_t Get_Adc_Average(uint8_t ch)
{
    uint32_t temp_val = 0;
    uint8_t t;
    for (t = 0; t < 40; t++)
    {
        temp_val += Get_ADC_Value(ch);
        delay_1ms(5);
    }
    return temp_val / 40;
}

/**********************************************************
 * 函 数 名 称:Get_Frc
 * 函 数 功 能:压力测试
 * 传 入 参 数:无
 * 函 数 返 回:无
 * 作       者:LiangXia
 * 备       注:无
 **********************************************************/
void Get_Frc()
{
    /* value convert */
    int VOLTAGE_AO = map(Get_Adc_Average(ADC_CHANNEL_1), 0, 4095, 0, 3300); // 前两位是采集ADC值(一般是0-4095,此处实际测试是2374-3907)  后两位是电压值
    if (VOLTAGE_AO < VOLTAGE_MIN)
    {
        PRESS_AO = PRESS_MAX;
    }
    else if (VOLTAGE_AO > VOLTAGE_MAX)
    {
        PRESS_AO = 0;
    }
    else
    {
        PRESS_AO = map(VOLTAGE_AO, VOLTAGE_MAX, VOLTAGE_MIN, PRESS_MIN, PRESS_MAX);
    }
    delay_1ms(10);
    printf("\r\n ADC data = %d \r\n", Get_Adc_Average(ADC_CHANNEL_1));
    printf("\r\n VOLTAGE data = %dmv \r\n", VOLTAGE_AO);
    printf("\r\n PRESS data = %dg \r\n", PRESS_AO);
}

bsp_adc.h文件

#ifndef __BSP_ADC_H
#define __BSP_ADC_H

#include "gd32f4xx.h"

void adc_config(void);
void Get_Frc();

#endif

上面代码有问题的请评论区评论指出,非常感谢,创作不易,还望点赞!

作者:Liang_Xia_Strive

物联沃分享整理
物联沃-IOTWORD物联网 » 基于GD32单片机的50kg压力采集系统,附带源码和原理图

发表评论