文件共享,文件分享。
綜合項目,花了很久時間精細研究得到的成果,可以完美運行。
酒精測試儀以STC12C5A60S2單片機作為主控芯片,采用高精度MQ-3乙醇氣體傳感器對空氣中的乙醇濃度進行檢測,主控芯片對檢測信號進行A/D轉換和處理(不需要外接A/D轉換,芯片自帶該功能,),最后通過LCD1602液晶顯示屏顯示出來。酒精濃度測試儀具有醉酒閾值設定功能,可以根用戶需要設定修改醉酒閾值。當檢測到的酒精濃度超過設定閥值時會發出聲光警報。
硬件電路十分簡單,方便學習。
代碼原理圖數據手冊見附件。
51hei截圖20200422100422.png (105.98 KB, 下載次數: 63)
下載附件
2020-4-22 10:05 上傳
51hei截.png (29.61 KB, 下載次數: 53)
下載附件
2020-4-22 10:05 上傳
單片機源程序如下:
- #include "STC12C5A60S2.h"
- #include "intrins.h"
- #define uchar unsigned char
- #define uint unsigned int
-
- sbit RS = P2^7;
- sbit RW = P2^6;
- sbit EN = P2^5;
- sbit k0 = P3^3;
- sbit k1 = P3^4;
- sbit tm = P2^0;
- sbit in = P1^1;
- sbit led0= P1^5;
- sbit led1= P1^3;
- uchar shi=2,fen,miao;
- uchar num=0,n=0;
- uchar da1=0,add=0;
- double Data,c;
- char ac,bc,dc;
- char a[5]="";
- char b[4]="2.00";
- void key();
- void jian_ce();
- /************************************
- 延時函數
- *************************************/
- //一個機械周期
- void DelayUs2x(uchar t)
- {
- while(--t);
- }
- //自定義延時,單位微秒us
- void DelayMs(uchar t)
- {
- while(t--)
- {
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- /************************************
- 判忙函數
- *************************************/
- bit LCD_Check_Busy(void)
- {
- P0= 0xFF;
- RS=0;
- RW=1;
- EN=0;
- _nop_();
- EN=1;
- return (bit)(P0 & 0x80);
- }
- /************************************
- 寫指令函數
- *************************************/
- void LCD_Write_Com(uchar com)
- {
- while(LCD_Check_Busy()); //忙則等待
- RS=0;
- RW=0;
- EN=1;
- P0= com;
- _nop_();
- EN=0;
- }
- /************************************
- 寫數據函數
- *************************************/
- void LCD_Write_Data(uchar Data)
- {
- while(LCD_Check_Busy()); //忙則等待
- RS=1;
- RW=0;
- EN=1;
- P0= Data;
- _nop_();
- EN=0;
- }
- /************************************
- 清屏函數
- *************************************/
- void LCD_Clear(void)
- {
- LCD_Write_Com(0x01);
- DelayMs(5);
- }
- /************************************
- 寫字符串函數
- *************************************/
- void LCD_Write_String(uchar x,uchar y,uchar *s)
- {
- if (y == 0)
- {
- LCD_Write_Com(0x80 + x); //表示第一行
- }
- else
- {
- LCD_Write_Com(0xC0 + x); //表示第二行
- }
- while (*s)
- {
- LCD_Write_Data( *s);
- s ++;
- }
- }
- /************************************
- LCD初始化函數
- *************************************/
- void LCD_Init(void)
- {
- LCD_Write_Com(0x38);
- DelayMs(5);
- LCD_Write_Com(0x38);
- DelayMs(5);
- LCD_Write_Com(0x38);
- DelayMs(5);
- LCD_Write_Com(0x38);
- LCD_Write_Com(0x08);
- LCD_Write_Com(0x01);
- LCD_Write_Com(0x06);
- DelayMs(5);
- LCD_Write_Com(0x0C);
- }
-
- /************************************
- ADC函數
- *************************************/
- void InitADC() //初始AD寄存器
- {
- P1ASF=0X00; //P1.0腳作為模擬量輸入端
- ADC_RES=0X00; //清除高8位緩沖數據
- //ADC_CONTR為ADC控制寄存器
- ADC_CONTR=0xF0; //AD轉換控制寄存器
- _nop_(); //低三位 000 為P1.0口作為A/D輸入
- _nop_();
- _nop_(); //必須經過4個空操作延時后執行
- _nop_();
- ADC_CONTR=0xE8; //1110.1000 第三位置一
- }
- void timer0() interrupt 1 //定時器0
- {
- TH0=(65536-20000)/256;
- TL0=(65536-20000)%256;
- InitADC();
- }
- void adc_isr() interrupt 5 //ADC中斷
- {
- da1=ADC_RES; //獲取轉換結果
- c=((double)da1/256)*5; //取八位計算基準電壓
-
- a[0]=((int)c%10+0x30); //個位
- a[1]='.'; //小數點
- a[2]=((int)(c*10)%10+0x30); //十分位
- a[3]=((int)(c*100)%10+0x30); //百分位
- a[4]='\0';
- LCD_Write_String(8,0,a); //LCD顯示測量值
- ADC_CONTR&=0xEF; //標志位清零
- num++;
- if(num==252)num=0;
- }
- /************************************
- LCD顯示函數
- *************************************/
- void LCDXS()
- {
- LCD_Init();
- LCD_Clear();
- LCD_Write_String(0,0,"nong du:");
- LCD_Write_String(12,0,"mg/L");
- LCD_Write_String(0,1,"fen jie:");
- LCD_Write_String(8,1,b);
- LCD_Write_String(12,1,"mg/L");
- }
- /************************************
- 中斷初始化函數
- *************************************/
- void Init_zd()
- {
- TH0=(65536-20000)/256;
- TL0=(65536-20000)%256;
- IE=0xA2; //打開EA(總中斷)
- //EADC(ADC中斷允許位)
- //ET0(定時器0中斷允許位)
- TR0=1;
- }
- /************************************
- 按鍵控制
- *************************************/
- void key()
- {
- if(!k0)//按鍵選位
- {
- DelayMs(30);
- if(!k0)
- {add++;
- while(!k0);
- switch (add)
- {
- case 1: EA=0;n=1;DelayMs(5);
- LCD_Write_Com(0xc0+8);
- LCD_Write_Com(0x0f);
- break;
-
- case 2: LCD_Write_Com(0xc0+10);
- break;
-
- case 3: LCD_Write_Com(0xc0+11);
- break;
-
- case 4: LCD_Write_Com(0x0c);
- add=0;DelayMs(5);n=0;EA=1;
- break;
- } //switch(add)
- }
- }//if(!k0);
- if(add!=0)//按鍵加
- {
- switch (add)
- {
- case 1:if(!k1)
- {
- DelayMs(30);
- if(!k1)
- {shi++;
- while(!k1);
- if(shi==5)shi=0;
- }
- }
- LCD_Write_Com(0xc0+8);
- LCD_Write_Data(0x30+shi);
- LCD_Write_Com(0xc0+8);
- break;
- case 2:if(!k1)
- {
- DelayMs(30);
- if(!k1)
- {fen++;
- while(!k1);
- if(fen==10)fen=0;
- }
- }
- LCD_Write_Com(0xc0+10);
- LCD_Write_Data(0x30+fen);
- LCD_Write_Com(0xc0+10);
- break;
- case 3:if(!k1)
- {
- DelayMs(30);
- if(!k1)
- {miao++;
- while(!k1);
- if(miao==10)miao=0;
- }
- }
- LCD_Write_Com(0xc0+11);
- LCD_Write_Data(0x30+miao);
- LCD_Write_Com(0xc0+11);
- break;
- }//switch()
- }//if(add!=0)
- }//key()
- /************************************
- 主函數
- *************************************/
- void main()
- {
- LCDXS();
- DelayMs(255);
- Init_zd();
-
- while(1)
- {
- ac=(int)c%10;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
酒精測試儀—程序.rar
(43.71 KB, 下載次數: 57)
2020-4-22 09:55 上傳
點擊文件名下載附件
完整程序 下載積分: 黑幣 -5
AD原理圖.rar
(15.72 KB, 下載次數: 36)
2020-4-22 09:55 上傳
點擊文件名下載附件
原理圖 下載積分: 黑幣 -5
|