基于GD32单片机的12位ADC压力采集(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

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

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
GD32系列的ADC模块支持多种采样方式和转换模式,可以通过不同的配置实现电压转换。 以下是一个简单的示例代码,演示了如何使用GD32ADC模块进行电压转换并获取转换结果: ```c #include "gd32f30x.h" void adc_init(void) { /* 使能 ADC0 时钟 */ rcu_periph_clock_enable(RCU_ADC0); /* 配置 ADC0 时钟分频为 8 */ adc_clock_config(ADC0, ADC_CLOCK_SYNC_PCLK_DIV8); /* 配置 ADC0 触发源为软件触发 */ adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); /* 配置 ADC0 为单次转换模式 */ adc_special_function_config(ADC0, ADC_SCAN_MODE, DISABLE); adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE); adc_special_function_config(ADC0, ADC_DISCONTINUOUS_MODE, DISABLE); adc_special_function_config(ADC0, ADC_DATA_ALIGN, ADC_DATAALIGN_RIGHT); adc_special_function_config(ADC0, ADC_TRIGGER_MODE, ADC_TRIG_MODE_SOFTWARE); adc_special_function_config(ADC0, ADC_CHANNEL_DISCON_DISABLE, ADC_REGULAR_CHANNEL); /* 配置 ADC0 通道 0 */ adc_regular_channel_config(ADC0, 0, ADC_SAMPLETIME_239POINT5, ADC_CHANNEL_0, ADC_REGULAR_DIFF_DISABLE); /* 使能 ADC0 */ adc_enable(ADC0); } uint16_t adc_get_value(void) { uint16_t adc_value; /* 启动 ADC0 转换 */ adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL); /* 等待转换完成 */ while (!adc_flag_get(ADC0, ADC_FLAG_EOC)); /* 读取转换结果 */ adc_value = adc_regular_data_read(ADC0); return adc_value; } int main(void) { uint16_t adc_value; /* 初始化 ADC0 */ adc_init(); /* 循环读取电压并输出 */ while (1) { adc_value = adc_get_value(); printf("Voltage: %.2fV\r\n", ((float)adc_value / 4096.0) * 3.3); } return 0; } ``` 在这个示例中,我们使用ADC0通道0进行电压转换。首先,在`adc_init`函数中进行ADC模块的初始化配置,包括时钟分频、触发源、转换模式、对齐方式、通道配置等。然后,在`adc_get_value`函数中启动ADC转换,并等待转换完成。最后,读取转换结果并计算电压。 需要注意的是,ADC转换结果是一个16的无符号整数,需要通过电压分压电路或其他方式将被测量电压转换为符合ADC输入电压范围的电压信号。在这个示例中,我们假设被测量电压范围为0-3.3V,因此将ADC参考电压设置为3.3V,并将转换结果除以4096(2的12次方)得到电压

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liang_Xia_Strive

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值