STM32中基于DMA的ADC采样实例之MQ

Wesley13
• 阅读 556

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

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

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

2.传感器模块图

STM32中基于DMA的ADC采样实例之MQSTM32中基于DMA的ADC采样实例之MQ

3.MQ-2传感器原理图

STM32中基于DMA的ADC采样实例之MQ

4.传感器规格

STM32中基于DMA的ADC采样实例之MQ

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

STM32中基于DMA的ADC采样实例之MQ

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

STM32中基于DMA的ADC采样实例之MQ

代码如下:

主函数: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. Delay_ms( 1000);

  17. }

  18. }

ADC初始化代码:

  1. void adc_init()

  2. {

  3. GPIO_InitTypeDef GPIO_InitStructure;

  4. ADC_InitTypeDef ADC_InitStructure;

  5. DMA_InitTypeDef DMA_InitStructure;

  6. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

  7. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1,ENABLE);

  8. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;

  9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;

  10. GPIO_Init(GPIOC,&GPIO_InitStructure);

  11. DMA_DeInit(DMA1_Channel1);

  12. DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //ADC地址

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

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

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

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

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

  18. DMA_InitStructure.DMA_PeripheralDataSize =

  19. DMA_PeripheralDataSize_HalfWord ; //外设数据单位

  20. DMA_InitStructure.DMA_MemoryDataSize =

  21. DMA_MemoryDataSize_HalfWord ; //内存数据单位

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

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

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

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

  26. DMA_Cmd(DMA1_Channel1,ENABLE);

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

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

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

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

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

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

  33. ADC_Init(ADC1, &ADC_InitStructure);

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

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

  36. ADC_DMACmd(ADC1,ENABLE);

  37. ADC_Cmd(ADC1,ENABLE);

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

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

  40. ADC_StartCalibration(ADC1); //ADC校准

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

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

  43. }

adc.h:

  1. #ifndef _adc_H

  2. #define _adc_H

  3. #include "stm32f10x.h"

  4. #define ADC1_DR_Address ((uint32_t)0x4001244c);

  5. void adc_init(void);

  6. #endif

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

硬件连线图:

STM32中基于DMA的ADC采样实例之MQ

测试图:

STM32中基于DMA的ADC采样实例之MQ

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

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
2年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这