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
上面代码有问题的请评论区评论指出,非常感谢,创作不易,还望点赞!