【GD32E230】MQ-135 空气质量传感器 MQ135传感器 有害气体检测模块

2.37 MQ-135空气质量传感器
MQ135 气体传感器所使用的气敏材料是在清洁空气中电导率较低的二 氧化锡(SnO2)。当传感器所处环境中存在污染气体时,传感器的电导率随空 气中污染气体浓度的增加而增大。MQ135 气体传感器对氨气、硫化物、苯系 蒸汽的灵敏度高,对烟雾和其它有害气体的监测也很理想。这种传感器可检 测多种有害气体,是一款适合多种应用的低成本传感器。
2.37.1 模块来源
采购链接:
MQ-135 空气质量传感器 MQ135传感器 有害气体检测模块
资料下载链接:
https://pan.baidu.com/s/1B8WhPIzTmWwQsFFVayRpAA?pwd=9966
资料提取码:9966

2.37.2 规格参数
工作电压:3.3V-5V
工作电流:150MA
输出方式: DO接口为数字量输出 AO接口为模拟量输出
读取方式:ADC
管脚数量:4 Pin(2.54mm间距排针)
工作电流:150MA
输出方式: DO接口为数字量输出 AO接口为模拟量输出
读取方式:ADC
管脚数量:4 Pin(2.54mm间距排针)

2.37.3 移植过程
我们的目标是在立创开发板GD32E230C8T6上能够判断当前环境状况的功能。首先要获取资料,查看数据手册应如何实现,再移植至我们的工程。
2.37.3.1 查看资料
本品在较宽的浓度范围内对氨气,氮氧化合物,醇类,芳族化合物,硫化物,烟雾有良好的灵敏度,具有长寿命、低成本、驱动电路简单等优点.

在这里插入图片描述
其对应的原理图见图2.37.3.1-2,AO输出为MQ-135传感器直接输出的电压,所以为模拟量;DO为经过LM393进行电压比较后,输出高低电平,所以为数字量。具体原理见光敏电阻光照传感器章节的2.3.3.1 查看资料。在这里插入图片描述
因此DO引脚可以配置为GPIO的输入模式,AO引脚需要配置为ADC模拟输入模式。在这里插入图片描述
2.37.3.2 引脚选择在这里插入图片描述
2.37.3.3 移植至工程

在文件bsp_mq135.c中,编写如下代码

/********************************************************************************
  * 文 件 名: bsp_mq135.c
  * 版 本 号: 初版
  * 修改作者: LC
  * 修改日期: 2023年5月6日
  * 功能介绍:          
  ******************************************************************************
  * 注意事项:
*********************************************************************************/


#include "bsp_mq135.h"
#include "systick.h"


 //DMA缓冲区
uint16_t gt_adc_val[ SAMPLES ][ CHANNEL_NUM ]; 


/******************************************************************
 * 函 数 名 称:ADC_DMA_Init
 * 函 数 说 明:初始化ADC+DMA功能
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void ADC_DMA_Init(void)
{
        /* DMA初始化功能结构体定义 */
        dma_parameter_struct dma_single_data_parameter;

        /* 使能引脚时钟 */
        rcu_periph_clock_enable(RCU_MQ135_GPIO_AO);                    
        rcu_periph_clock_enable(RCU_MQ135_GPIO_DO); 
        /* 使能ADC时钟 */
        rcu_periph_clock_enable(RCU_MQ135_ADC);                

        /* 使能DMA时钟 */
        rcu_periph_clock_enable(RCU_MQ135_DMA);

        /*        配置ADC时钟        */ 
        rcu_adc_clock_config(RCU_ADCCK_APB2_DIV4);        
        /*        配置DO为输入模式        */
        gpio_mode_set(PORT_MQ135_DO, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_MQ135_DO); 
        /*        配置AO为浮空模拟输入模式        */
        gpio_mode_set(PORT_MQ135_AO, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_MQ135_AO);
        
        /*        清除 DMA通道0 之前配置         */
        dma_deinit(CHANNEL_DMA);
        /*        DMA初始化配置         */
        dma_single_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA);         //设置DMA传输的外设地址为ADC0基地址
        dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;     //关闭外设地址自增
        dma_single_data_parameter.memory_addr = (uint32_t)(gt_adc_val);         //设置DMA传输的内存地址为 gt_adc_val数组
        dma_single_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;      //开启内存地址自增(因为不止一个通道)
        dma_single_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
        dma_single_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;
        dma_single_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY;         //DMA传输方向为 外设往内存
        dma_single_data_parameter.number = SAMPLES * CHANNEL_NUM;               //传输的数据长度为:每个通道采集30次 * 1个通道
        dma_single_data_parameter.priority = DMA_PRIORITY_HIGH;                 //设置高优先级
        dma_init(CHANNEL_DMA, &dma_single_data_parameter);//将配置保存至DMA1的通道0
        
        /*        使能DMA1通道0循环模式                */
        dma_circulation_enable(CHANNEL_DMA);

        /*        启动DMA1的通道0功能                */
        dma_channel_enable(CHANNEL_DMA);         
        
        

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

        /*        使能连续转换模式        */
        adc_special_function_config(ADC_CONTINUOUS_MODE, ENABLE);
         
        /*        使能扫描模式        */
        adc_special_function_config(ADC_SCAN_MODE, ENABLE);

        /*        数据右对齐        */        
        adc_data_alignment_config(ADC_DATAALIGN_RIGHT);

        /*        ADC0设置为规则组  一共使用 CHANNEL_NUM 个通道                */  
        adc_channel_length_config(ADC_REGULAR_CHANNEL, CHANNEL_NUM);
                        
        /*        ADC规则通道配置:ADC0的通道11的扫描顺序为0;采样时间:55.5个周期                */  
        /*        DMA开启之后 gt_adc_val[x][0] = PC1的数据   */
        adc_regular_channel_config(0, CHANNEL_ADC, ADC_SAMPLETIME_55POINT5);

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

        /*        ADC外部触发禁用, 即只能使用软件触发                */  
                adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE); 
        adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);

        /*        使能规则组通道每转换完成一个就发送一次DMA请求                */  
        //adc_dma_request_after_last_enable();  

        /*        使能DMA请求                */  
        adc_dma_mode_enable();

        /*        使能DMA                */          
        adc_enable();

        /*        等待ADC稳定                */  
        delay_1ms(1);

        /*        开启ADC自校准                */
        adc_calibration_enable(); 



        /*        DMA通道外设选择                */
        /*        数据手册的195页根据PERIEN[2:0]值确定第三个参数,例是100 则为DMA_SUBPERI4          例是010 则为DMA_SUBPERI2         */
        /*        我们是ADC0功能,PERIEN[2:0]值为000,故为DMA_SUBPERI0                */
        //dma_channel_subperipheral_select(CHANNEL_DMA, DMA_SUBPERI0);


        /*        开启软件触发ADC转换                */
        adc_software_trigger_enable(ADC_REGULAR_CHANNEL); 
}
 

/******************************************************************
 * 函 数 名 称:Get_Adc_Dma_Value
 * 函 数 说 明:对DMA保存的数据进行平均值计算后输出
 * 函 数 形 参:CHx 第几个扫描的数据
 * 函 数 返 回:对应扫描的ADC值
 * 作       者:LC
 * 备       注:无
******************************************************************/
unsigned int Get_Adc_Dma_Value(char CHx)
{
        unsigned char i = 0;
        unsigned int AdcValue = 0;
    
    /* 因为采集 SAMPLES 次,故循环 SAMPLES 次 */
        for(i=0; i< SAMPLES; i++)
        {
        /*    累加    */
                AdcValue+=gt_adc_val[i][CHx];
        }
    /* 求平均值 */
        AdcValue=AdcValue / SAMPLES;
    
        return AdcValue;
}

/******************************************************************
 * 函 数 名 称:Get_MQ135_Percentage_value
 * 函 数 说 明:读取MQ135值,并且返回百分比
 * 函 数 形 参:无
 * 函 数 返 回:返回百分比
 * 作       者:LC
 * 备       注:无
******************************************************************/
unsigned int Get_MQ135_Percentage_value(void)
{
    int adc_max = 4095;
    int adc_new = 0;
    int Percentage_value = 0;
    
    adc_new = Get_Adc_Dma_Value(0);
    
    Percentage_value = ((float)adc_new/adc_max) * 100;
    return Percentage_value;
}

/******************************************************************
 * 函 数 名 称:Get_MQ135_DO_value
 * 函 数 说 明:获取MQ135DO引脚的电平状态
 * 函 数 形 参:无
 * 函 数 返 回:0=未检测到空气质量差 1=检测到空气质量正常
 * 作       者:LC
 * 备       注:调整模块上的滑动电阻即可调整灵敏度
******************************************************************/
char Get_MQ135_DO_value(void)
{
    if( gpio_input_bit_get(PORT_MQ135_DO,GPIO_MQ135_DO) == RESET )
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

在文件bsp_mq135.h中,编写如下代码

#ifndef _BSP_MQ135_H_
#define _BSP_MQ135_H_
 
#include "gd32e23x.h"
 
 
#define RCU_MQ135_GPIO_AO    RCU_GPIOA
#define RCU_MQ135_GPIO_DO    RCU_GPIOB

#define RCU_MQ135_ADC              RCU_ADC
#define RCU_MQ135_DMA        RCU_DMA

#define PORT_DMA             DMA
#define CHANNEL_DMA          DMA_CH0
 
#define PORT_ADC             ADC
#define CHANNEL_ADC          ADC_CHANNEL_1

#define PORT_MQ135_AO         GPIOA
#define GPIO_MQ135_AO         GPIO_PIN_1

#define PORT_MQ135_DO         GPIOB
#define GPIO_MQ135_DO         GPIO_PIN_1

 //采样次数
#define SAMPLES         30
//采样通道数 
#define CHANNEL_NUM     1


extern uint16_t gt_adc_val[ SAMPLES ][ CHANNEL_NUM ];  //DMA缓冲区
 

void ADC_DMA_Init(void);
unsigned int Get_Adc_Dma_Value(char CHx);
unsigned int Get_MQ135_Percentage_value(void);
char Get_MQ135_DO_value(void);

#endif

2.37.4 移植验证
在自己工程中的main主函数中,编写如下

 /******************************************************************************

  ******************************************************************************/
#include "gd32e23x.h"
#include "systick.h"
#include "bsp_usart.h"
#include "bsp_mq135.h"
#include "stdio.h"

int main(void)
{
    systick_config();                //滴答定时器初始化 1ms
    ADC_DMA_Init();
    usart_gpio_config(115200U);
    printf("ADC+DMA demo start\r\n");
    while(1)
    {        
        printf("%d%%\r\n", Get_MQ135_Percentage_value() );
        delay_1ms(1000);
    }
}                            

移植现象:输出换算后的空气质量百分比。在这里插入图片描述
移植成功示例,见文件2.37.4-1

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值