jjzjj

MQ2烟雾传感器模块——stm32f103

Aprilis askua 2023-10-29 原文

MQ2烟雾传感器的使用

ADC的使用

电压与浓度的转换

定时器的使用

ADC的使用

利用mq2传感器对气体进行检测,无非就是利用传感器内部的电路以及材料在不同气体环境下有着不同的电阻值,通过对电阻电压的采集来检测相应气体浓度的变化。这时我们就可以利用ADC来对外部传感器的电压值进行采集,ADC呢就是将连续变量的模拟信号转换为离散的数字信号。ADC部分大家不了解可以去详细了解一下,大佬们写的都很好。
接下来是代码部分:
首先对io口进行配置,再对ADC的模式进行配置。

void Adc_Init()//初始化函数
{ 
 GPIO_InitTypeDef GPIO_Initstructre;     
 ADC_InitTypeDef ADC_InitStruct;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOARCC_APB2Periph_ADC1,ENABLE)//使能时钟
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能io口
 GPIO_Initstructre.GPIO_Mode=GPIO_Mode_AIN; 
 GPIO_Initstructre.GPIO_Pin=GPIO_Pin_1;
 GPIO_Initstructre.GPIO_Speed=GPIO_Speed_50MHz;
 GPIO_Init(GPIOA,&GPIO_Initstructre);
 GPIO_SetBits(GPIOA,GPIO_Pin_1);
 
 RCC_ADCCLKConfig(RCC_PCLK2_Div6);//保证不超过14M
 ADC_DeInit(ADC1);//复位ADC1
 ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;//不使能连续扫描
 ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//数据右对齐
 ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//软件触发
 ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;//独立模式
 ADC_InitStruct.ADC_NbrOfChannel = 1;
 ADC_InitStruct.ADC_ScanConvMode = DISABLE;//不使用扫描模式
 ADC_Init(ADC1,&ADC_InitStruct);
 ADC_Cmd(ADC1,ENABLE);//使能指定的ADC1
 ADC_ResetCalibration(ADC1);//使能复位校准  
  
 while(ADC_GetResetCalibrationStatus(ADC1));//等待复位校准结束
 
 ADC_StartCalibration(ADC1);//开启AD校准
 
 while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
}

然后是ADC电压采集的相关函数

u16 Get_Adc(u8 ch)
{
 ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5);//ADC1,通道1,配置采集周期

 ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件复位

 while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//状态发生改变

 return ADC_GetConversionValue(ADC1);//返回值	

}

利用上一个函数的返回值进一步进行数据计算

u16 Get_Adc_Average(u8 ch,u8 times)//两个入口参数,通道,取平均值的次数
{
 u32 temp_val=0;
 u8 t;
 for(t=0;t<times;t++)
  {
   temp_val+=Get_Adc(ch);
   delay_ms(5);
  }
 return temp_val/times;

}

然后是对气体PPM的转换

void MQ2_cumlate(float RS)
{
		R0 = RS / pow(CAL_PPM / 613.9f, 1 / -2.074f);
}

float MQ2_GetPPM(void)
{   
	  u16 adcx;
	  adcx=Get_Adc_Average(ADC_Channel_1,30);//ADC1,取30次的平均值
      float Vrl = 3.3f * adcx / 4096.f;//3.3v的参考电压,4096份
	  Vrl = ( (float)( (int)( (Vrl+0.005)*100 ) ) )/100;
      float RS = (3.3f - Vrl) / Vrl * RL;
	  
      if(times<6) // 获取系统执行时间,3s前进行校准,用到了定时器
       {
		  R0 = RS / pow(CAL_PPM / 613.9f, 1 / -2.074f);//校准R0
       } 
	  float ppm = 613.9f * pow(RS/R0, -2.074f);

      return  ppm;
}

接下来是定时器部分的代码,这一部分主要是为了上方用到的校准

void TIM3_Int_Init(u16 arr,u16 psc)
{
	 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitSture;
	 NVIC_InitTypeDef NVIC_InitStructure;

	 
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//定时器3,时钟
	
	 TIM_TimeBaseInitSture.TIM_Period = arr;//自动装载值
	 TIM_TimeBaseInitSture.TIM_Prescaler = psc;//预分频系数
	 TIM_TimeBaseInitSture.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
	 TIM_TimeBaseInitSture.TIM_ClockDivision = TIM_CKD_DIV1;
	
	 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitSture);//定时器3
 
     TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//定时器3,更新中断,使能

	 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	 NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

     TIM_Cmd(TIM3,ENABLE);
}

void TIM3_IRQHandler(void)//中断函数,0.5秒中断一次
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)//判断状态
	 { 
		 TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除中断待处理位
		 times++;
	 }
}
	
	

最后我们可以通过串口助手,或者显示屏幕将数据进行显示,MQ系列的传感器主要就是ADC和相应的浓度转换。

电压值转化部分参考了以下博主的代码😁

https://blog.csdn.net/qq_41422043/article/details/89138213?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7

若有错误,请大家指出。😉😉😉

大家自取😭,不经常上csdn
https://pan.baidu.com/s/1Ljk8tgpFsnpGC9zx5zyz8w
提取码:44p5

有关MQ2烟雾传感器模块——stm32f103的更多相关文章

  1. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  2. STM32的HAL和LL库区别和性能对比 - 2

    LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L

  3. ESP32学习入门:WiFi连接网络 - 2

    目录一、ESP32简单介绍二、ESP32Wi-Fi模块介绍三、ESP32Wi-Fi编程模型四、ESP32Wi-Fi事件处理流程 五、ESP32Wi-Fi开发环境六、ESP32Wi-Fi具体代码七、ESP32Wi-Fi代码解读6.1主程序app_main7.2自定义代码wifi_init_sta()八、ESP32Wi-Fi连接验证8.1测试方法8.2服务器模拟工具sscom58.3测试代码8.4测试结果前言为了开发一款亚马逊物联网产品,开始入手ESP32模块。为了能够记录自己的学习过程,特记录如下操作过程。一、ESP32简单介绍ESP32是一套Wi-Fi(2.4GHz)和蓝牙(4.2)双模解决方

  4. Spring Security 6.0系列【32】授权服务器篇之默认过滤器 - 2

    有道无术,术尚可求,有术无道,止于术。本系列SpringBoot版本3.0.4本系列SpringSecurity版本6.0.2本系列SpringAuthorizationServer版本1.0.2源码地址:https://gitee.com/pearl-organization/study-spring-security-demo文章目录前言1.OAuth2AuthorizationServerMetadataEndpointFilter2.OAuth2AuthorizationEndpointFilter3.OidcProviderConfigurationEndpointFilter4.N

  5. ruby - 摘要::CRC32 与 Zlib - 2

    在我的代码中,我需要使用各种算法(包括CRC32)对文件进行哈希处理。因为我还在Digest系列中使用其他加密哈希函数,所以我认为为它们维护一个一致的接口(interface)会很好。为了记录,我确实找到了digest-crc,一颗完全符合我要求的gem。问题是,Zlib是标准库的一部分,并且有一个我想重用的CRC32工作实现。此外,它是用C编写的,因此它应该提供与digest-crc相关的卓越性能,后者是纯ruby​​实现。实现Digest::CRC32一开始看起来非常简单:%w(digestzlib).each{|f|requiref}classDigest::CRC32一切正常:

  6. ruby - 安装gem : Couldn't reserve space for cygwin's heap, Win32错误487错误 - 2

    我正在尝试在我的机器上安装win32-apigem,但在构建native扩展时我遇到了一些问题:$geminstallwin32-api--no-ri--rdocTemporarilyenhancingPATHtoincludeDevKit...Buildingnativeextensions.Thiscouldtakeawhile...C:\Programs\dev_kit\bin\make.exe:***Couldn'treservespaceforcygwin'sheap,Win32error0ERROR:Errorinstallingwin32-api:ERROR:Failed

  7. Ruby 1.9 - 没有这样的文件可以加载 'win32/open3' - 2

    我在Windows上运行ruby​​1.9.2并试图移植在Ruby1.8中工作的代码。该代码使用以前运行良好的Open4.popen4。对于1.9.2,我做了以下事情:通过geminstallPOpen4安装了POpen4需要POpen4通过require'popen4'尝试像这样使用POpen4:Open4.popen4("cmd"){|io_in,io_out,io_er|...}当我这样做时,我得到了错误:nosuchfiletoload--win32/open3如果我尝试安装win32-open3(geminstallwin32-open3),我会收到错误消息:win32-op

  8. Dell Inspiron 5488加内存32G - 2

    DellInspiron5488加内存32G 原装内置内存仅仅8G,目前看,真的太小了! 1.内存型号Dell5488内存型号:DDR42666。笔记本有两个内存插槽,原装占了一个,还能扩展一个。 2.买内存如果买Dell原装笔记本内存,8G就得500块左右。 我咨询了一下,三星的笔记本内存,可以兼容。16G,299块(2023年2月23日,京东价) Dell5488内存组合,最多只能插两根16G内存。 我于是买了两根三星16G内存。装上,很爽😄 跑国产系统统信UOS,再也看不到用交换区了,32G内存,爽!  

  9. 蓝桥杯 stm32 MCP4017 - 2

    本文代码使用HAL库。文章目录前言一、MCP4017的重要特性二、MCP4017计算RBW阻值三、MCP4017地址四、MCP4017读写函数五、CubeMX创建工程(利用ADC测量MCP4017电压)、对应代码:总结前言一、MCP4017的重要特性蓝桥杯板子上的是MCP4017T-104ELT,如图1。MCP4017是一个可编程电阻,通过写入的数值可以改变电阻的大小。重点在于6引脚(W),5引脚(B&#

  10. STM32 OTA应用开发——通过USB实现OTA升级 - 2

    STM32OTA应用开发——通过USB实现OTA升级目录STM32OTA应用开发——通过USB实现OTA升级前言1环境搭建2功能描述3BootLoader的制作4APP的制作5烧录下载配置6运行测试结束语前言什么是OTA?百度百科:空中下载技术(Over-the-AirTechnology;OTA),是通过移动通信的空中接口实现对移动终端设备及SIM卡数据进行远程管理的技术。经过公网多年的应用与发展,已十分成熟,网络运营商通过OTA技术实现SIM卡远程管理,还能提供移动化的新业务下载功能。实际上,现在我们所说的OTA比百度百科的定义还要更广泛,OTA的形式已经不再局限于手机和SIM卡,只要涉及

随机推荐