STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器

时间:2022-05-12 08:19:58

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

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

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

2.传感器模块图

STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器

3.MQ-2传感器原理图

STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器

4.传感器规格

STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器

查找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端。

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

STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器

STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器

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

STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器

代码如下:

主函数:main.c

  1. #include "printf.h"
  2. #include "adc.h"
  3. #include "systick.h"
  4. extern __IO uint16_t ADC_ConvertedValue;
  5. float ADC_ConvertedValueLocal;
  6. int main(void)
  7. {
  8. adc_init();
  9. printf_init();
  10. SysTick_Init(); //配置SysTick为1ms中断一次
  11. while(1)
  12. {
  13. ADC_ConvertedValueLocal =(float) ADC_ConvertedValue/4096*3.3;
  14. printf("The current AD value =0x%04X\n",ADC_ConvertedValue);
  15. printf("The current AD value =%f V\n",ADC_ConvertedValueLocal);
  16.  
  17. Delay_ms(1000);
  18. }
  19.  
  20. }

ADC初始化代码:

  1. void adc_init()
  2. {
  3. GPIO_InitTypeDef GPIO_InitStructure;
  4. ADC_InitTypeDef ADC_InitStructure;
  5. DMA_InitTypeDef DMA_InitStructure;
  6.  
  7. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
  8. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1,ENABLE);
  9. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
  10. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
  11. GPIO_Init(GPIOC,&GPIO_InitStructure);
  12.  
  13. DMA_DeInit(DMA1_Channel1);
  14. DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//ADC地址
  15. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue; //内存地址(要传输的变量的指针)
  16. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //方向(从内存到外设)
  17. DMA_InitStructure.DMA_BufferSize = 1; //传输内容的大小
  18. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址固定
  19. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //内存地址固定
  20. DMA_InitStructure.DMA_PeripheralDataSize =
  21. DMA_PeripheralDataSize_HalfWord ; //外设数据单位
  22. DMA_InitStructure.DMA_MemoryDataSize =
  23. DMA_MemoryDataSize_HalfWord ; //内存数据单位
  24. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular ; //DMA模式:循环传输
  25. DMA_InitStructure.DMA_Priority = DMA_Priority_High ; //优先级:高
  26. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止内存到内存的传输
  27.  
  28. DMA_Init(DMA1_Channel1, &DMA_InitStructure); //配置DMA1的1通道
  29.  
  30. DMA_Cmd(DMA1_Channel1,ENABLE);
  31.  
  32. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立ADC模式
  33. ADC_InitStructure.ADC_ScanConvMode = DISABLE; //禁止扫描方式
  34. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//开启连续转换模式
  35. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部触发转换
  36. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集数据右对齐
  37. ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换的通道数目
  38. ADC_Init(ADC1, &ADC_InitStructure);
  39.  
  40. RCC_ADCCLKConfig(RCC_PCLK2_Div8);//配置ADC时钟,为PCLK2的8分频,即9Hz
  41. ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5);//配置ADC1通道11为55.5个采样周期
  42. ADC_DMACmd(ADC1,ENABLE);
  43. ADC_Cmd(ADC1,ENABLE);
  44.  
  45. ADC_ResetCalibration(ADC1);//复位校准寄存器
  46. while(ADC_GetResetCalibrationStatus(ADC1));//等待校准寄存器复位完成
  47.  
  48. ADC_StartCalibration(ADC1);//ADC校准
  49. while(ADC_GetCalibrationStatus(ADC1));//等待校准完成
  50.  
  51. ADC_SoftwareStartConvCmd(ADC1, ENABLE);//由于没有采用外部触发,所以使用软件触发ADC转换
  52. }

adc.h:

  1. #ifndef _adc_H
  2. #define _adc_H
  3. #include "stm32f10x.h"
  4.  
  5. #define ADC1_DR_Address ((uint32_t)0x4001244c);
  6.  
  7. void adc_init(void);
  8.  
  9. #endif

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

硬件连线图:

STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器

测试图:

STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器

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

STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器的更多相关文章

  1. Spring 中基于 AOP 的 @AspectJ注解实例

    @AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格.通过在你的基于架构的 XML 配置文件中包含以下元素,@AspectJ 支持是可用的 ...

  2. stm32之ADC应用实例(单通道、多通道、基于DMA)

    文本仅做记录.. 硬件:STM32F103VCT6 开发工具:Keil uVision4 下载调试工具:ARM仿真器 网上资料很多,这里做一个详细的整合.(也不是很详细,但很通俗).  所用的芯片内嵌 ...

  3. stm32之ADC应用实例(单通道、多通道、基于DMA)-转载精华帖,最后一部分的代码是精华

    硬件:STM32F103VCT6    开发工具:Keil uVision4    下载调试工具:ARM仿真器网上资料很多,这里做一个详细的整合.(也不是很详细,但很通俗).所用的芯片内嵌3个12位的 ...

  4. STM32 多通道ADC采样,采用Timer1进行采样率控制,利用DMA进行传输

    http://blog.csdn.net/varding/article/details/17559399 http://www.51hei.com/stm32/3842.html https://w ...

  5. 基于STM32Cube的ADC模数采样设计

    1.背景         此实验建立在STM32F429核心板基础上,对于深刻了解STM32Cube使用具有深刻意义.利用DMA进行ADC采样,具有速度快,极大减少CPU消耗的优势,对于数据采集系统具 ...

  6. STM32的ADC采样时间

    STM32的ADC采样时间与其ADC的时钟频率密不可分. 例:STM32F103系列的ADC的时钟是在APB2(最大72MHZ)上.我们可以对其分频: RCC_PCLK2_Div2: ADC cloc ...

  7. STM32之ADC实例(基于DMA方式)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/zouleideboke/article/details/75112224 ADC简介: ADC(An ...

  8. GD32F330 | ADC实例 基于DMA方式

    GD32F330 | ADC实例 基于DMA方式 简单记录一下 ADC多通道转换 DMA搬运 的使用,以 GD32F330G8U6 为例: 一.ADC 基础知识 12位ADC是一种采用逐次逼近方式的模 ...

  9. 【STM32】用DMA实现多路ADC通道数据采集

    今天尝试了下STM32的ADC采样,并利用DMA实现采样数据的直接搬运存储,这样就不用CPU去参与操作了. 找了不少例子参考,ADC和DMA的设置了解了个大概,并直接利用开发板来做一些实验来验证相关的 ...

随机推荐

  1. C语言 · Torry的困惑(基本型)

    问题描述 Torry从小喜爱数学.一天,老师告诉他,像2.3.5.7--这样的数叫做质数.Torry突然想到一个问题,前10.100.1000.10000--个质数的乘积是多少呢?他把这个问题告诉老师 ...

  2. Android使用SAX解析XML(6)

    应用截图: (1)开始运行时 (2)选择学院 (3)选择专业 (4)选择班级 (5)选择班级的详细信息 本文参考了<Android平台开发之旅>.

  3. mysql 批量创建表,利用存储过程

    最近根据需求,需要提前创建一批日志表,以日期结尾,每天创建一张,例如XXX20160530,请参考如下: BEGIN    DECLARE `sName` VARCHAR(128);   DECLAR ...

  4. hdu 2828 Lamp 重复覆盖

    题目链接 给n个灯和m个开关, 每个灯可以由若干个开关控制, 每个开关也可以控制若干个灯, 问你能否找到一种开关的状态, 使得所有的灯都亮. 将灯作为列, 然后把每个开关拆成两行, 开是一行, 关是一 ...

  5. 拥抱开源,怎样关注Linux Kernel 邮件列表?

    现在开源如此火爆.以至于张口闭口不提到都仿佛不是搞IT 的.那么怎样拥抱开源?本文适合刚開始学习的人,如有大神至此,goto exit ! 一.怎样增加开源 以Linux 为例,这么一个成功的开源项目 ...

  6. Python脚本:获取股票信息

    在水木上看到有人在问到想用python去获取股票的信息,sina finance上面的那些数据的是通过js控制的,会根据股票代码去获取实时信息然后根据用户友好的方式展示出来.首先,新浪的一个url让我 ...

  7. Java 9 揭秘(2&period; 模块化系统)

    文 by / 林本托 Tips 做一个终身学习的人. 在此章节中,主要介绍以下内容: 在JDK 9之前Java源代码用于编写,打包和部署的方式以及该方法的潜在问题 JDK 9中有哪些模块 如何声明模块 ...

  8. PV 动态供给 - 每天5分钟玩转 Docker 容器技术(153)

    前面的例子中,我们提前创建了 PV,然后通过 PVC 申请 PV 并在 Pod 中使用,这种方式叫做静态供给(Static Provision). 与之对应的是动态供给(Dynamical Provi ...

  9. React 和 Redux 结合 1

    React依赖: "devDependencies": { "babel-core": "^6.26.0", "babel-loa ...

  10. 洛谷P1494 【&lbrack;国家集训队&rsqb;小Z的袜子】

    纪念自己独立完成的一道省选题(菜鸡如我只会看题解qwq) 还算是一道比较裸的莫队题把,比有的题目简单很多,也很好想怎么O(1)转移,比别的题就多了一个组合数计算(还有gcd??),还没算%意义下,也是 ...