历史上的今天
返回首页

历史上的今天

今天是:2024年12月11日(星期三)

正在发生

2018年12月11日 | STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器

2018-12-11 来源:eefocus

最近学习了一下STM32中的ADC采样,由于手头正好有一个MQ-2的烟雾传感器,所以正好可以测试一把。体验ADC采样的过程。下面介绍一下这个MQ-2烟雾传感器。


1.MQ-2烟雾传感器简介


 MQ-2气体传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡(SnO2)。当传感器所处环境中存在可燃气体时,传感器的电导率随空气中可燃气体浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。 MQ-2气体传感器对液化气、丙烷、氢气的灵敏度高,对天然气和其它可燃蒸汽的检测也很理想。这种传感器可检测多种可燃性气体,是一款适合多种应用的低成本传感器。


2.传感器模块图



3.MQ-2传感器原理图



4.传感器规格



查找MQ-2传感器资料后,可知MQ-2传感器的加热电压为5.0v,当然经测试加热电压小于5v也是可以的,比如我在测试的时候,我给单片机的电压就是小于5V的,我的单片机没有接电源,直接是J-link接入PC然后pc进行供电,但最好还是单片机接上电源线,这样传感器比较灵敏。


5.MQ-2烟雾传感器模块特点


1、具有信号输出指示。


2、双路信号输出(模拟量输出及TTL电平输出)。


3、TTL输出有效信号为低电平。(当输出低电平时信号灯亮,可直接接单片机)                 


4、模拟量输出0~5V电压,浓度越高电压越高。


5、对液化气,天然气,城市煤气有较好的灵敏度。


6、结果受温湿度影响。


6.硬件连线


MQ-2传感器的VCC端用杜邦线接入32开发板的JP2(我的开发板上的JP2可输入5V电压),MQ-2传感器的GND端接32开发板的GND,32开发板上所有的GND可共用,这里最好接摄像头的GND,MQ-2传感器的AOUT端接开发板的摄像头(CAMERA)的PC1-ADC1端。


至于连线为什么这么连,与我写的代码以及我的开发板的原理图有关,如图:




注意:MQ-2模块的TTL输出端是悬空的,至于为啥是悬空的,这是厂家提供的,可以参考这个链接:点击打开链接



代码如下:


主函数:main.c


#include "printf.h"

#include "adc.h"

#include "systick.h"

extern __IO uint16_t ADC_ConvertedValue;  

float ADC_ConvertedValueLocal;  

int main(void)

{  

adc_init();

printf_init();

        SysTick_Init();   //配置SysTick为1ms中断一次

while(1)

            ADC_ConvertedValueLocal =(float) ADC_ConvertedValue/4096*3.3;  

            printf("The current AD value =0x%04X\n",ADC_ConvertedValue);  

            printf("The current AD value =%f V\n",ADC_ConvertedValueLocal); 

 

            Delay_ms(1000);

        }


}

ADC初始化代码:

void adc_init()

{

GPIO_InitTypeDef GPIO_InitStructure;

ADC_InitTypeDef ADC_InitStructure;

DMA_InitTypeDef DMA_InitStructure;


RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1,ENABLE);

        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;  

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;

GPIO_Init(GPIOC,&GPIO_InitStructure);


DMA_DeInit(DMA1_Channel1);

DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//ADC地址

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue; //内存地址(要传输的变量的指针)

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //方向(从内存到外设)

DMA_InitStructure.DMA_BufferSize = 1; //传输内容的大小

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址固定

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //内存地址固定

DMA_InitStructure.DMA_PeripheralDataSize = 

DMA_PeripheralDataSize_HalfWord ; //外设数据单位

DMA_InitStructure.DMA_MemoryDataSize = 

DMA_MemoryDataSize_HalfWord ;    //内存数据单位

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular  ; //DMA模式:循环传输

DMA_InitStructure.DMA_Priority = DMA_Priority_High ; //优先级:高

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;   //禁止内存到内存的传输


DMA_Init(DMA1_Channel1, &DMA_InitStructure);  //配置DMA1的1通道

 

DMA_Cmd(DMA1_Channel1,ENABLE);

 

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立ADC模式

ADC_InitStructure.ADC_ScanConvMode = DISABLE;  //禁止扫描方式

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//开启连续转换模式 

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部触发转换

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集数据右对齐

ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换的通道数目

ADC_Init(ADC1, &ADC_InitStructure);


RCC_ADCCLKConfig(RCC_PCLK2_Div8);//配置ADC时钟,为PCLK2的8分频,即9Hz

ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5);//配置ADC1通道11为55.5个采样周期 

        ADC_DMACmd(ADC1,ENABLE);

ADC_Cmd(ADC1,ENABLE);

 

ADC_ResetCalibration(ADC1);//复位校准寄存器

while(ADC_GetResetCalibrationStatus(ADC1));//等待校准寄存器复位完成

 

ADC_StartCalibration(ADC1);//ADC校准

while(ADC_GetCalibrationStatus(ADC1));//等待校准完成

 

ADC_SoftwareStartConvCmd(ADC1, ENABLE);//由于没有采用外部触发,所以使用软件触发ADC转换

}

adc.h:


#ifndef _adc_H

#define _adc_H

#include "stm32f10x.h"

 

#define ADC1_DR_Address  ((uint32_t)0x4001244c);

 

void adc_init(void);

 

#endif


延时函数在我这篇博客:点击打开链接


其实这里最好用用定时器来代替延时的,用定时器的话,不会占用CPU,这样会大大降低功耗,相反用延时的话会一直占用CPU,功耗增加可想而知,不过由于自己学习32也没有多久,对定时器的操作还不太熟,以后等自己熟悉了定时器的操作之后再来修改代码。


硬件连线图:



测试图:


其实在实际的应用中,会把ADC的转换值利用公式换算成为烟雾的浓度值,通过这个浓度值与预设值进行比对然后进行报警。不过为了使ADC的采样值更加精确,通常会取多个ADC采样值然后后求平均值,最后将平均值换算成为对应的烟雾浓度值。由于自己只是为了学习这个模块及了解一下ADC采样的过程,代码比较简单,写的很新手,有时间我再来优化一下这个代码。

推荐阅读

史海拾趣

Deltron / DEM Manufacturing公司的发展小趣事

DEM Manufacturing一直注重技术创新和产品升级。在合并后的几年里,公司投入大量资源用于研发,推出了一系列具有创新性的电子产品。这些产品不仅满足了市场的多样化需求,还为公司赢得了良好的口碑和广泛的客户基础。

CDIL[Continental Device India Pvt. Ltd.]公司的发展小趣事

随着市场竞争的加剧和技术的不断进步,CDIL在15年前作出了重要决策——退出晶圆制造,转而专注于IC封装和电子制造服务。这一转型不仅使CDIL能够更好地适应市场需求,也为其带来了更广阔的发展空间。如今,CDIL的IC封装技术已达到国际先进水平,为全球众多知名电子企业提供优质服务。

捷茂微(GATEMODE)公司的发展小趣事

近年来,CDIL积极响应政府政策,利用生产挂钩激励计划(PLI)和电子元件和半导体制造促进计划(SPECS),计划将其产能从目前的5亿片基础上提高1亿片。同时,公司还计划在未来几年内建立两条新的ATMP生产线,以进一步提升产能和技术水平。此外,CDIL还在碳化硅(SiC)等新技术领域进行了深入研发,以满足电动汽车、电源管理设备等新兴市场的需求。

Everspin Technologies公司的发展小趣事

Everspin一直致力于MRAM技术的创新和发展。其中,自旋转移力矩MRAM(STT-MRAM)是该公司的重要技术之一。Everspin在平面内和垂直磁隧道结(MTJ)STT-MRAM位单元的开发方面取得了显著成果,并积累了超过600项有效专利和应用的知识产权组合。这些技术的创新和专利的积累,使得Everspin在MRAM市场中保持了领先地位。

DIALIGHT公司的发展小趣事

DIALIGHT公司一直专注于工业LED照明领域的发展。他们深入了解工业空间照明的需求和挑战,设计了一系列专为工业应用而定制的LED照明产品。这些产品不仅易于安装和维护,而且能在恶劣的环境下持续使用。此外,DIALIGHT还提供集成系统解决方案,帮助客户降低能源成本、维护成本和碳足迹,同时提高设施的安全性和生产力。通过不断创新和优质服务,DIALIGHT在工业LED照明领域赢得了广泛的认可和信赖。

极海半导体(Geehy)公司的发展小趣事

DIALIGHT公司的故事始于1938年的纽约布鲁克林,当时该公司专注于为飞机生产仪表板灯。随着技术的不断进步和市场的变化,公司在1971年,即LED推出仅一年后,推出了他们的第一个LED产品。这一举措标志着DIALIGHT正式从传统的飞机仪表板灯制造转向LED照明技术的研发和应用。从此,DIALIGHT彻底改变了LED的用途,将其广泛应用于世界各地的交通控制、指示灯、结构塔和工业场所,为全球提供了优质的照明解决方案。

问答坊 | AI 解惑

vxworks下编译ace_tao的问题

我在XP下安装了tarnado2.2 for pcpentium, 目标用vmware建的虚拟机 用的是ace1.4和tao5.4a 按照ACE-INSTALL.html中介绍的方法,有几个环境变量不知道怎么设置 由于例子的目标机是PPC860所以下面三个参数如下 PATH=E:\\tornado\\host\\x86-win32 ...…

查看全部问答>

请教高手: 看门狗问题

为什么 430F413 看门狗复位时,内部ran,全部清零呢。这样过程值就不能使用了。看门狗就没什么意义了。请指导下。…

查看全部问答>

使用捕捉模块捕捉红外遇到的定时器计数问题

我的板子使用输入捕捉中断IC5来接收红外,可是我测试的时候一旦我按下红外以后,中断不断的进入,还有使用定时器读取到的值好像也有问题,请大牛们帮我看看我的程序,看看哪里有问题。void __ISR(_INPUT_CAPTURE_5_IRQ, ipl4) IRIntHandler( void ) ...…

查看全部问答>

C语言之父不可不说的故事

        计算机科学家先驱、C语言之父丹尼斯•里奇(Dennis Ritchie )已于10月12日去世,享年70岁。里奇是公认的Unix操作系统最好的合伙创始人,并且他还早在1971年就开发了C语音编程。下面就由福州卓跃教 ...…

查看全部问答>

TVP5150裁剪视频的问题

我在配置TVP5150的时候,利用AVID和VBLK裁剪视频,在寄存器配置的时候,发现对AVID的11h和12h,13h和14h配置,都能够在显示器上显示出变小的视频(水平方向),但是对VBLK的18h和19h配置,无论寄存器怎么设置,视频都不发生变化。我把5150的资料传 ...…

查看全部问答>

STM32F207串口通信

哪位仁兄有207的串口通信程序 能发一份吗 谢谢qlm1006@163.com…

查看全部问答>

msp430 入门 TI MSP430 LaunchPad 欢乐学习季学习交流

刚刚入手msp430 到ti公司申请了两片msp430f149 然后自己搭了最小系统就开始了msp430 我用的是iar for msp430   下面是io口操作的源代码…

查看全部问答>

altium designer 各种封装库

看着比较全的PCB封装 不想自己画封装的快来下载吧 [ 本帖最后由 最美的太阳 于 2012-6-8 09:11 编辑 ]…

查看全部问答>

关于CCS上的低级问题(求高手)

关于CCS上的低级问题(求高手) 本人新手,在CCS上进行512X512图像的小波变换,编译链接都正确,但是load数据运行时发生以下错误Error: Illegal opcode (422a0000) at pc = 0x00000004 Illegal opcode at pc = 0x00000004  在线跪求哪位 ...…

查看全部问答>