【GD32】MQ-8氢气检测传感器

2.36 MQ-8氢气检测传感器

MQ-8气体传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡(Sn0s)。当传感器所处环境中存在氢气时,传感器的电导率随空气中氢气浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。MQ-8气体传感器对氢气的灵敏度高,对其他干扰气体有很好的抑制性。这种传感器可检测多种含氢气体,特别是城市煤气,是一款适合多种应用场合的低成本传感器。

2.36.1 模块来源

采购链接:
MQ-8氢气传感器检测报警模块 气体传感器模块
资料下载链接:
https://pan.baidu.com/s/1B8WhPIzTmWwQsFFVayRpAA?pwd=9966
资料提取码:9966

2.36.2 规格参数

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

2.36.3 移植过程

我们的目标是在梁山派GD32F470上能够判断当前环境状况的功能。首先要获取资料,查看数据手册应如何实现,再移植至我们的工程。

2.36.3.1 查看资料

本品在较宽的浓度范围内对氢气有良好的灵敏度,具有长寿命、低成本、驱动电路简单等优点.

在这里插入图片描述

其对应的原理图见图2.36.3.1-2,AO输出为MQ-8传感器直接输出的电压,所以为模拟量;DO为经过LM393进行电压比较后,输出高低电平,所以为数字量。具体原理见光敏电阻光照传感器章节的2.3.3.1 查看资料。
在这里插入图片描述

因此DO引脚可以配置为GPIO的输入模式,AO引脚需要配置为ADC模拟输入模式。在这里插入图片描述
2.36.3.2 引脚选择
想要使用ADC,需要确定使用的引脚是否有ADC外设功能。可以通过数据手册,在数据手册的第28页结尾,是关于GD32F450Zx系列芯片引脚的功能定义示意图。
在这里插入图片描述

当前只有AO引脚需要使用到ADC接口,所以DO引脚可以使用开发板上其他的GPIO。这里选择使用PC1的附加ADC功能。使用ADC0的第11道输入通道。
在这里插入图片描述
在这里插入图片描述
2.36.3.3 移植至工程
移植步骤中的导入.c和.h文件与上一节相同,只是将.c和.h文件更改为bsp_mq8.c与bsp_mq8.h。见2.2.3.3 移植至工程。这里不再过多讲述。移植完成后面修改相关代码。
在文件bsp_mq8.c中,编写如下代码。

/********************************************************************************* 文 件 名: bsp_mq8.c* 版 本 号: 初版* 修改作者: LC* 修改日期: 2023年5月6日* 功能介绍:          ******************************************************************************* 注意事项:
*********************************************************************************/#include "bsp_mq8.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_single_data_parameter_struct dma_single_data_parameter;/* 使能引脚时钟 */rcu_periph_clock_enable(RCU_MQ8_GPIO_AO);                    rcu_periph_clock_enable(RCU_MQ8_GPIO_DO); /* 使能ADC时钟 */rcu_periph_clock_enable(RCU_MQ8_ADC);                /* 使能DMA时钟 */rcu_periph_clock_enable(RCU_MQ8_DMA);/*        配置ADC时钟        */ adc_clock_config(ADC_ADCCK_PCLK2_DIV4);        /*        配置DO为输入模式        */gpio_mode_set(PORT_MQ8_DO, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_MQ8_DO); /*        配置AO为浮空模拟输入模式        */gpio_mode_set(PORT_MQ8_AO, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_MQ8_AO); // PC1 : ADC012_IN11 /*        配置ADC为独立模式        */adc_sync_mode_config(ADC_SYNC_MODE_INDEPENDENT);/*        使能连续转换模式        */adc_special_function_config(PORT_ADC, ADC_CONTINUOUS_MODE, ENABLE);/*        使能扫描模式        */adc_special_function_config(PORT_ADC, ADC_SCAN_MODE, ENABLE);/*        数据右对齐        */        adc_data_alignment_config(PORT_ADC, ADC_DATAALIGN_RIGHT);/*        ADC0设置为规则组  一共使用 CHANNEL_NUM 个通道                */  adc_channel_length_config(PORT_ADC, ADC_REGULAR_CHANNEL, CHANNEL_NUM);/*        ADC规则通道配置:ADC0的通道11的扫描顺序为0;采样时间:15个周期                */  /*        DMA开启之后 gt_adc_val[x][0] = PC1的数据   */adc_regular_channel_config(PORT_ADC, 0, CHANNEL_ADC, ADC_SAMPLETIME_15);//PC1/*        ADC0设置为12位分辨率                */  adc_resolution_config(PORT_ADC, ADC_RESOLUTION_12B); /*        ADC外部触发禁用, 即只能使用软件触发                */  adc_external_trigger_config(PORT_ADC, ADC_REGULAR_CHANNEL, EXTERNAL_TRIGGER_DISABLE);/*        使能规则组通道每转换完成一个就发送一次DMA请求                */  adc_dma_request_after_last_enable(PORT_ADC);  /*        使能DMA请求                */  adc_dma_mode_enable(PORT_ADC);/*        使能DMA                */          adc_enable(PORT_ADC);/*        等待ADC稳定                */  delay_1ms(1);/*        开启ADC自校准                */adc_calibration_enable(PORT_ADC); /*        清除 DMA通道0 之前配置         */dma_deinit(PORT_DMA, CHANNEL_DMA);/*        DMA初始化配置         */dma_single_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(PORT_ADC));         //设置DMA传输的外设地址为ADC0基地址dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;                         //关闭外设地址自增dma_single_data_parameter.memory0_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_memory_width = DMA_PERIPH_WIDTH_16BIT;             //传输的数据位 为 16位dma_single_data_parameter.direction = DMA_PERIPH_TO_MEMORY;                                         //DMA传输方向为 外设往内存dma_single_data_parameter.number = SAMPLES * CHANNEL_NUM;                                     //传输的数据长度为:每个通道采集30次 * 1个通道dma_single_data_parameter.priority = DMA_PRIORITY_HIGH;                                                 //设置高优先级dma_single_data_mode_init(PORT_DMA, CHANNEL_DMA, &dma_single_data_parameter);//将配置保存至DMA1的通道0/*        DMA通道外设选择                *//*        数据手册的195页根据PERIEN[2:0]值确定第三个参数,例是100 则为DMA_SUBPERI4          例是010 则为DMA_SUBPERI2         *//*        我们是ADC0功能,PERIEN[2:0]值为000,故为DMA_SUBPERI0                */dma_channel_subperipheral_select(PORT_DMA, CHANNEL_DMA, DMA_SUBPERI0);/*        使能DMA1通道0循环模式                */dma_circulation_enable(PORT_DMA, CHANNEL_DMA);/*        启动DMA1的通道0功能                */dma_channel_enable(PORT_DMA, CHANNEL_DMA); /*        开启软件触发ADC转换                */adc_software_trigger_enable(PORT_ADC, 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_MQ8_Percentage_value* 函 数 说 明:读取MQ8值,并且返回百分比* 函 数 形 参:无* 函 数 返 回:返回百分比* 作       者:LC* 备       注:无
******************************************************************/
unsigned int Get_MQ8_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_MQ8_DO_value* 函 数 说 明:获取MQ8DO引脚的电平状态* 函 数 形 参:无* 函 数 返 回:0=未检测到高于灵敏度的氢气值 1=检测到高于灵敏度的氢气值* 作       者:LC* 备       注:调整模块上的滑动电阻即可调整灵敏度
******************************************************************/
char Get_MQ8_DO_value(void)
{if( gpio_input_bit_get(PORT_MQ8_DO,GPIO_MQ8_DO) == RESET ){return 0;}else{return 1;}
}

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

#ifndef _BSP_MQ8_H_
#define _BSP_MQ8_H_#include "gd32f4xx.h"#define RCU_MQ8_GPIO_AO    RCU_GPIOC
#define RCU_MQ8_GPIO_DO    RCU_GPIOF#define RCU_MQ8_ADC        RCU_ADC0
#define RCU_MQ8_DMA         RCU_DMA1#define PORT_DMA            DMA1
#define CHANNEL_DMA         DMA_CH0#define PORT_ADC            ADC0
#define CHANNEL_ADC         ADC_CHANNEL_11#define PORT_MQ8_AO         GPIOC
#define GPIO_MQ8_AO         GPIO_PIN_1#define PORT_MQ8_DO         GPIOF
#define GPIO_MQ8_DO         GPIO_PIN_11//采样次数
#define SAMPLES         30
//采样通道数 
#define CHANNEL_NUM     1extern 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_MQ8_Percentage_value(void);
char Get_MQ8_DO_value(void);#endif

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

/********************************************************************************* 文 件 名: main.c* 版 本 号: 初版* 修改作者: LC* 修改日期: 2022年05月06日* 功能介绍:          ******************************************************************************* 开发板官网:www.lckfb.com        
*********************************************************************************/#include "gd32f4xx.h"
#include "systick.h"
#include "bsp_usart.h"
#include "bsp_mq8.h"
#include "stdio.h"int main(void)
{nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  // 优先级分组systick_config();                //滴答定时器初始化 1msADC_DMA_Init();usart_gpio_config(115200U);printf("ADC+DMA demo start\r\n");while(1){        printf("%d%%\r\n", Get_MQ8_Percentage_value() );delay_1ms(1000);}
}                            

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/614783.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8绝缘子边缘破损检测系统(可以从图片、视频和摄像头三种方式检测)

可检测图片和视频当中出现的绝缘子和绝缘子边缘是否出现破损&#xff0c;以及自动开启摄像头&#xff0c;进行绝缘子检测。基于最新的YOLO-v8训练的绝缘子检测模型和完整的python代码以及绝缘子的训练数据&#xff0c;下载后即可运行。&#xff08;效果视频&#xff1a;YOLOv8绝…

高中数学:三角函数-cosx、sinx、tanx的函数图像与性质

一、sinx函数 1、图像 2、性质 sinx是奇函数 单调区间加2kπ&#xff0c;对称轴加kπ&#xff0c;这个确定的思路是&#xff0c;相同函数值&#xff0c;对应的x点之间的距离。 3、练习 例题1 例题2 例题3 例题4 二、cosx函数 1、图像 2、性质 cosx是奇函数 3、练…

SQLite 在Android安装与定制方案(十七)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite超详细的编译时选项&#xff08;十六&#xff09; 下一篇&#xff1a;SQLite Android 绑定&#xff08;十八&#xff09; 安装 有三种方法可以将 SQLite Android 绑定添加到应用程序&#xff1a; 1、通过…

win10系统中exe文件打不开

问题描述 昨天下载了某个驱动安装程序之后&#xff0c;点击.exe文件没有反应。 解决方法 1. 开启兼容模式运行 右键点击属性 点击【兼容性】&#xff0c;并且【以兼容模式运行程序】 2. 给exe文件换个文件夹再次尝试 我使用第一个方法没有用&#xff0c;之后尝试了把文…

[温故] 红黑树算法

前言 最近在突然想起一些基础的东西, 向着温故知新, 有了些新的感悟和大家分享一下. 排序算法是数据结构的一个重要组成部分, 当时学习的时候没有少折腾, 这里来看看大佬们怎么运用这些数据结构来构建庞大的计算机体系的. 二叉树是排序算法的一个衍生, 基于二叉树的构建不同…

Qt | 视频播放器(multimedia、multimediawidgets)

QT +=multimedia 通俗解释: 此代码行告诉编译器在构建应用程序时包含多媒体库。这意味着您的应用程序将能够播放和显示音频和视频文件。 使用分步说明构建模型: 创建一个新的 Qt 项目。 在 .pro 文件中添加以下行: QT += multimedia 导入必要的多媒体头文件: #include &l…

最新常见的图数据库对比,选型,架构,性能对比

图数据库排名 地址&#xff1a;https://db-engines.com/en/ranking/graphdbms 知识图谱查询语言 SPARQL、Cypher、Gremlin、PGQL 和 G-CORE 语法 / 语义 / 特性SPARQLCypherGremlinPGQLG-CORE图模式匹配查询语法CGPCGPCGP(无可选)1CGPCGP语义子图同态、包 2无重复边、包 2子…

物流自动分拣系统激光雷达漫反射板

早在二十世纪六十年代&#xff0c;激光器的诞生为激光雷达技术的发展奠定了基础。随后&#xff0c;激光雷达技术开始应用于各种领域&#xff0c;包括军事、航空、地理勘测等。然而&#xff0c;在物流自动分拣领域&#xff0c;激光雷达的应用相对较晚。 随着物流行业的快速发展和…

Windows安装MongoDB结合内网穿透轻松实现公网访问本地数据库

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

基于SpringBoot的“银行OA系统的设计与实现”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“银行OA系统的设计与实现”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 用户登录界面 管理员主界面 员工基本档…

GAN:对抗式生成网络之图片生成

对抗式生成网络(Adversarial Generative Network, AGN)这一术语在您提供的信息中并未直接出现。通常,在深度学习文献和实践中,与“对抗”和“生成”概念相结合的网络架构指的是生成式对抗网络(Generative Adversarial Networks, GANs)。GANs由Ian Goodfellow等人于2014年…

【C++学习】C++智能指针:提高代码安全与性能的利器

文章标题 智能指针的提出智能指针概念及使用RAII 智能指针的原理C库多种智能指针详解版本一&#xff1a;std::auto_ptr&#xff08;C98&#xff09;1. std::auto_ptr 使用2. std::auto_ptr 原理3. std::auto_ptr 模拟实现 版本二&#xff1a;unique_ptr (C11)1. unique_ptr 的使…