標(biāo)題: 單片機(jī)酒精濃度檢測(cè)儀設(shè)計(jì)資料 [打印本頁(yè)]
作者: Griry 時(shí)間: 2018-5-27 16:38
標(biāo)題: 單片機(jī)酒精濃度檢測(cè)儀設(shè)計(jì)資料
本設(shè)計(jì)基于STC12C5A16AD單片機(jī)設(shè)計(jì)的酒精氣體濃度探測(cè)儀,可用來(lái)檢測(cè)酒精氣體濃度,酒精氣體濃度測(cè)試儀在生產(chǎn)生活中有重要的應(yīng)用,比如,在一些環(huán)境要求嚴(yán)格的生產(chǎn)車(chē)間,用這種酒精濃度探測(cè)儀,可隨時(shí)檢測(cè)車(chē)間內(nèi)的酒精氣體濃度,當(dāng)酒精氣體濃度高于允許限定值時(shí),發(fā)出警報(bào),提醒人們及時(shí)通風(fēng)換氣,做到安全生產(chǎn),此酒精測(cè)試儀經(jīng)過(guò)再一步的改進(jìn)可以使用到酒后駕駛測(cè)試上面去,利用該測(cè)試儀來(lái)告誡駕駛員請(qǐng)勿酒后駕駛。
在這次的設(shè)計(jì)中,利用了MQ-3型酒精的傳感器通過(guò)對(duì)空氣中的酒精濃度測(cè)試轉(zhuǎn)換成0~5V的模擬量電壓進(jìn)行輸出,把這個(gè)0~5V的電壓傳送到STC12C5A16AD內(nèi)部自帶的A/D轉(zhuǎn)換模塊中去,通過(guò)模擬量模塊的轉(zhuǎn)換輸出一個(gè)8位0~255的數(shù)據(jù)給單片機(jī)的P1口,再通過(guò)單片機(jī)進(jìn)行一些軟件程序的處理顯示在LCD的液晶上面。
- #include "STC12c5A.h"
- #include "1602.h"
- #include "2402.h"
- #define uchar unsigned char
- #define uint unsigned int
- //聲明常量
- #define ALCH 80 //醉駕標(biāo)準(zhǔn)80mg/L
- //K_MG_MV和K_ZERO為傳感器校準(zhǔn)系數(shù),要根據(jù)每個(gè)MQ-3模塊校準(zhǔn)
- #define K_MG_MV 160/66 //傳感器靈敏度系數(shù),每毫克/L對(duì)應(yīng)的10毫伏數(shù)
- #define K_ZERO 0 //傳感器零點(diǎn)漂移,約130mV
- //定義按鍵
- sbit Key_Up = P3^6;
- sbit Key_Down = P3^7;
- //定義LED報(bào)警燈
- sbit Led_Warn1 = P3^4;
- sbit Led_Warn2 = P3^5;
- //定義乙醇傳感器TTL電平輸出引腳
- sbit DOUT = P1^4;
- //定義標(biāo)識(shí)
- volatile bit FlagStartAL = 0; //開(kāi)始轉(zhuǎn)換標(biāo)志
- volatile bit FlagKeyPress = 0; //有鍵彈起標(biāo)志
- //全局變量定義
- uchar Threshold; //酒精濃度上限報(bào)警值
- uint ALCounter; //酒精轉(zhuǎn)換計(jì)時(shí)器
- uint ALValue; //酒精測(cè)量值
- float ALtemp; //計(jì)算臨時(shí)變量
- uint keyvalue, keyUp, keyDown; //鍵值
- char * pSave; //EEPROM存盤(pán)用指針
- //函數(shù)聲明
- void Data_Init();
- void Timer0_Init();
- void Port_Init();
- void ADC_Init();
- uchar GetADVal();
- void KeyProcess(uint );
- //數(shù)據(jù)初始化
- void Data_Init()
- {
- ALCounter = 0;
- ALValue = 0;
- Led_Warn1 = 1;
- Led_Warn2 = 2;
- keyvalue = 0;
- keyUp = 1;
- keyDown = 1;
- }
- //定時(shí)器0初始化,中斷時(shí)間約2毫秒
- //計(jì)算:晶振11.0592MHz,定時(shí)器時(shí)鐘11059200/12=921600,每毫秒922個(gè)脈沖
- // 16位定時(shí)器初值65536-1844=63692=0xf8cc
- void Timer0_Init()
- {
- ET0 = 1; //允許定時(shí)器0中斷
- TMOD = 1; //定時(shí)器工作方式選擇
- TL0 = 0xcc; //
- TH0 = 0xf8; //定時(shí)器賦予初值,大約為2毫秒中斷1次
- TR0 = 1; //啟動(dòng)定時(shí)器
- }
- //定時(shí)器0中斷
- void Timer0_ISR (void) interrupt 1 using 0
- {
- TL0 = 0xcc;
- TH0 = 0xf8; //定時(shí)器賦予初值
- //每1秒鐘啟動(dòng)一次AD轉(zhuǎn)換
- ALCounter ++;
- if (ALCounter >= 500)
- {
- FlagStartAL = 1;
- ALCounter = 0;
- }
- }
- void Port_Init() //設(shè)定AD啟動(dòng);
- {
- P1M0 = 0x80; //10000000,P1.7作為AD輸入;
- P1M1 = 0x80; //
- }
- void ADC_Init()
- {
- uint i;
- P1ASF = 0x80; //設(shè)P1.7為AD輸入
- ADC_RES = 0; //清先前的結(jié)果
- ADC_CONTR|=0x80; //POWER=1,打開(kāi)ADC電源
- for(i=5000;i>0;i--) ; //延時(shí)
- ADC_CONTR = ADC_CONTR&0xE0; //1110,0000 清ADC_FLAG,ADC_START位和低3位
- ADC_CONTR = ADC_CONTR&0xf8|0x07; //設(shè)置當(dāng)前通道號(hào)為P1.7
- for(i=2500;i>0;i--) ; //延時(shí)
- }
- //進(jìn)行AD轉(zhuǎn)換,得到當(dāng)前酒精值
- uchar GetADVal()
- {
- uint i;
- ADC_CONTR&=0xf7;
- for(i=250;i>0;i--); //待輸入電壓穩(wěn)定后開(kāi)始轉(zhuǎn)換
- //ADC_RES = 0;
- ADC_CONTR |= 0x08; //ADC_Start=1, 啟動(dòng)轉(zhuǎn)換
- while((ADC_CONTR&0x10)==0); //等待轉(zhuǎn)換結(jié)束ADC_FLAG=1
- ADC_CONTR&=0xe7; //清ADC_FLAG和ADC_START位,停止轉(zhuǎn)換
- return ADC_RES;
- }
- //存入設(shè)定值
- void Save_Setting()
- {
- pSave = (char *)&Threshold; //地址低位對(duì)應(yīng)低8位,高位對(duì)應(yīng)高8位
- wrteeprom(0, *pSave); //存醉酒閾值低8位
- DELAY(300);
- pSave ++;
- wrteeprom(1, *pSave); //存醉酒閾值高8位
- DELAY(300);
- }
- //載入設(shè)定值
- void Load_Setting()
- {
- pSave = (char *)&Threshold;
- *pSave++ = rdeeprom(0);
- *pSave = rdeeprom(1);
- if ((Threshold>=255)||(Threshold<0)) Threshold = 80;
- }
- //按鍵處理程序,參數(shù)為鍵值,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(); //數(shù)據(jù)初始化
- Timer0_Init(); //定時(shí)器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 ");
- //延時(shí)
- 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");
- //載入設(shè)定值
- Load_Setting();
- L1602_int(2,9,Threshold);
- while(1)
- {
- //如果FlagStartAL標(biāo)志置位,則進(jìn)行AD轉(zhuǎn)換
- if (FlagStartAL == 1)
- {
- //酒精濃度換算,50mg/L=62.5ppm,傳感器靈敏度應(yīng)事先校準(zhǔn)
- ALValue = 500 * GetADVal() / 256; //8位ADC,首先得到電壓值,單位10毫伏
- ALValue = ALValue - K_ZERO; //首先減去零點(diǎn)漂移,一般是130mV
- if (ALValue < 0) ALValue = 0;
- ALValue = ALValue * K_MG_MV; //將mV轉(zhuǎn)變成mg/L,K_MG_MV系數(shù)需要校準(zhǔn)
- L1602_int(1,9,ALValue);
- if (ALValue > Threshold) Led_Warn1 = 0; //超過(guò)閾值,則 Led_Warn1燈報(bào)警,否則報(bào)警燈滅。
- else Led_Warn1 = 1;
- FlagStartAL = 0;
- }
- //查詢(xún)乙醇傳感器TTL電平,該指示燈為傳感器模塊報(bào)警
- if (DOUT == 0) Led_Warn2 = 0;
- else Led_Warn2 = 1;
- //鍵盤(pán)查詢(xún),在彈起時(shí)響應(yīng)
- 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);
- }
- }
復(fù)制代碼
作者: ADCFFFF 時(shí)間: 2023-12-7 01:34
1602.h
作者: 君子之膠淡如水 時(shí)間: 2024-5-18 20:07
ALValue = 500 * GetADVal() / 256; //8位ADC,首先得到電壓值,單位10毫伏
這個(gè)公式是什么意思是
| 歡迎光臨 (http://m.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |