【stm32简单外设篇】- MQ-2烟雾传感器模块

一、适用场景

适用场景:烟雾与火灾预警、嵌入式 ADC 与阈值比较实战教学等。

二、器材清单

MQ-2 气体传感器模块 ×1

stm32f103开发板 ×1

若干杜邦线 ×1组

稳定电源 5V×1

三、工作原理(要点)

MQ-2 属于 半导体气敏传感器,核心为 SnO₂ 敏感材料 + 内置加热丝:在空气中,SnO₂ 表面吸附氧分子,电阻较高当遇到可燃气体(甲烷、丁烷、LPG、烟雾等)时,气体与吸附氧发生反应,释放电子,敏感层电阻降低,输出电压发生变化

MQ-2 必须预热才能稳定工作,初次使用:建议预热 12--24 小时,日常使用:上电预热 2--5 分钟即可进入稳定状态

四、接线示意

GND → GND

VCC→ 5V/3.3V电源

标准库

数字信号

DO→ PC1

模拟信号

AO→PC1

HAL库

数字信号

DO→ PA0

模拟信号

AO→PA0

五、示例代码

标准库

数字信号

cpp 复制代码
#include "stm32f10x.h"
#include "stdio.h"
#include "bsp_SysTick.h"
#include "bsp_usart.h"


void gpio_init()
{
	GPIO_InitTypeDef PC;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

	PC.GPIO_Pin = GPIO_Pin_1;
	PC.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_Init(GPIOC,&PC);	
}


int main(void)
{	
	SysTick_Init();	    	 //延时函数初始化	  
	gpio_init();	  		//初始化与LED连接的硬件接口
	USART_Config();

	while(1)
	{
		if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1) == 0)
		{
			Usart_SendString(USART1,"有烟\n");
		}else
		{
			Usart_SendString(USART1,"无烟\n");
		}
		Delay_us(500000);
	}
}

模拟信号

cpp 复制代码
#include "breathing.h"
#include "stm32f10x.h"
#include "stdio.h"
#include "bsp_usart.h"

char showlight[20];
extern volatile uint16_t adc_light;

void TIM3_Int_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
	
	//定时器TIM3初始化
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式,即从0开始向上数到越界
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
 
	//中断优先级NVIC设置
	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寄存器
 
	TIM_Cmd(TIM3, ENABLE);  //使能TIMx					 
}




void TIM3_IRQHandler(void)
{
  uint16_t value;

	value = (adc_light)/74;
	
	
	if(TIM_GetITStatus(TIM3,TIM_IT_Update) == SET)
	{
			
			sprintf(showlight,"light:%d,value:%d\n",adc_light,value);
			Usart_SendString(USART1,showlight);
	}
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
#include "adc_time.h"
#include "stm32f10x.h"

volatile uint16_t adc_light;

void adcgpio_init()
{
	GPIO_InitTypeDef PC;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

	PC.GPIO_Pin = GPIO_Pin_1;
	PC.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_Init(GPIOC,&PC);
}

void adcmode_init()
{
	ADC_InitTypeDef adc;
	NVIC_InitTypeDef nvic;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2,ENABLE);
	
  adc.ADC_Mode=ADC_Mode_Independent;
	adc.ADC_ScanConvMode = DISABLE;
	adc.ADC_ContinuousConvMode = ENABLE;
	adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	adc.ADC_DataAlign = ADC_DataAlign_Right;
	adc.ADC_NbrOfChannel = 1;
	
	ADC_Init(ADC2,&adc);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div8);
	ADC_RegularChannelConfig(ADC2,ADC_Channel_11,1,ADC_SampleTime_55Cycles5);
	ADC_ITConfig(ADC2,ADC_IT_EOC,ENABLE);

	ADC_Cmd(ADC2,ENABLE);
	
	ADC_ResetCalibration(ADC2);
	while(ADC_GetResetCalibrationStatus(ADC2));
	
	ADC_StartCalibration(ADC2);
	while(ADC_GetCalibrationStatus(ADC2));
	
	ADC_SoftwareStartConvCmd(ADC2,ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
  nvic.NVIC_IRQChannel = ADC1_2_IRQn;
	nvic.NVIC_IRQChannelPreemptionPriority = 3;
	nvic.NVIC_IRQChannelSubPriority = 0;
	nvic.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&nvic);

	
}

void adctime_Init()
{
	adcgpio_init();
	adcmode_init();
}

void ADC1_2_IRQHandler(void)
{
	if(ADC_GetITStatus(ADC2,ADC_IT_EOC) == SET)
	{
		adc_light = ADC_GetConversionValue(ADC2);
	}
	ADC_ClearITPendingBit(ADC2,ADC_IT_EOC);
}
#include "stm32f10x.h"
#include "stdio.h"
#include "bsp_SysTick.h"
#include "adc_time.h"
#include "breathing.h"
#include "bsp_usart.h"

int main()
{
	USART_Config();
	adctime_Init();
	TIM3_Int_Init(4999,7199);  //定时500ms
	while(1)
	{
	}
//	return 0;
}

HAL库

数字信号

cpp 复制代码
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == 1)
			HAL_UART_Transmit(&huart1,"无烟雾\r\n", strlen("无烟雾\r\n"), HAL_MAX_DELAY);
		else
			HAL_UART_Transmit(&huart1,"有烟雾\r\n", strlen("有烟雾\r\n"), HAL_MAX_DELAY);
		HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

模拟信号

cpp 复制代码
int main(void)
{

  /* USER CODE BEGIN 1 */
  char show[20]={0};
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		//#1。启动常规序列
		HAL_ADC_Start(&hadc1);
		//#2.等待转换完成
		HAL_ADC_PollForConversion(&hadc1,HAL_MAX_DELAY);
		//#3。获取结果
		uint32_t dr = HAL_ADC_GetValue(&hadc1);
		//#4.把结果转换成电压
		float voltage = dr *(3.3f-0.0f)/4095.0f;
		sprintf(show,"adc:%d,%.2f\n",dr,voltage);
		HAL_UART_Transmit(&huart1,show,strlen(show),HAL_MAX_DELAY);
		HAL_Delay(500);
//		if(voltage>1.5f)//光线暗
//			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_13,GPIO_PIN_SET);// 灭灯
//		else//光线亮
//			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_13,GPIO_PIN_RESET); // 亮灯

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

六、讲解视频

https://www.bilibili.com/video/BV1LzvvBjEh7/?spm_id_from=333.1387.search.video_card.click&vd_source=f7dfe1b14f260b9cc3a146d2dbfd0719

https://www.bilibili.com/video/BV1J8vvBpEBe/?spm_id_from=333.1387.search.video_card.click&vd_source=f7dfe1b14f260b9cc3a146d2dbfd0719

https://www.bilibili.com/video/BV1ntvvB9Ey1/?spm_id_from=333.1387.search.video_card.click&vd_source=f7dfe1b14f260b9cc3a146d2dbfd0719

相关推荐
上海合宙LuatOS2 小时前
LuatOS核心库API——【iperf 】吞吐量测试
linux·运维·服务器·单片机·嵌入式硬件·物联网·硬件工程
上海合宙LuatOS2 小时前
LuatOS核心库API——【iotauth 】 IOT 鉴权库
java·单片机·嵌入式硬件·物联网·struts·计算机外设·硬件工程
无限进步_2 小时前
138. 随机链表的复制 - 题解与详细分析
c语言·开发语言·数据结构·算法·链表·github·visual studio
m0_531237172 小时前
C语言-内存函数
c语言·开发语言·算法
wengqidaifeng2 小时前
数据结构(四)二叉树初步:计算机科学中的分叉树
c语言·数据结构
学嵌入式的小杨同学3 小时前
嵌入式硬件开发入门:PCB 设计核心流程 + 基础元器件实战指南
vscode·后端·嵌入式硬件·架构·vim·智能硬件·pcb工艺
2501_9181269111 小时前
stm32做一个次声波检测器,需要哪些元件
stm32·单片机·嵌入式硬件·学习·个人开发
加斯顿工程师13 小时前
STM32F103C8T6驱动SRF05超声波测距传感器程序
stm32·单片机·嵌入式硬件
m0_5312371713 小时前
C语言-指针终阶
c语言·开发语言