基于STM32的智慧宿舍系统(DAY5)_光照传感器、MQ2、电流传感器、紫外线传感器

注意上述右图的配置需要根据我们实际所使用的通道来,239.5这个是采样时间,根据需要调整,然后我们打到DMA配置项,如下图

这个地方只有DMA模式需要调整,完成上述配置后我们就可以生成代码了,然后我们按照如下步骤:

1、校准ADC,开启DMA接收,在main函数初始化部分调用

#define ADC_MAX_NUM  5 //表明通道数
#define BTN_BUFF_LEN 100 //采样次数
static uint16_t dma_adc_data[BTN_BUFF_LEN * ADC_MAX_NUM];

2、调用如下两句语句进行ADC校准

HAL_ADCEx_Calibration_Start(&hadc1);
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)dma_adc_data, BTN_BUFF_LEN * ADC_MAX_NUM);

DMA采集的数据存放buff,采集5个通道,每个通道采集BTN_BUFF_LEN次,dma_adc_data数据存放方式:HAL_ADC_Start_DMA(&hadc1, (uint32_t *)dma_adc_data, BTN_BUFF_LEN * ADC_MAX_NUM);
* 数据采集u32类型,dma_adc_data为u16类型,
* 第1个u32:通道1和通道2 * 第2个u32:通道3和通道4
* 第3个u32:通道5和通道1 * 第4个u32:通道2和通道3 * 第5个u32:通道4和通道5

3、进行数据获取,我们可以在循环调用如下函数,这样采集到的原始值会保存在ADC_Values,数据顺序为我们设置的顺序,比如ADC_Values[0],为我们第一个通道的值。

这里我们使用如下代码将其转换为电压:

// 常量定义
    const float ADC_VREF = 3.3f;
    const float ADC_RESOLUTION_12BIT = 4096.0f;
    const float ADC_RESOLUTION_10BIT = 1023.0f;
    const float ADC_CH1_CONV_FACTOR = 4980.0f / ADC_RESOLUTION_10BIT; // CH1 为 10-bit,参考电压 4980mV

    // 计算五个 ADC 通道的电压值
    adc_ch1.adc_voltage = ADC_Values[0] * ADC_CH1_CONV_FACTOR;  // mv
    adc_ch2.adc_voltage = ADC_Values[1] * ADC_VREF / ADC_RESOLUTION_12BIT; // v
    adc_ch3.adc_voltage = ADC_Values[2] * ADC_VREF / ADC_RESOLUTION_12BIT;
    adc_ch4.adc_voltage = ADC_Values[3] * ADC_VREF / ADC_RESOLUTION_12BIT;
    adc_ch5.adc_voltage = ADC_Values[4] * ADC_VREF / ADC_RESOLUTION_12BIT;

    // 打印通道的转换电压
    debug_print("\r\nADC1 通道电压: CH1 %.3f mV, CH2 %.3f V, CH3 %.3f V, CH4 %.3f V, CH5 %.3f V\r\n",
                adc_ch1.adc_voltage, adc_ch2.adc_voltage, adc_ch3.adc_voltage, adc_ch4.adc_voltage, adc_ch5.adc_voltage);
/**
 * @brief Get the Adc Value object 处理原始数据,获取5个通道的数据
 */
static void Get_Adc_Value(void)
{
    if (DMA_RECEIVE_OVER == 1) // DMA数据采集完处理数据
    {
        DMA_RECEIVE_OVER = 0;

        for (uint8_t adc_channel = 0; adc_channel < ADC_MAX_NUM; adc_channel++)
        {
            adc_max = 0;
            adc_add = 0;
            adc_min = 0xffff;
            for (uint16_t i = 0; i < BTN_BUFF_LEN; i++)
            {
                adc_add += dma_adc_data[ADC_MAX_NUM * i + adc_channel];
                adc_max = adc_max > dma_adc_data[ADC_MAX_NUM * i + adc_channel] ? adc_max : dma_adc_data[ADC_MAX_NUM * i + adc_channel];
                adc_min = adc_min < dma_adc_data[ADC_MAX_NUM * i + adc_channel] ? adc_min : dma_adc_data[ADC_MAX_NUM * i + adc_channel];
            }
            ADC_Values[adc_channel] = (adc_add - adc_max - adc_min) / (BTN_BUFF_LEN - 2);
        }
    }
}

计算后debug结果如下:

我们可以通过接入3.3V电压判断一下我们的转换是否正确,注意最大只能接入3.3V,否则会损坏管脚

我在通道2上接入3.3V电压,经过转换后我们得到的电压值为3.298,这个值与3.3V基本没啥差别,说明我们的ADC还是挺准的,到这里我们第一步已经完成了,下面就是根据电压值套公式转换了。这一步没啥讲的,直接查手册,套进去算就好了。

我们这里使用串口进行debug,打印出每个通道的电压,如下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值