本帖最后由 chenqiguang1998 于 2024-6-3 11:11 编辑
#申请原创# 在本次测评中,我们将对 APM32F411V Tiny Board 的 ADC 代码进行测试,并尝试驱动压力薄膜传感器。
一、引脚设置
首先,我们需要将压力薄膜传感器连接到 APM32F411V Tiny Board 的 ADC 引脚上。根据参考手册,我们可以将压力薄膜传感器的输出引脚连接到 APM32F411V Tiny Board 的 PA2 引脚上。
二、数据读取和转换代码
接下来,我们需要编写ADC代码来读取压力薄膜传感器的输出电压,并将其转换为压力值。以下是一个简单的ADC代码示例:
ADC_HandleTypeDef hadc1;
void MX_ADC1_Init(void) {
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
DAL_ADC_Init(&hadc1);
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 1U;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
DAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
u16 Get_Adc(ADC_HandleTypeDef *hadc1)
{
while(!__DAL_ADC_GET_FLAG(&hadc1, ADC_FLAG_EOC ));//等待转换结束
return DAL_ADC_GetValue(&hadc1); //返回最近一次ADC1规则组的转换结果
}
u16 Get_Adc_Average(ADC_HandleTypeDef *hadc1, u8 times) {
u32 temp_sum = 0;
u16 adc_value;
u8 t;
for(t = 0; t < times; t++) {
adc_value = Get_Adc(hadc1);
temp_sum += adc_value;
DAL_Delay(5);
}
return (times > 1) ? (u16)(temp_sum / times) : adc_value;
}
压力薄膜传感器接在LM393上,有两个属出口,分别是A0(模拟量输出)和D0(高低电平输出),此处考虑到使用场景的精细度,使用ADC进行读取转换;
在代码中,我们假设压力与 ADC 值成线性关系,并使用一个简单的线性方程来进行转换计算。具体来说,我们使用了以下公式:
- (x - in_min):计算输入值x与输入范围下限in_min之间的差值。
- (out_max - out_min) / (in_max - in_min):计算输入范围和输出范围之间的比例关系。
- 将步骤1的结果乘以步骤2的结果,得到一个与输入值x相对应的在输出范围内的偏移量。
- 最后,将步骤3的结果加上输出范围的下限out_min,得到映射后的压力值。
这样,通过该函数就可以将压力传感器的数值转换为实际的压力值,从而实现对压力的测量和监测。
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;
}
接着我们进行代码的测试:
#define PRESS_MIN 20
#define PRESS_MAX 6000
#define VOLTAGE_MIN 150
#define VOLTAGE_MAX 3300
uint8_t state = 0;
uint16_t val = 0;
uint16_t value_AD = 0;
long PRESS_AO = 0;
int VOLTAGE_AO = 0;
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;
}
long readPressureSensor() {
uint16_t value_AD = 0;
uint16_t voltage_AO = 0;
long pressure_AO = 0;
value_AD = Get_Adc_Average(1, 10); // 10次平均值
voltage_AO = map(value_AD, 0, 4095, 0, 3300);
if (voltage_AO < VOLTAGE_MIN) {
pressure_AO = 0;
} else if (voltage_AO > VOLTAGE_MAX) {
pressure_AO = PRESS_MAX;
} else {
pressure_AO = map(voltage_AO, VOLTAGE_MIN, VOLTAGE_MAX, PRESS_MIN, PRESS_MAX);
}
return pressure_AO;
}
int main()
{
long pressure=0;
DAL_Init();
SystemClock_Config();
MX_ADC1_Init();
while (1)
{
pressure = readPressureSensor();
printf("Pressure: %.2f\n", pressure);
DAL_Delay(1000);
}
}
|