文章目錄
- 1 簡介
- 2 緒論
- 2.1 課題背景與目的
- 3 煙霧傳感器介紹
- 3.1 型別
- 3.2 MQ系列傳感器介紹
- 3.3 模塊介紹
- 4 系統設計
- 4.1 自診斷故障報警功能
- 4.2 煙霧濃度顯示
- 4.3 煙霧報警功能
- 4.4 防止報警器誤報功能
- 4.5 看門狗自檢單片機狀態功能
- 4.6 與上位機通訊功能
- 4.7 自動控制相關安全裝置的擴展功能
- 5 軟體設計
- 5.1 初始化流程
- 5.2 傳感器資料濾波
- 5.3 報警子程式
- 6 實作效果
- 7 部分相關代碼
- 8 最后
1 簡介
Hi,大家好,這里是丹成學長,今天向大家介紹一個 單片機專案
基于單片機的火災報警系統設計與實作
大家可用于 課程設計 或 畢業設計
技術解答、畢設幫助、開題指導
print("Q 746876041")
2 緒論
2.1 課題背景與目的
火災是指在時間或空間上失去控制的燃燒所造成的災害,在各種災害中,火災是最經常、最普遍地威脅公眾安全和社會發展的主要災害之一,人類能夠對火進行利用和控制,是文明進步的一個重要標志,火,給人類帶來文明進步、光明和溫暖,但是,失去控制的火,就會給人類造成巨大的災難,本系統是一個由單片機控制的火災煙霧濃度、溫度檢測系統,它將傳感器輸出地電壓信號進行A/D轉換、濾波、線性化,由單片機將電壓值轉換為氣體濃度和溫度送LED顯示,并判斷是否超過報警上限,若超過,則發出聲光報警,同時用戶可以自己設定報警上限和定時時間,使用戶可以根據實際情況方便的掌握安全狀況,本系統的設計能夠及時監測到系統故障和環境中有無火災,火災一旦發生將實作聲光報警,并采取有效措施控制火情的發展,將火災消滅在萌芽狀態,以確保人身財產安全,最大限度地減少損失,

目標
通過設計一個以 stm32單片機為核心外加 MQ-2 型半導體電阻式霧敏感器件的火災報警器可以實作聲光報警、 故障自診斷、 濃度顯示、 報警限設定、 延時報警及與上位機串口通信等功能,
是一種結構簡單、 性能穩定、 使用方便、 價格低廉、智能化的火災報警器, 具有一定的實用價值,
3 煙霧傳感器介紹
3.1 型別
煙霧傳感器種類繁多, 從檢測原理上可以分為三大類:
- (a) 利用物理化學性質的煙霧傳感器: 如半導體煙霧傳感器、 接觸燃燒煙霧傳感器等,
- (b) 利用物理性質的煙霧傳感器: 如熱導煙霧傳感器、 光干涉煙霧傳感器、 紅外傳感器等,
- ? 利用電化學性質的煙霧傳感器: 如電流型煙霧傳感器、 電勢型氣體傳感器等,
3.2 MQ系列傳感器介紹
MQ系列傳感器使用的敏感材料是活性很高的金屬訊訓物半導體,傳感器加熱后,在不同氣體濃度中電導率不同,使用簡單的電路就可以將電導率的變化轉換成與該氣體濃度相對應的信號輸出了,
3.3 模塊介紹
MQ-2傳感器對可燃氣、煙霧等氣體靈敏度高,基于MQ-2的煙霧傳感器模塊通過電路設計,提供了兩種輸出方式:
- 數字量輸出:通過板載電位器設定濃度閾值,當檢測到環境氣體濃度超過閾值時,通過數字引腳DO輸出低電平,
- 模擬量輸出:濃度越高,AO引腳輸出的電壓值越高,通過ADC采集的模擬值越高,

4 系統設計
報警器系統結構框圖如下圖所示,系統以單片機為核心,配合外圍電路共同完成:
- 信號采集
- 濃度顯示
- 時間顯示
- 狀態顯示
- 聲音及閃爍報警
- 按鍵輸入
- 故障自檢等功能,
報警器采用巡檢的作業方式,進行兩級報警值設定,并發出不同的光、聲信號,系統應采用高性能的單片機,要求作業穩定、測量精度高、通用性強、功耗低,保證報警器的精確性及可靠性,而且最好體積小,成本低有利于減少報警器的體積,降低報警器的成本

4.1 自診斷故障報警功能
當傳感器加熱絲或者電纜線發生斷線或者接觸不良的情況時, 報警器發出警報, 并且黃色指示燈閃爍, 提醒用戶檢查傳感器或者電路線接觸情況, 及時排除故障, 保證安全,
4.2 煙霧濃度顯示
通過液晶屏顯示可燃煙霧的濃度值, 并且可以切換到設定狀態, 通過鍵盤設定或者更改報警限值, 以便于用戶或檢測人員隨時觀測煙霧濃度及更改報警限,
4.3 煙霧報警功能
當煙霧濃度連續 20 秒取值都在報警限值之上, 蜂鳴器開始報警, 且聲音越來越急促,并且伴隨紅燈閃爍, 因為人對變化的信號更為敏感, 所以變化的聲音及燈光更容易引起用戶的注意,
4.4 防止報警器誤報功能
快速重復檢測及延時報警可以區別出是管道中可燃煙霧的泄漏, 還是由于打開閥門時的微量煙霧的散失,
4.5 看門狗自檢單片機狀態功能
呼叫單片機中的看門狗程式, 定時檢查單片機作業狀態, 一旦發現單片機出現死回圈狀態, 立即復位, 保證報警器作業正常,
4.6 與上位機通訊功能
可以實作與計算機串口通訊, 對報警器采取統一控制, 以及便于采集和處理資料, 也可以在計算機上更改報警限值等,
4.7 自動控制相關安全裝置的擴展功能
留有繼電器介面, 可以帶動排風扇或大功率蜂鳴器, 也可以控制管道電子閥門, 可在報警的同時自動啟動相關安全裝置,
5 軟體設計
主程式流程圖如圖所示,
首先要給傳感器預熱三分鐘, 因為 MQ-2 型半導體電阻式煙霧傳感器在不通電存放一段時間后, 再次通電時, 傳感器不能立即正常采集煙霧資訊,需要一段時間預熱, 程式初始化結束后, 系統進入監控狀態, 本論文的主程式設計先對傳感器預熱三分鐘, 預熱同時, 對傳感器加熱絲故障檢測, 采用軟體方式檢測傳感器加熱絲或電纜線是否斷線或者接觸不良,

5.1 初始化流程

5.2 傳感器資料濾波
在煙霧傳感器對煙霧濃度采樣時, 可能會遇到尖脈沖干擾的現象, 干擾通常只影響個別采樣點的資料, 此資料與其他采樣點的資料相差比較大,

5.3 報警子程式
當煙霧濃度超過報警設定值時, 報警器發出一種近似警笛的鳴叫聲, 對應通道的紅燈閃亮, 以提示操作人員采取安全對策或自動控制相關安全裝置, 從而保障生產安全, 避免火災和爆炸事故的發生,

6 實作效果


7 部分相關代碼
/************************************************
作者:丹成學長,Q746876041
************************************************/
#ifndef __SMOKE_H
#define __SMOKE_H
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
//正常狀態高電平,有煙霧低電平,單片機檢測到下降沿觸發中斷
//引腳定義
#define SMOKE_INT_GPIO_PORT GPIOB
#define SMOKE_INT_GPIO_CLK (RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO)
#define SMOKE_INT_GPIO_PIN GPIO_Pin_4
#define SMOKE_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOB
#define SMOKE_INT_EXTI_PINSOURCE GPIO_PinSource4
#define SMOKE_INT_EXTI_LINE EXTI_Line4 //中斷標志位
#define SMOKE_INT_EXTI_IRQ EXTI4_IRQn
#define SMOKE_IRQHandler EXTI4_IRQHandler
#define SMOKE_BIT GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_4)//讀取
void EXTI_SMOKE_Config(void);
#endif
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//功能:煙霧探測器模塊驅動
//作用:
//撰寫:MARK
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#include "smoke.h"
#include "stm32f10x_gpio.h"
static void SMOKE_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置NVIC為優先級組1 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* 配置中斷源*/
NVIC_InitStructure.NVIC_IRQChannel = SMOKE_INT_EXTI_IRQ;
/* 配置搶占優先級 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 配置子優先級 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中斷通道 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief 配置 IO為EXTI中斷口,并設定中斷優先級
* @param 無
* @retval 無
*/
void EXTI_SMOKE_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
/*開啟GPIO口的時鐘*/
RCC_APB2PeriphClockCmd(SMOKE_INT_GPIO_CLK,ENABLE);
/* 配置 NVIC 中斷*/
SMOKE_NVIC_Configuration();
/* 選擇用到的GPIO */
GPIO_InitStructure.GPIO_Pin = SMOKE_INT_GPIO_PIN;
/* 配置為浮空輸入 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(SMOKE_INT_GPIO_PORT, &GPIO_InitStructure);
/* 選擇EXTI的信號源 */
GPIO_EXTILineConfig(SMOKE_INT_EXTI_PORTSOURCE, SMOKE_INT_EXTI_PINSOURCE);
EXTI_InitStructure.EXTI_Line = SMOKE_INT_EXTI_LINE;
/* EXTI為中斷模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
/* 上升沿下降沿中斷觸發 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
/* 使能中斷 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
#include <stdio.h>
#include "stm32f10x.h"
#include "stm32f10x_it.h"
#include "./LED/LED.h"
#include "./usart3/usart3.h"
#include "./cJSON/cJSON.h"
#include "./millis/millis.h"
#include "./yun/yun.h"
#include "./systick/bsp_SysTick.h"
#include "./dht11/bsp_dht11.h"
#include "all_init.h"
#include "math_display.h"
#include "bsp_beep.h"
#include "./stepmotor/stepmotor.h"
#include "smoke.h"
volatile u8 aRxBuffer[1024]={0x00};
volatile u8 RxCounter=0;
volatile u8 ReceiveState=0;
unsigned long lastCheckInTime = 0; //記錄上次報到時間
unsigned long lastCheckStatusTime = 0;
unsigned long lastSayTime = 0;
unsigned long lastUpdateTime = 0; //記錄上次上傳資料時間
const unsigned long postingInterval = 40000; // 每隔40秒向服務器報到一次
const unsigned long statusInterval = 100000; // 資料上傳間隔時間10秒
const unsigned long updateInterval = 5000;
/*用CJSON處理接收到的資訊*/
int processMessage(char *msg) {
cJSON *jsonObj = cJSON_Parse(msg);
cJSON *method;
char *m;
//json字串決議失敗,直接退出
if(!jsonObj)
{
//uart1.printf("json string wrong!");
return 0;
}
method = cJSON_GetObjectItem(jsonObj, "M");
m = method->valuestring;
if(strncmp(m, "WELCOME", 7) == 0)
{
//防止設備在線狀態未消除,先登出
checkout();
//防止連續發送指令過快
Delay_ms(50);
checkin();
}
if(strncmp(m, "connected", 9) == 0)
{
checkout();
Delay_ms(50);
checkin();
}
//有設備或用戶登錄,發送歡迎資訊
if(strncmp(m, "login", 5) == 0)
{
char *from_id = cJSON_GetObjectItem(jsonObj, "ID")->valuestring;
char new_content[] = "Dear friend, welcome to BIGIOT !";
say(from_id, new_content);
}
//收到say指令,執行相應動作,并進行相應回復
if(strncmp(m, "say", 3) == 0 && millis() - lastSayTime > 10)
{
char *content = cJSON_GetObjectItem(jsonObj, "C")->valuestring;
char *from_id = cJSON_GetObjectItem(jsonObj, "ID")->valuestring;
lastSayTime = millis();
if(strncmp(content, "play", 4) == 0)
{
char new_content[] = "led1 played";
//do something here....
Led_On(LED1);//板載LED1亮
say(from_id, new_content);
}
else if(strncmp(content, "stop", 4) == 0)
{
char new_content[] = "led stoped";
//do something here....
Led_Off(LED1);//板載LED滅
say(from_id, new_content);
}
else if(strncmp(content, "up", 2) == 0)
{
char new_content[] = "led2 played";
//do something here....
Led_On(LED2);//板載LED2亮
say(from_id, new_content);
}
else if(strncmp(content, "plus", 4) == 0)
{
char new_content[] = "led2 stoped";
//do something here....
Led_Off(LED2);//板載LED2滅
say(from_id, new_content);
}
else if(strncmp(content, "pause", 5) == 0)
{
char new_content[] = "beep played";
macBEEP_ON();//打開蜂鳴器
say(from_id, new_content);
}
else if(strncmp(content, "right", 5) == 0)
{
char new_content[] = "beep stoped";
macBEEP_OFF();//關閉蜂鳴器
say(from_id, new_content);
}
else if(strncmp(content, "down", 4) == 0)
{
char new_content[] = "stepmotor played";
Motor_angle(-720,200); //步進電機順時針
say(from_id, new_content);
}
else if(strncmp(content, "forward", 7) == 0)
{
char new_content[] = "stepmotor stoped";
Motor_angle(720,200); //步進電機逆時針
say(from_id, new_content);
}
}
if(jsonObj)cJSON_Delete(jsonObj);
return 1;
}
int main(void)
{
u8 i = 0;
float wendu;
float shidu;
int yanwu;
int chuanglian;
DHT11_Data_TypeDef DHT11_Data;
all_init(); //打包的全部初始化函式
while (1)
{
//delay_ms(100);
if (millis() - lastCheckInTime > postingInterval || lastCheckInTime == 0)
{
checkin();
lastCheckInTime = millis();
}
if (millis() - lastCheckStatusTime > statusInterval)
{
check_status();
lastCheckStatusTime = millis();
}
if( DHT11_Read_TempAndHumidity ( & DHT11_Data ) == SUCCESS)//呼叫DHT11_Read_TempAndHumidity讀取溫濕度,
//若成功則輸出該資訊
{
display_num(DHT11_Data.temp_int,DHT11_Data.temp_deci,DHT11_Data.humi_int,DHT11_Data.humi_deci);
//螢屏顯示溫度和濕度值,封裝后的程式
if (millis() - lastUpdateTime > updateInterval)
{
wendu = (float)DHT11_Data.temp_int + (float)DHT11_Data.temp_deci/10.0;
shidu = (float)DHT11_Data.humi_int + (float)DHT11_Data.humi_deci/10.0;
if(SMOKE_BIT == Bit_RESET) //檢測到該引腳電平變低---有煙霧
{
yanwu = 1;
}
else if(SMOKE_BIT == Bit_SET) //檢測到該引腳電平變高---正常
{
yanwu = 0;
}
/*上傳三個介面的實時資料*/
update4(DEVICEID, INPUTID_1, wendu, INPUTID_2, shidu, INPUTID_3, yanwu, INPUTID_4, chuanglian);
lastUpdateTime = millis();
}
}
if(ReceiveState == 1)
{
ReceiveState = 0;
i = 0;
processMessage(aRxBuffer);
RxCounter = 0;
}
}
}
/*******************************************************************
篇幅有限,只展示部分代碼
作者:丹成學長,Q746876041
********************************************************************/
8 最后
技術解答、畢設幫助、開題指導
print("Q 746876041")

單片機畢設專案大全:
https://blog.csdn.net/huawei123444/article/details/119822845
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/336317.html
標籤:其他
