1. 程式人生 > >微控制器之煙霧報警器

微控制器之煙霧報警器

微控制器之煙霧報警器(MQ-2)

轉載https://blog.csdn.net/qq_21792169/article/details/51236071

適用於初學者。高手不要忘下看了

要求:液晶屏顯示.四個按鍵分別控制選擇設定值位數,加一,減一。報警功能開關鍵

lcd.c檔案

#include<reg51.h>
#define LCD1602_4PINS
#define LCD1602_DATAPINS P0
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;


#define uchar unsigned char
#define uint unsigned int


void Lcd1602_Delay1ms(uint c)   //誤差 0us
{
    uchar a,b;
for (; c>0; c--)
{
for (b=199;b>0;b--)
{
  for(a=1;a>0;a--);
}      
}
    
}


void LcdWriteCom(uchar com)  //寫入命令
{
LCD1602_E = 0;//使能清零
LCD1602_RS = 0;//選擇寫入命令
LCD1602_RW = 0;//選擇寫入


LCD1602_DATAPINS = com;//由於4位的接線是接到P0口的高四位,所以傳送高四位不用改
Lcd1602_Delay1ms(1);


LCD1602_E = 1;//寫入時序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;


// Lcd1602_Delay1ms(1);
LCD1602_DATAPINS = com << 4; //傳送低四位
Lcd1602_Delay1ms(1);


LCD1602_E = 1;//寫入時序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
}


void LcdWriteData(uchar dat) //寫入資料
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 1; //選擇寫入資料
LCD1602_RW = 0; //選擇寫入


LCD1602_DATAPINS = dat;//由於4位的接線是接到P0口的高四位,所以傳送高四位不用改
Lcd1602_Delay1ms(1);


LCD1602_E = 1; //寫入時序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;


LCD1602_DATAPINS = dat << 4; //寫入低四位
Lcd1602_Delay1ms(1);


LCD1602_E = 1; //寫入時序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
}


void LcdInit()  //LCD初始化子程式
{
LcdWriteCom(0x32);//將8位匯流排轉為4位匯流排
LcdWriteCom(0x28);//在四位線下的初始化
LcdWriteCom(0x0c);  //開顯示不顯示游標
LcdWriteCom(0x06);  //寫一個指標加1
LcdWriteCom(0x01);  //清屏
LcdWriteCom(0x80);  //設定資料指標起點
}

 

main.c檔案:

/*
*CS_ :片選使能,低電平晶片使能。 
*CH0 :模擬輸入通道 0,或作為 IN+/-使用。 
*CH1 :模擬輸入通道 1,或作為 IN+/-使用。 
*GND :晶片參考 0 電位(地)。 
*DI  :資料訊號輸入,選擇通道控制。 
*DO  :資料訊號輸出,轉換資料輸出。 
*CLK :晶片時鐘輸入。 
*Vcc/REF :電源輸入及參考電壓輸入(複用)。 
*/




#include<reg51.h>


#define uchar unsigned char
#define uint unsigned int


sbit key1=P1^4;  /* 報警值設定位選擇器 */
sbit key2=P1^5; /* 報警值加一 */
sbit key3=P1^6;  /* 報警值減一*/
sbit key4=P1^7;  /* 報警功能開關鍵*/


sbit LED1=P2^0;  /* 報警指示燈LED1*/
sbit LED2=P2^1;  /* 報警指示燈LED2*/
sbit beep=P2^2;  /* 蜂鳴器報警*/


sbit ADC_CS=P1^0;   /* ADC使能管腳 */
sbit ADC_CLK=P1^1;  /* ADC時鐘訊號管腳 */
sbit ADC_IO=P1^2;   /* ADC輸入輸出管腳*/


void Lcd1602_Delay1ms(uint c);   //誤差 0us
void LcdWriteCom(uchar com);  /*LCD1602寫入8位命令子函式*/
void LcdWriteData(uchar dat); /*LCD1602寫入8位資料子函式*/ 
void LcdInit(); /*LCD1602初始化子程式*/


unsigned char *buff=" max value :";
unsigned int set_value=100;     /* 報警值預設設定為100 ,三位數字*/
unsigned int adc_value=0;


unsigned char Key_Scan()   /* 按鍵掃描函式 */
{
unsigned char key_num = 0 ; 


/* check key if press */
if ((key1 ==0)||(key2 ==0)||(key3 ==0)||(key4 ==0))
{
Delay10ms(1); //消除抖動
if ((key1 ==0)||(key2 ==0)||(key3 ==0)||(key4 ==0))
{
if(key1==0)  key_num=1;
if(key2==0)  key_num=2;
if(key3==0)  key_num=3;
if(key4==0)  key_num=4;
}
}

while((key1 ==0)||(key2 ==0)||(key3 ==0)||(key4 ==0));
return key_num;   //將讀取到鍵值的值返回
}


void all_init(void)
{
   unsigned char i;
   LcdInit();/* 初始化LCD顯示 */
   LED1=0;   /* 熄滅報警燈 */
   LED2=0;   /* 熄滅報警燈 */   
   beep=0;   /* 關閉蜂鳴器 */
   ADC_CS=1; /* 使能為1 */
  LcdWriteCom(0x80);
  for(i=0;i<sizeof(buff),i++)
  LcdWriteData(buff[i]);
}
   
unsigned int get_adc_value()
{
  
}  
 
void main()
{
  unsigned char key_num;
  unsigned char beep_on_off=0;    /* 預設為關閉狀態 */
  unsigned char set_value_ hundreds; /* 百位 */
  unsigned char set_value_ decade;   /* 十位 */
  unsigned char set_value_ single;   /* 個位 */
  unsigned char set_value_bit_select=0;
  
  all_init();
  
  while(1)
  {
    adc_value=get_adc_value();
key_num=Key_Scan();
set_value_ hundreds=set_value/100;
set_value_ decade  =(set_value%100)/10;
set_value_ single  =set_value%10;

switch(key_num)
{
 case 1:
 {
set_value_bit_select++;
if(set_value_bit_select>=3)  
set_value_bit_select=0;
key_num=0;
break;
     
 }
 case 2:
 {
   switch(set_value_bit_select)
{
  case 0:
{
set_value_ single++;
if(set_value_ single>9)
set_value_ single=0;
}
  case 1:
{
set_value_ decade++;
if(set_value_ decade>9)
set_value_ decade=0;
}
  case 2:
{
set_value_ hundreds++;
if(set_value_ hundreds>9)
set_value_ hundreds=0;

default:break;

key_num=0;
break;
 }
 
 case 3:
 {
   switch(set_value_bit_select)
{
  case 0:
{
set_value_ single--;
if(set_value_ single<0)
set_value_ single=9;
}
  case 1:
{
set_value_ decade--;
if(set_value_ decade<0)
set_value_ decade=9;
}
  case 2:
{
set_value_ hundreds--;
if(set_value_ hundreds<0)
set_value_ hundreds=9;

default:break;
}
 key_num=0;
break;
 }
 case 4:
 {
beep_on_off=~beep_on_off;
key_num=0;
break;
 }
 default:break;
}


set_value=set_value_ hundreds*100+set_value_ decade*10+set_value_ single;
LcdWriteCom(0x80+sizeof(buff));
LcdWriteData(set_value/100);        /* 寫入百位 */
LcdWriteData((set_value%100)/10);   /* 寫入十位 */
LcdWriteData(set_value%10);/* 寫入個位 */
if(beep_on_off==1)
{
if(adc_value>=set_value)    /* 判斷氣體濃度是否大於設定值 */
{
LED1=1;   /* 點亮報警燈 */
LED2=1;   /* 點亮報警燈 */   
beep=1;   /* 開啟蜂鳴器 */
}
else
{
LED1=0;   /* 熄滅報警燈 */
LED2=0;   /* 熄滅報警燈 */   
beep=0;   /* 關閉蜂鳴器 */
}
}
    else
{
LED1=0;   /* 熄滅報警燈 */
LED2=0;   /* 熄滅報警燈 */   
beep=0;   /* 關閉蜂鳴器 */

  }
  
}