• 方案介紹
    • 一、前言
    • 二、硬件選型
    • 三、設計思路
    • 四、項目模塊代碼
  • 附件下載
  • 相關推薦
申請入駐 產業(yè)圖譜

基于STC89C52單片機設計的防煤氣泄漏裝置

3小時前
138
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

更多詳細資料請聯系.docx

共1個文件

一、前言

煤氣泄漏是一個嚴重的安全隱患,可能導致火災、爆炸以及對人體健康的威脅。為了提高家庭和工業(yè)環(huán)境中煤氣泄漏的檢測和預防能力,設計了一種基于單片機的防煤氣泄漏裝置。

單片機選擇STC89C52作為主控芯片。為了檢測煤氣泄漏,采用了MQ4傳感器,能夠快速、準確地檢測煤氣濃度。通過采集MQ4傳感器的模擬信號,使用PCF8591模數轉換芯片將模擬信號轉換為數字信號。采用IIC接口的OLED顯示屏,將采集到的數據顯示出來,方便用戶獲取檢測結果。用戶可以通過兩個獨立按鍵設置煤氣泄漏的報警閾值,以適應不同環(huán)境的需求。

當檢測到煤氣泄漏超過設定的閾值時,裝置會觸發(fā)蜂鳴器進行報警,并同時打開換氣扇進行通風換氣,以迅速排除煤氣并降低安全風險。

這種基于單片機設計的防煤氣泄漏裝置具有以下優(yōu)點:高效可靠的煤氣泄漏檢測能力、靈活的報警閾值設置、直觀清晰的數據顯示以及及時的安全響應措施??梢詮V泛應用于家庭、工業(yè)和商業(yè)場所,提供有效的煤氣泄漏監(jiān)測和安全保護。

二、硬件選型

在設計基于單片機的防煤氣泄漏裝置時,硬件選型是非常關鍵的。以下是詳細介紹硬件選型的相關內容:

【1】主控芯片選擇:STC89C52 STC89C52是一款8051架構的單片機,具有豐富的接口資源、較高的性能和穩(wěn)定可靠的工作特性,廣泛應用于各種嵌入式系統(tǒng)中。具有8位數據總線、16位地址總線和4KB的內部存儲器。STC89C52具備多個通用I/O口、定時器/計數器、串口等功能,非常適合本項目需求。

【2】煤氣傳感器選擇:MQ4 MQ4傳感器是一種能夠檢測多種可燃氣體,如天然氣、甲烷等的傳感器。具有高靈敏度和快速響應的特點,能夠準確地檢測煤氣泄漏情況。MQ4傳感器的輸出為模擬信號,需要通過模數轉換器將其轉換為數字信號供主控芯片處理。

【3】模數轉換器選擇:PCF8591 PCF8591是一款集成了8位模數/數模轉換和4個模擬輸入通道的模數轉換器。采用IIC總線通訊接口,能夠將模擬信號轉換為數字信號,并通過IIC協議發(fā)送給主控芯片。本項目中,PCF8591用于采集MQ4傳感器輸出的模擬信號,并將其轉換為數字信號供STC89C52處理。

【4】顯示屏選擇:0.96寸OLED顯示屏(IIC接口) 本設計采用基于IIC接口的OLED顯示屏,具有高亮度、對比度和快速響應的特點。通過簡單的通訊方式,可以將煤氣濃度信息實時顯示在屏幕上。OLED顯示屏使用面積小、功耗低,在嵌入式系統(tǒng)中應用廣泛。

【5】按鍵選擇:獨立按鍵 本設計采用兩個獨立按鍵來設置報警的閥值。一個按鍵用于遞增閥值,另一個按鍵用于遞減閥值。獨立按鍵具有簡單可靠、使用方便等特點,適合本項目需求。

【6】報警裝置選擇:蜂鳴器和換氣扇 當檢測到煤氣泄漏超過設定的報警閥值時,蜂鳴器將發(fā)出警報,用于提醒周圍人員。同時,為了降低煤氣濃度,需要啟動換氣扇進行通風換氣。具體的報警和換氣扇電路可以根據實際需求設計。

三、設計思路

軟件設計思路如下:

【1】初始化:在程序開始時,進行主控芯片STC89C52的初始化設置,包括引腳配置、定時器設置等。同時,初始化PCF8591和OLED顯示屏,確保它們可以正常工作。

【2】傳感器檢測:通過MQ4傳感器檢測煤氣是否泄漏。將MQ4傳感器與STC89C52的模擬輸入引腳連接,通過讀取該引腳的模擬電壓值,獲取煤氣濃度數據。

【3】數據采集與處理:使用PCF8591模數轉換芯片,將MQ4傳感器的模擬輸出信號轉換為數字信號,并通過STC89C52的IIC接口與PCF8591進行通信,獲取轉換后的數字數據。

【4】數據顯示:將采集到的煤氣濃度數據通過IIC接口的OLED顯示屏進行顯示。使用STC89C52的IIC通信功能,將數據發(fā)送給OLED顯示屏,通過顯示屏將數據以可讀的方式展示給用戶。

【5】閾值設置:通過兩個獨立按鍵實現報警閾值的設置。將按鍵與STC89C52的GPIO引腳連接,通過讀取按鍵狀態(tài)來判斷用戶是否進行閾值設置操作。當按鍵按下時,進入設置模式,用戶可以通過按鍵的不同組合來調整報警閾值,并將設置的值保存在相應的變量中。

【6】報警與通風控制:根據當前采集到的煤氣濃度數據和用戶設置的報警閾值進行比較。如果煤氣濃度超過設定的閾值,觸發(fā)蜂鳴器進行報警,并控制換氣扇打開進行通風換氣。反之,當煤氣濃度低于或等于設定的閾值時,停止報警并關閉換氣扇。

【7】循環(huán)監(jiān)測:使用主循環(huán)結構,不斷進行煤氣泄漏檢測、數據采集、數據顯示和閾值比較等操作,以實現持續(xù)的監(jiān)測和反饋。

四、項目模塊代碼

4.1 PCF8591采集代碼

下面是使用STC89C52單片機通過PCF8591讀取MQ4傳感器的ADC數據的代碼。使用IIC總線進行PCF8591之間的通信,使用了自定義的IIC總線函數。通過readADC()函數實現了讀取MQ4傳感器模擬量的ADC轉換結果。

#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int

sbit SDA = P2^0;    // IIC總線數據線
sbit SCL = P2^1;    // IIC總線時鐘線

sbit MQ4_DOUT = P3^0;   // MQ4傳感器數字輸出引腳
sbit MQ4_AIN = P3^1;    // MQ4傳感器模擬輸入引腳

sfr IAP_DATA = 0xe2;    // 定義IAP_DATA寄存器
sfr IAP_ADDRH = 0xe3;   // 定義IAP_ADDRH寄存器
sfr IAP_ADDRL = 0xe4;   // 定義IAP_ADDRL寄存器
sfr IAP_CMD = 0xe5;     // 定義IAP_CMD寄存器
sfr IAP_TRIG = 0xe6;    // 定義IAP_TRIG寄存器
sfr IAP_CONTR = 0xe7;   // 定義IAP_CONTR寄存器

// 函數聲明
void delay(uint ms);
void startIIC();
void stopIIC();
void sendByte(uchar dat);
uchar receiveByte();
void writeDAC(uchar dat);
uchar readADC();

void main() {
    uchar mq4Value;
    
    while (1) {
        mq4Value = readADC();  // 讀取ADC轉換結果
        
        // 處理mq4Value值,進行相應操作
        
        delay(100);  // 延時一段時間
    }
}

// 延時函數
void delay(uint ms) {
    uint i, j;
    for(i = ms; i > 0; i--) {
        for(j = 110; j > 0; j--);
    }
}

// IIC總線起始信號
void startIIC() {
    SDA = 1;
    _nop_();
    SCL = 1;
    _nop_();
    SDA = 0;
    _nop_();
    SCL = 0;
    _nop_();
}

// IIC總線停止信號
void stopIIC() {
    SDA = 0;
    _nop_();
    SCL = 1;
    _nop_();
    SDA = 1;
    _nop_();
}

// 發(fā)送一個字節(jié)的數據
void sendByte(uchar dat) {
    uchar i;
    for (i = 0; i < 8; i++) {
        SDA = dat >> 7;
        _nop_();
        SCL = 1;
        _nop_();
        SCL = 0;
        _nop_();
        dat <<= 1;
    }
    SDA = 1;
    _nop_();
    SCL = 1;
    _nop_();
    SCL = 0;
    _nop_();
}

// 接收一個字節(jié)的數據
uchar receiveByte() {
    uchar i, dat = 0;
    SDA = 1;
    for (i = 0; i < 8; i++) {
        dat <<= 1;
        SCL = 1;
        _nop_();
        dat |= SDA;
        SCL = 0;
        _nop_();
    }
    return dat;
}

// 寫入DAC數值
void writeDAC(uchar dat) {
    startIIC();
    sendByte(0x90);  // 地址和寫命令
    receiveByte();   // 接收應答
    sendByte(0x40);  // DAC通道A,并寫入數據
    receiveByte();   // 接收應答
    sendByte(dat);   // DAC數據
    receiveByte();   // 接收應答
    stopIIC();
}

// 讀取ADC轉換結果
uchar readADC() {
    uchar adcValue;
    
    startIIC();
    sendByte(0x91);   // 地址和讀命令
    receiveByte();    // 接收應答
    adcValue = receiveByte();  // 讀取ADC數據
    stopIIC();
    
    return adcValue;
}

4.2 OLED顯示屏代碼

以下是通過STC89C52控制IIC接口的OLED顯示屏顯示ADC數據實現代碼。

#include <reg51.h>

#define SCL P1_0   // IIC時鐘線
#define SDA P1_1   // IIC數據線

#define OLED_ADDR 0x78   // OLED顯示屏的IIC地址

// OLED顯示屏初始化函數
void OLED_Init() {
    // 初始化OLED顯示屏
    // ...

    // 發(fā)送初始化命令到OLED顯示屏
    // ...
}

// IIC總線開始信號
void IIC_Start() {
    SDA = 1;
    SCL = 1;
    SDA = 0;
    SCL = 0;
}

// IIC總線停止信號
void IIC_Stop() {
    SDA = 0;
    SCL = 1;
    SDA = 1;
}

// IIC總線發(fā)送一個字節(jié)的數據
void IIC_WriteByte(unsigned char dat) {
    unsigned char i;
    for (i = 0; i < 8; i++) {
        SCL = 0;
        if (dat & 0x80)
            SDA = 1;
        else
            SDA = 0;
        SCL = 1;
        dat <<= 1;
    }
    SCL = 0;
    SDA = 1;
    SCL = 1;
}

// 設置OLED顯示屏光標位置
void OLED_SetPos(unsigned char x, unsigned char y) {
    IIC_Start();
    IIC_WriteByte(OLED_ADDR);
    IIC_WriteByte(0xb0 + y);
    IIC_WriteByte(((x & 0xf0) >> 4) | 0x10);
    IIC_WriteByte((x & 0x0f) | 0x01);
    IIC_Stop();
}

// 在OLED顯示屏上顯示一個字符
void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch) {
    unsigned char c = 0, i = 0;
    c = ch - ' ';   // 獲取字符在字庫中的偏移量
    if (x > 128 - 8 || y > 64 - 16)
        return;   // 超出屏幕范圍,退出函數
    OLED_SetPos(x, y);
    for (i = 0; i < 8; i++) {
        IIC_Start();
        IIC_WriteByte(OLED_ADDR);
        IIC_WriteByte(0x40);
        IIC_WriteByte(*(OLED_CharSet + c * 16 + i));
        IIC_Stop();
        x++;
    }
}

// 在OLED顯示屏上顯示字符串
void OLED_ShowString(unsigned char x, unsigned char y, unsigned char *str) {
    while (*str) {
        OLED_ShowChar(x, y, *str);
        x += 8;
        str++;
    }
}

// ADC模擬數值轉換為字符串
void ADC_ToString(unsigned int adcValue, unsigned char *str) {
    unsigned char i, j;
    unsigned int temp;

    temp = adcValue;
    for (i = 0; i < 4; i++) {
        str[i] = temp % 10 + '0';
        temp /= 10;
    }

    // 反轉字符串
    i = 0;
    j = 3;
    while (i < j) {
        temp = str[i];
        str[i] = str[j];
        str[j] = temp;
        i++;
        j--;
    }
    str[4] = '?';   // 字符串結束符
}

// 主函數
void main() {
    unsigned int adcValue = 0;
    unsigned char str[5];

    // 初始化OLED顯示屏
    OLED_Init();

    while (1) {
        // 讀取ADC數據
        adcValue = ADC_Read();   // 假設使用的函數為ADC_Read(),用于讀取ADC數據

        // 將ADC數據轉換為字符串
        ADC_ToString(adcValue, str);

        // 在OLED顯示屏上顯示ADC數據
        OLED_ShowString(0, 0, "ADC Value:");
        OLED_ShowString(0, 2, str);
    }
}

4.3 主代碼邏輯

#include <reg51.h>

#define SCL P1_0    // IIC時鐘線
#define SDA P1_1    // IIC數據線

#define OLED_ADDR 0x78    // OLED顯示屏的IIC地址
#define MQ4_PIN P2      // MQ4傳感器連接的引腳

sbit Buzzer = P3^0;    // 蜂鳴器控制引腳
sbit VentilationFan = P3^1;    // 換氣扇控制引腳

// 全局變量
unsigned int alarmThreshold = 100;    // 報警閾值,默認為100
unsigned int adcValue = 0;    // 保存ADC采集到的數值

// IIC總線開始信號
void IIC_Start() {
    SDA = 1;
    SCL = 1;
    SDA = 0;
    SCL = 0;
}

// IIC總線停止信號
void IIC_Stop() {
    SDA = 0;
    SCL = 1;
    SDA = 1;
}

// IIC總線發(fā)送一個字節(jié)的數據
void IIC_WriteByte(unsigned char dat) {
    unsigned char i;
    for (i = 0; i < 8; i++) {
        SCL = 0;
        if (dat & 0x80)
            SDA = 1;
        else
            SDA = 0;
        SCL = 1;
        dat <<= 1;
    }
    SCL = 0;
    SDA = 1;
    SCL = 1;
}

// 設置OLED顯示屏光標位置
void OLED_SetPos(unsigned char x, unsigned char y) {
    IIC_Start();
    IIC_WriteByte(OLED_ADDR);
    IIC_WriteByte(0xb0 + y);
    IIC_WriteByte(((x & 0xf0) >> 4) | 0x10);
    IIC_WriteByte((x & 0x0f) | 0x01);
    IIC_Stop();
}

// 在OLED顯示屏上顯示一個字符
void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch) {
    unsigned char c = 0, i = 0;
    c = ch - ' ';    // 獲取字符在字庫中的偏移量
    if (x > 128 - 8 || y > 64 - 16)
        return;    // 超出屏幕范圍,退出函數
    OLED_SetPos(x, y);
    for (i = 0; i < 8; i++) {
        IIC_Start();
        IIC_WriteByte(OLED_ADDR);
        IIC_WriteByte(0x40);
        IIC_WriteByte(*(OLED_CharSet + c * 16 + i));
        IIC_Stop();
        x++;
    }
}

// 在OLED顯示屏上顯示字符串
void OLED_ShowString(unsigned char x, unsigned char y, unsigned char *str) {
    while (*str) {
        OLED_ShowChar(x, y, *str);
        x += 8;
        str++;
    }
}

// ADC轉換函數
unsigned int ADC_Convert(unsigned char channel) {
    ADC_CONTR = ADC_POWER | ADC_START | channel | ADC_SPEED;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & ADC_FLAG))
        ;
    ADC_CONTR &= ~ADC_FLAG;
    return (ADC_RES * 256 + ADC_RESL);
}

// ADC模擬數值轉換為字符串
void ADC_ToString(unsigned int adcValue, unsigned char *str) {
    unsigned char i, j;
    unsigned int temp;

    temp = adcValue;
    for (i = 0; i < 4; i++) {
        str[i] = temp % 10 + '0';
        temp /= 10;
    }

    // 反轉字符串
    i = 0;
    j = 3;
    while (i < j) {
        temp = str[i];
        str[i] = str[j];
        str[j] = temp;
        i++;
        j--;
    }
    str[4] = '?';    // 字符串結束符
}

 主函數
void main() {
    unsigned char str[5];

    // 初始化OLED顯示屏
    OLED_Init();

    // 設置初始報警閾值
    SetAlarmThreshold();

    while (1) {
        // 讀取MQ4傳感器的ADC數值
        adcValue = ADC_Convert(0);    // 假設MQ4傳感器連接到ADC的通道0

        // 將ADC數值轉換為字符串
        ADC_ToString(adcValue, str);

        // 在OLED顯示屏上顯示ADC數值
        OLED_ShowString(0, 0, "Gas Level:");
        OLED_ShowString(0, 2, str);

        // 判斷是否觸發(fā)報警
        if (adcValue > alarmThreshold) {
            // 觸發(fā)報警
            ActivateAlarm();
        } else {
            // 取消報警
            DeactivateAlarm();
        }

        // 檢測是否按下設置閾值的按鍵
        if (IsThresholdButtonPressed()) {
            // 設置報警閾值
            SetAlarmThreshold();
        }

        // 檢測是否按下通風換氣的按鍵
        if (IsVentilationButtonPressed()) {
            // 控制通風換氣
            ControlVentilation();
        }
    }
}
  • 更多詳細資料請聯系.docx
    下載

相關推薦