本設計基于STC12C5A16AD單片機設計的酒精氣體濃度探測儀,可用來檢測酒精氣體濃度,酒精氣體濃度測試儀在生產生活中有重要的應用,比如,在一些環境要求嚴格的生產車間,用這種酒精濃度探測儀,可隨時檢測車間內的酒精氣體濃度,當酒精氣體濃度高于允許限定值時,發出警報,提醒人們及時通風換氣,做到安全生產,此酒精測試儀經過再一步的改進可以使用到酒后駕駛測試上面去,利用該測試儀來告誡駕駛員請勿酒后駕駛。 在這次的設計中,利用了MQ-3型酒精的傳感器通過對空氣中的酒精濃度測試轉換成0~5V的模擬量電壓進行輸出,把這個0~5V的電壓傳送到STC12C5A16AD內部自帶的A/D轉換模塊中去,通過模擬量模塊的轉換輸出一個8位0~255的數據給單片機的P1口,再通過單片機進行一些軟件程序的處理顯示在LCD的液晶上面。
- #include "STC12c5A.h"
- #include "1602.h"
- #include "2402.h"
- #define uchar unsigned char
- #define uint unsigned int
- //聲明常量
- #define ALCH 80 //醉駕標準80mg/L
- //K_MG_MV和K_ZERO為傳感器校準系數,要根據每個MQ-3模塊校準
- #define K_MG_MV 160/66 //傳感器靈敏度系數,每毫克/L對應的10毫伏數
- #define K_ZERO 0 //傳感器零點漂移,約130mV
- //定義按鍵
- sbit Key_Up = P3^6;
- sbit Key_Down = P3^7;
- //定義LED報警燈
- sbit Led_Warn1 = P3^4;
- sbit Led_Warn2 = P3^5;
- //定義乙醇傳感器TTL電平輸出引腳
- sbit DOUT = P1^4;
- //定義標識
- volatile bit FlagStartAL = 0; //開始轉換標志
- volatile bit FlagKeyPress = 0; //有鍵彈起標志
- //全局變量定義
- uchar Threshold; //酒精濃度上限報警值
- uint ALCounter; //酒精轉換計時器
- uint ALValue; //酒精測量值
- float ALtemp; //計算臨時變量
- uint keyvalue, keyUp, keyDown; //鍵值
- char * pSave; //EEPROM存盤用指針
- //函數聲明
- void Data_Init();
- void Timer0_Init();
- void Port_Init();
- void ADC_Init();
- uchar GetADVal();
- void KeyProcess(uint );
- //數據初始化
- void Data_Init()
- {
- ALCounter = 0;
- ALValue = 0;
- Led_Warn1 = 1;
- Led_Warn2 = 2;
- keyvalue = 0;
- keyUp = 1;
- keyDown = 1;
- }
- //定時器0初始化,中斷時間約2毫秒
- //計算:晶振11.0592MHz,定時器時鐘11059200/12=921600,每毫秒922個脈沖
- // 16位定時器初值65536-1844=63692=0xf8cc
- void Timer0_Init()
- {
- ET0 = 1; //允許定時器0中斷
- TMOD = 1; //定時器工作方式選擇
- TL0 = 0xcc; //
- TH0 = 0xf8; //定時器賦予初值,大約為2毫秒中斷1次
- TR0 = 1; //啟動定時器
- }
- //定時器0中斷
- void Timer0_ISR (void) interrupt 1 using 0
- {
- TL0 = 0xcc;
- TH0 = 0xf8; //定時器賦予初值
- //每1秒鐘啟動一次AD轉換
- ALCounter ++;
- if (ALCounter >= 500)
- {
- FlagStartAL = 1;
- ALCounter = 0;
- }
- }
- void Port_Init() //設定AD啟動;
- {
- P1M0 = 0x80; //10000000,P1.7作為AD輸入;
- P1M1 = 0x80; //
- }
- void ADC_Init()
- {
- uint i;
- P1ASF = 0x80; //設P1.7為AD輸入
- ADC_RES = 0; //清先前的結果
- ADC_CONTR|=0x80; //POWER=1,打開ADC電源
- for(i=5000;i>0;i--) ; //延時
- ADC_CONTR = ADC_CONTR&0xE0; //1110,0000 清ADC_FLAG,ADC_START位和低3位
- ADC_CONTR = ADC_CONTR&0xf8|0x07; //設置當前通道號為P1.7
- for(i=2500;i>0;i--) ; //延時
- }
- //進行AD轉換,得到當前酒精值
- uchar GetADVal()
- {
- uint i;
- ADC_CONTR&=0xf7;
- for(i=250;i>0;i--); //待輸入電壓穩定后開始轉換
- //ADC_RES = 0;
- ADC_CONTR |= 0x08; //ADC_Start=1, 啟動轉換
- while((ADC_CONTR&0x10)==0); //等待轉換結束ADC_FLAG=1
- ADC_CONTR&=0xe7; //清ADC_FLAG和ADC_START位,停止轉換
- return ADC_RES;
- }
- //存入設定值
- void Save_Setting()
- {
- pSave = (char *)&Threshold; //地址低位對應低8位,高位對應高8位
- wrteeprom(0, *pSave); //存醉酒閾值低8位
- DELAY(300);
- pSave ++;
- wrteeprom(1, *pSave); //存醉酒閾值高8位
- DELAY(300);
- }
- //載入設定值
- void Load_Setting()
- {
- pSave = (char *)&Threshold;
- *pSave++ = rdeeprom(0);
- *pSave = rdeeprom(1);
- if ((Threshold>=255)||(Threshold<0)) Threshold = 80;
- }
- //按鍵處理程序,參數為鍵值,1為Up鍵,2為Down鍵
- void KeyProcess(uint num)
- {
- switch (num)
- {
- case 1:
- if (Threshold<255) Threshold++;
- break;
- case 2:
- if (Threshold>1) Threshold--;
- break;
- default:
- break;
- }
- L1602_int(2,9,Threshold);
- Save_Setting();
- }
- void main()
- {
- uint i,j;
- EA = 0;
- Data_Init(); //數據初始化
- Timer0_Init(); //定時器0初始化
- Port_Init(); //端口初始化
- ADC_Init(); //ADC初始化
- EA = 1;
- L1602_init();
- L1602_string(1,1,"Welcome to ALCT! ");
- L1602_string(2,1,"Lijiang Nbjsxy ");
- //L1602_string(2,1,"Designed by AAA ");
- //延時
- for (i=0;i<1000;i++)
- for (j=0;j<1000;j++)
- {;}
- //清屏
- L1602_string(1,1," ");
- L1602_string(2,1," ");
- L1602_string(1,1,"Alcohol: mg/L");
- L1602_string(2,1,"Setting: mg/L");
- //載入設定值
- Load_Setting();
- L1602_int(2,9,Threshold);
- while(1)
- {
- //如果FlagStartAL標志置位,則進行AD轉換
- if (FlagStartAL == 1)
- {
- //酒精濃度換算,50mg/L=62.5ppm,傳感器靈敏度應事先校準
- ALValue = 500 * GetADVal() / 256; //8位ADC,首先得到電壓值,單位10毫伏
- ALValue = ALValue - K_ZERO; //首先減去零點漂移,一般是130mV
- if (ALValue < 0) ALValue = 0;
- ALValue = ALValue * K_MG_MV; //將mV轉變成mg/L,K_MG_MV系數需要校準
- L1602_int(1,9,ALValue);
- if (ALValue > Threshold) Led_Warn1 = 0; //超過閾值,則 Led_Warn1燈報警,否則報警燈滅。
- else Led_Warn1 = 1;
- FlagStartAL = 0;
- }
- //查詢乙醇傳感器TTL電平,該指示燈為傳感器模塊報警
- if (DOUT == 0) Led_Warn2 = 0;
- else Led_Warn2 = 1;
- //鍵盤查詢,在彈起時響應
- if ((Key_Up)&&(keyUp==0)) {FlagKeyPress = 1; keyvalue = 1;}
- else if ((Key_Down)&&(keyDown==0)) {FlagKeyPress = 1; keyvalue = 2;}
- if (FlagKeyPress == 1)
- {
- KeyProcess(keyvalue);
- FlagKeyPress = 0;
- }
- if (!Key_Up) keyUp = 0;
- else keyUp = 1;
- if (!Key_Down) keyDown = 0;
- else keyDown = 1;
- DELAY(100);
- }
- }
復制代碼
|