STM32教程第十二讲:使用ADC检测MQ2烟雾传感器浓度

文章目录

  • 需求
  • 一、MQ-2 气体传感器
  • 特点
  • 应用
  • 电路及引脚
  • 二、实现流程
  • 1.开时钟,分频,配IO
  • 2.配置ADC的工作模式
  • 3.配置通道
  • 4.复位,AD校准
  • 5.数值的获取
  • 需求实现
  • 总结

  • 需求

    使用ADC将MQ2模块检测到的烟雾浓度模拟量转化为数字量。
    最后,将实时检测的结果显示在串口上。


    一、MQ-2 气体传感器

    特点

    广泛的探测范围,高灵敏度,快速响应恢复,优异的稳定性,寿命长以及简单的驱动电路。

    应用

    可用于家庭和工厂的气体泄漏监测装置, 适宜于液化气、丁烷、丙烷、甲烷、酒精、氢气、烟雾等的探测。

    电路及引脚


    二、实现流程

    由于该模块的实现流程和ADC光照采集几乎一样,下面使用库函数的方式来编写。

    1.开时钟,分频,配IO

    该模块使用的引脚为PC1/ADC123_IN11,所以接下来我们要配置PC1。
    烟雾检测模块是获得一个模拟量,所以接引脚模式配置为模拟输入。
    代码如下:

    	//开时钟ADC1和PC
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1,ENABLE);
    	RCC_ADCCLKConfig(RCC_PCLK2_Div6); 
    	//配置GPIO口
    	GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//MQ2
        GPIO_Init(GPIOC, &GPIO_InitStructure);
    

    2.配置ADC的工作模式

    和光照检测一样,直接改成库函数就行。
    代码如下(示例):

    	ADC_InitTypeDef ADC_InitStruct={0};  //
    	ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//ADC独立模式
    	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
    	ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//选择软件SWSTART位触发
    	ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;//连续还是单次模式
    	ADC_InitStruct.ADC_ScanConvMode = DISABLE;//关闭扫描
    	ADC_InitStruct.ADC_NbrOfChannel = 1;
    	ADC_Init(ADC1,&ADC_InitStruct);
    	ADC_Cmd(ADC1, ENABLE);
    

    3.配置通道

    这里使用库函数编写就很简单了,直接一个函数就解决了。
    输入参数 1 ADCx:x 可以是 1 或者 2 来选择 ADC 外设 ADC1 或 ADC2
    输入参数 2 ADC_Channel:被设置的 ADC 通道
    输入参数 3 Rank:规则组采样顺序。取值范围 1 到 16。
    输入参数 4 ADC_SampleTime:指定 ADC 通道的采样时间值

    ADC_RegularChannelConfig(ADC1, ADC_Channel_11,1, ADC_SampleTime_239Cycles5);
    

    4.复位,AD校准

    没什么好说的,该部分可有可无,想严谨点的话就加上。

    	ADC_ResetCalibration(ADC1);//复位
    	  while(ADC_GetResetCalibrationStatus(ADC1));
        ADC_StartCalibration(ADC1);//AD校准
    	  while(ADC_GetCalibrationStatus(ADC1));	
    

    5.数值的获取

    依旧是先转换一次,再while等待转换完成,最后读取打印。

    void Get_Smoke_Value()
    {
    	uint16_t Smoke=0;
    	//让规则通道转换一次
    	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    	//ADC1->CR2 |= 0x01<<22;
    	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == 0)//判断寄存器的位2是不是等于1,是0就等待转换完成
    	{}
    	Smoke = ADC_GetConversionValue(ADC1); //读规则组通道数据寄存器
    	printf("烟雾浓度参数 = %d \r\n",Smoke);		
    	return; 
    }
    

    需求实现

    关键代码如下:
    main.c

    #include "stm32f10x.h"
    #include "usart.h"
    #include "stdio.h"
    #include "delay.h"
    #include "string.h"
    #include "pwm.h"
    #include "adc.h"
    
    int main()
    {
    	  NVIC_SetPriorityGrouping(5);//两位抢占两位次级
          Usart1_Config(); 
    	  SysTick_Config(72000);
    	  RGBpwm_Config();
    	  uint8_t cai_count=0;
    	  uint16_t cont=0;
    	  Adc_Config();
        while(1)
        {	
    			if(ledcnt[0]>=ledcnt[1]){//过去500ms
    			ledcnt[0]=0;
    					Get_Smoke_Value();
    			}
        }
    		
    		return 0;
    }
    
    

    adc.c

    #include "ADC.h"
    //库函数
    void Adc_Config(void)
    {
    	//开时钟ADC1和PC,PA
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1,ENABLE);
    	RCC_ADCCLKConfig(RCC_PCLK2_Div6); 
    	//配置GPIO口
    	GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//MQ2
        GPIO_Init(GPIOC, &GPIO_InitStructure);
    	//配置ADC1
    	ADC_InitTypeDef ADC_InitStruct={0};  //
    	ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//ADC独立模式
    	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
    	ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//选择软件SWSTART位触发
    	ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;//连续还是单次模式
    	ADC_InitStruct.ADC_ScanConvMode = DISABLE;//关闭扫描
    	ADC_InitStruct.ADC_NbrOfChannel = 1;
    	ADC_Init(ADC1,&ADC_InitStruct);
    	ADC_Cmd(ADC1, ENABLE);
    	//配置通道
    	ADC_RegularChannelConfig(ADC1, ADC_Channel_11,1,  ADC_SampleTime_239Cycles5);
    	//校准
    	ADC_ResetCalibration(ADC1);
    	  while(ADC_GetResetCalibrationStatus(ADC1));
        ADC_StartCalibration(ADC1);
    		while(ADC_GetCalibrationStatus(ADC1));	
    
    }
    
    void Get_Smoke_Value()
    {
    	uint16_t Smoke=0;
    	//让规则通道转换一次
    	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    	//ADC1->CR2 |= 0x01<<22;
    	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == 0)//判断寄存器的位2是不是等于1,是0就等待转换完成
    	{}
    	Smoke = ADC_GetConversionValue(ADC1); //读规则组通道数据寄存器
    	printf("烟雾浓度参数 = %d \r\n",Smoke);
    		
    	return; 
    }
    
    

    adc.h

    #ifndef _ADC_H_
    #define _ADC_H_
    #include "stm32f10x.h"
    #include "stdio.h"
    void Get_Smoke_Value();
    void Adc_Config(void);
    #endif
    		
    

    总结

    大致流程和ADC光照采集差别不大,照着一步一步做就能实现。

    作者:小白橘颂

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32教程第十二讲:使用ADC检测MQ2烟雾传感器浓度

    发表回复