文章目錄
- 前言
- 一、學習目的
- 二、模塊介紹
- 三、代碼記錄
- 總結
前言
? ? ? ?這次記錄一下煙霧傳感器的學習,由于煙霧傳感器的資料比較雜,算法比較多,對我來說也比較難,所以我的代碼中算法部分是不太具有參考價值,但是也可以做到隨煙霧濃度的變化數(shù)值呈線性相關,以后再記錄完善。
一、學習目的
? ? ? ?我的學習目的是通過STM32的ADC功能,學會使用煙霧傳感器檢測氣體的濃度,并用串口助手將氣體濃度的數(shù)值實時打印出來。
二、模塊介紹
? ? ? ?我使用是MQ-2煙霧傳感器模塊,它屬于二氧化錫半導體氣敏材料,當它與煙霧接觸時,如果晶粒間界處的勢壘收到煙霧的調(diào)至面變化,就會引起表面導電率的變化。且當煙霧濃度增大時,導電率增大,電阻變小,電壓增大。所以就可以用電壓的變化表示煙霧的濃度。
? ? ? ? MQ-2的引腳也和大部分傳感器一樣是四個(VCC,GND,AO,DO),不一樣的是,我這次想通過ADC功能獲取電壓值,并表示為氣體濃度,而不是僅僅通過檢測是否達到閾值后來改變某一個IO口的電平(例如之前記錄的光敏傳感器和聲音傳感器,都是通過光照/聲音達到一個閾值后,改變某一個IO的電平,再通過讀取函數(shù)讀取這個IO口的電平,進而判斷是光明黑暗/有聲無聲)。所以煙霧傳感器給我的感覺是要遠復雜于一般傳感器的。
要注意的是,煙霧傳感器由于內(nèi)部有電阻絲作用,要先接通電源預熱20秒,測得結果才會穩(wěn)定。煙霧傳感器發(fā)熱屬于正?,F(xiàn)象,但是如果燙手就不正常了哈,那就建議立刻停止實驗。
接線方面:由于要實時獲取電壓,所以要使用的是AO引腳(檢測模擬信號的變化)
VCC--5V
GND--GND
AO--PA0(PA0具有ADC功能,實時輸出MQ-2的電壓信號)
三、代碼記錄
mq.h
#ifndef __MQ2_H
#define __MQ2_H
#include "stm32f10x.h"
void ADC_Pin_Init(void);
u16 ADC_Trans(void);
#endif
?mq.c
#include "mq2.h"
#include "delay.h"
#include "sys.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_adc.h"
void ADC_Pin_Init(void) //初始化PA0口作為ADC檢測端,并且初始化ADC通道1
{
GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef ADC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOA,&GPIO_InitStruct);
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; //多次連續(xù)變換
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
ADC_InitStruct.ADC_NbrOfChannel = 1;
ADC_InitStruct.ADC_ScanConvMode = DISABLE;
ADC_Init(ADC1,&ADC_InitStruct);
ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_239Cycles5);
ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
ADC_Cmd(ADC1,ENABLE);
}
u16 ADC_Trans(void) //數(shù)據(jù)處理,求電壓值的平均數(shù)
{
u16 adc_value = 0;
u8 i = 0;
for(i = 0; i < 50; i++)
{
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
adc_value = adc_value + ADC_GetConversionValue(ADC1);
}
return adc_value / 50;
}
? ? ? ?mq.c文件將ADC和煙霧傳感器寫在了一起,主要就是初始化PA0口和ADC的通道1,和一個數(shù)據(jù)處理函數(shù)。
要注意的是,初始化ADC1時,一定要將ADC_InitStruct.ADC_ContinuousConvMode設置為ENABLE??!即設置為多次連續(xù)變換模式,否則串口將只輸出第一次的值。
【數(shù)據(jù)處理時,本來需要通過while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) != SET)來檢測轉換是否結束,但我的代碼寫完后會始終卡死在這個循環(huán)里。這也是很遺憾的一個點,如果大家有什么好的方法可以告訴我一下。】
main.c
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "mq2.h"
int main(void)
{
u16 ad = 0;
delay_init();
uart_init(115200);
printf("初始化完成\r\n");
ADC_Pin_Init();
while(1)
{
ad = ADC_Trans();
// printf("電壓為:%f\r\n",3.3/4095*ad);
printf("煙霧濃度為:%.2f\r\n",ad * 99 / 4096.0);
delay_ms(1000);
}
}
串口通信的代碼就不作記錄了,代碼燒錄后,打開串口助手就可以看到結果了。
?總結文章來源:http://www.zghlxwxcb.cn/news/detail-486028.html
? ? ? ?代碼雖然看上去簡單,那其實也是因為我的算法比較拉跨,我也看了很多大佬的算法,確實比較高級,但是由于有的代碼并不完整,有的用的是STM32F4系列的芯片,我始終未能找到一個我能掌握的高級算法,以后有了進展再另作記錄。文章來源地址http://www.zghlxwxcb.cn/news/detail-486028.html
到了這里,關于STM32學習記錄——煙霧傳感器的使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!