51單片機課程設計:基於DHT11的溫溼度報警器

51單片機課程設計:基於DHT11的溫溼度報警器

    本程序適用於51系列單片機,主要用於讀取DHT11溫溼度模塊數值,顯示在數碼管上,同時還具備溫溼度報警功能,當超出預設值,蜂鳴器報警,可在吉林農業大學單片機開發板上完美運行,其他朋友可以修改部分代碼移植的其他型號的開發板上。工程文件以及開發板電路圖可到附件下載,同時DHT11部分資料在附件也可以下載。

    關於粘貼複製亂碼的問題:如果程序複製到Keil編譯器上出現註釋亂碼,可以先建一個.c文件,也就是說不在keil裏面編輯,然後用記事本打開.c文件,將源碼複製進去,再在keil中添加文件即可。

/************************************說明***************************************
程序運行時 會對模塊進行預熱 保證讀取第一個數值的精確
預熱時間大概爲4秒左右
程序初始化時將會提示你設置最大溫溼度 
H1  最高溫度   L1   最低溫度
H2  最高溼度   L2   最低溼度
按鈕K1溫度加    按鈕K2溫度減
設置完成後  按K3   即確定按鈕 開始監控報警   
                                                    (適用於吉農51單片機開發板)
                                    2016-12-29----------------------------SWorld
********************************************************************************/
#include <reg52.h>  
#define OK 1 
#define ERROR 0  
#define NUMBER  20  
#define SIZE  5 
/*-----------------------------顯示部分接線方法-------------------------------*/
#define GPIO_DIG P0
sbit WEC=P2^3;              //段選
sbit DUC=P2^2;  //位選
/*----------------------------模塊引腳連接-------------------------------------*/
sbit dht11 = P2^0;  //dht 接口    只要接一個就行   接dht11   data0接口  NC不用管
/*-----------------------------按鍵引腳方法------------------------------------*/
sbit add=P2^5;//增加    連接K2
sbit sub=P2^4;//減少    連接K1
sbit ok=P2^6;//確定    連接K3
/*----------------------------報警引腳連接-------------------------------------*/
sbit bell=P2^7;//蜂鳴器接口  連接蜂鳴器
/*------------------------------全局變量---------------------------------------*/
unsigned char flag;   
/*---------------分別代表數碼管上的0~9共10位數以及字母L、H----------------------*/
unsigned char code array[12]= { 
         0x3f,0x06,0x5b,0x4f,0x66, 
         0x6d,0x7d,0x07,0x7f,0x6f,0x38,0x76//L  H
         }; 
unsigned char DisplayData[8]; //用來存放要顯示的8位數的值
unsigned int HTemp,LTemp,HHumi,LHumi,setok;          //用來存放最大溫溼度  以及是否設置好溫溼度 
int temp_value, humi_value;                                //溫溼度數值存放
unsigned char status; 
unsigned char value_array[5]; 
 
 
/*------------------------------函數聲明---------------------------------------*/
void Delay_1ms(unsigned int ms); 
unsigned char ReadTempAndHumi(void);  
void InitTime(void); 
void Delay_1ms(unsigned int ms); 
void SMG_Display(unsigned int value,unsigned int way ) ;       //顯示部分
unsigned char ReadValue(void); 
 
/*------------------------------延時函數
  延時1ms
 ---------------------------------------*/
void Delay_1ms(unsigned int ms) 
{ 
     unsigned int x, y; 
     for(x = ms; x > 0; x--) 
     { 
        for(y = 124; y > 0; y--); 
     } 
} 
/*------------------------------延時函數
  延時10ns
---------------------------------------*/
void  Delay_10us(void) 
{ 
    unsigned char  i; 
    i--; 
    i--; 
    i--; 
    i--; 
    i--; 
    i--; 
}  
/*------------------------------讀取模塊數值
---------------------------------------*/
unsigned char ReadValue(void) 
{ 
     unsigned char count, value = 0, i; 
     status = OK;   
     for(i = 8; i > 0; i--) 
     { 
        value <<= 1; 
        count = 0; 
        while(dht11 == 0 && count++ < NUMBER); 
        if(count >= NUMBER) 
        { 
             status = ERROR;
             return 0;    
        } 
        Delay_10us(); 
        Delay_10us(); 
        Delay_10us(); 
        if(dht11 != 0) 
        { 
             value++; 
             while(dht11 != 0 && count++ < NUMBER) 
             { 
                dht11 = 1; 
             } 
             if(count >= NUMBER) 
             { 
                status = ERROR;  
                return 0; 
              }  
        } 
    }  
    return (value); 
} 

/*------------------------------獲取模塊溫溼度
---------------------------------------*/
unsigned char ReadTempAndHumi(void) 
{  
     unsigned char i = 0, check_value = 0,count = 0; 
     EA = 0; 
     dht11 = 0;     
     Delay_1ms(20);   
     dht11 = 1;     
     Delay_10us(); 
     Delay_10us(); 
     Delay_10us(); 
     Delay_10us();  
     if(dht11 != 0)    
     { 
        EA = 1; 
        return ERROR; 
     } 
     else 
    { 
        while(dht11 == 0 && count++ < NUMBER);   
        if(count >= NUMBER)  
        { 
             dht11 = 1; 
             EA = 1; 
             return ERROR;   
        } 
        count = 0; 
        dht11 = 1;
        while(dht11 != 0 && count++ < NUMBER); 
        if(count >= NUMBER) 
        { 
             dht11 = 1; 
             EA = 1; 
             return ERROR;  
        }  
        for(i = 0; i < SIZE; i++) 
        { 
             value_array[i] = ReadValue(); 
             if(status == ERROR)
             { 
                dht11 = 1; 
                EA = 1;    
                return ERROR;  
             } 
             if(i != SIZE - 1)  
             { 
                check_value += value_array[i];  
             } 
        }
        if(check_value == value_array[SIZE - 1]) 
        { 
             humi_value = value_array[0] * 10; 
             temp_value = value_array[2] * 10; 
             dht11 = 1; 
             EA = 1; 
             return OK;   
        } 
        else 
        { 
         EA = 1; 
         return ERROR; 
        } 
    }         
} 
/**************************************************************
鍵盤掃描子程序
**************************************************************/
unsigned char Key_Scan()
{
    unsigned char keyValue = 0 , i; //保存鍵值
    //--檢測按鍵1--//
    if (ok != 1)//檢測按鍵K3是否按下
    {
        Delay_1ms(10);//消除抖動
        if (ok != 1)//再次檢測按鍵是否按下
        {
            keyValue = 3;
            i = 0;
            while ((i<50) && (ok != 1)) //檢測按鍵是否鬆開
            {
                Delay_1ms(10);
                i++;
            }
        }
    }
    //--檢測按鍵1--//
    if (add != 1)//檢測按鍵K1是否按下
    {
        Delay_1ms(10);//消除抖動
        if (add!= 1)//再次檢測按鍵是否按下
        {
            keyValue = 2;
            i = 0;
            while ((i<50) && (add != 1)) //檢測按鍵是否鬆開
            {
                Delay_1ms(10);
                i++;
            }
        }
    }
    //--檢測按鍵1--//
    if (sub != 1)//檢測按鍵K2是否按下
    {
        Delay_1ms(10);//消除抖動
        if (sub!= 1)//再次檢測按鍵是否按下
        {
            keyValue = 1;
            i = 0;
            while ((i<50) && (sub != 1)) //檢測按鍵是否鬆開
            {
                Delay_1ms(10);
                i++;
            }
        }
    }
    return keyValue;   //將讀取到鍵值的值返回
}
/*******************************************************************************
* 函 數 名         : DigDisplay
* 函數功能     : 使用數碼管顯示
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void DigDisplay()
{
    unsigned char i;
    unsigned int j;
    for(i=0;i<8;i++)
    {
        WEC=1;DUC=0;
        switch(i) //位選,選擇點亮的數碼管,
        {
            case(0):
                GPIO_DIG=0x7F; break;//顯示第0位
            case(1):
                GPIO_DIG=0xBF; break;//顯示第1位
            case(2):
                GPIO_DIG=0xDF; break;//顯示第2位
            case(3):
                GPIO_DIG=0xEF; break;//顯示第3位
            case(4):
                GPIO_DIG=0xF7; break;//顯示第4位
            case(5):
                GPIO_DIG=0xFB; break;//顯示第5位
            case(6):
                GPIO_DIG=0xFD; break;//顯示第6位
            case(7):
                GPIO_DIG=0xFE; break;//顯示第7位
        }
        WEC=0;DUC=1;
        GPIO_DIG=DisplayData[i];//發送段碼
        j=50; //掃描間隔時間設定
        while(j--);
        GPIO_DIG=0x00;//消隱
    }
}
/*------------------------------主函數
主函數共分爲5部分,有switch語句執行相關操作
case 1:設置最高溫度,完成設置後跳到下一循環
case 2:設置最低溫度,完成設置後跳到下一循環
case 3:設置最高溼度,完成設置後跳到下一循環
case 4:設置最低溼度,完成設置後跳到下一循環
case 5:溫溼度監控主循環,當低於後者超過預設值,
觸發警報。所讀取的數值同時顯示於數碼管
---------------------------------------*/ 
void main(void) 
{ 
    unsigned char mark = 0; 
    Delay_1ms(1000); 
    ReadTempAndHumi(); 
    Delay_1ms(3000); 
    InitTime(); 
    WEC=0;DUC=0;
    HTemp=30,LTemp=20;
    HHumi=100,LHumi=20;
    bell=1,setok=1;
    while(1) 
    { 
        switch(setok)
        {
            case 1:
                DisplayData[7]=array[11];
                DisplayData[6]=array[1];
                DisplayData[4]=array[HTemp/10];
                DisplayData[3]=array[HTemp%10];
                switch(Key_Scan())
                {
                case 1:
                    HTemp-=2;
                break;
                case 2:
                    HTemp+=2;
                break;
                case 3:
                    setok=2;
                break;
                }
            break;
            case 2:
                DisplayData[7]=array[10];
                DisplayData[6]=array[1];
                DisplayData[4]=array[LTemp/10];
                DisplayData[3]=array[LTemp%10];
                switch(Key_Scan())
                {
                    case 1:
                        LTemp-=2;
                    break;
                    case 2:
                        LTemp+=2;
                    break;
                    case 3:
                        setok=3;
                    break;
                }
                break;
            case 3:
                DisplayData[7]=array[11];
                DisplayData[6]=array[2];
                DisplayData[4]=array[HHumi/100];
                DisplayData[3]=array[HHumi%100/10];
                DisplayData[2]=array[HHumi%10];
                switch(Key_Scan())
                {
                case 1:
                    HHumi-=2;
                break;
                case 2:
                    HHumi+=2;
                break;
                case 3:
                    setok=4;
                break;
                }
            break;
            case 4:
                DisplayData[7]=array[10];
                DisplayData[6]=array[2];
                DisplayData[4]=array[LHumi/100];
                DisplayData[3]=array[LHumi%100/10];
                DisplayData[2]=array[LHumi%10];
                switch(Key_Scan())
                {
                    case 1:
                        LHumi-=2;
                    break;
                    case 2:
                        LHumi+=2;
                    break;
                    case 3:
                        setok=5;
                    break;
                }
            break;
            case 5:
                DisplayData[4]=0x00;
                if(flag == 30) 
                { 
                    flag = 0; 
                    mark++; 
                    ReadTempAndHumi(); 
                    if(temp_value<LTemp*10||temp_value>HTemp*10||humi_value<LHumi*10||humi_value>HHumi*10)
                    {
                        bell=0;
                    }
                    else
                    {
                        bell=1;
                    }
                } 
                SMG_Display(temp_value,0); 
                SMG_Display(humi_value,1); 
            break;
         }
         DigDisplay();
    } 
} 
/*------------------------------定時器初始化
---------------------------------------*/
void InitTime(void) 
{ 
    TH0 = (unsigned char)((65535U - 50000) >> 8); 
    TL0 = (unsigned char)(65535U - 50000) ; 
    TMOD = 0X01; 
    TR0 = 1; 
    ET0 = 1; 
    EA = 1; 
}  
/*------------------------------數值轉換
將讀取到的數值轉換爲數碼管可顯示的數值
---------------------------------------*/
void SMG_Display(unsigned int value,unsigned int way ) 
{ 
     unsigned char ge, bai, shi; 
     ge = value % 10; 
     shi = value % 100 / 10; 
     bai = value % 1000 / 100; 
     if(way==0)
     { 
          DisplayData[7]=array[bai];
          DisplayData[6]=array[shi]|0x80;
          DisplayData[5]=array[ge];
     }
     else
     {
         DisplayData[3]=array[bai];
         DisplayData[2]=array[shi]|0x80;
         DisplayData[1]=array[ge];
     }
}  
/*------------------------------定時器0
---------------------------------------*/
void timer(void) interrupt 1 
{ 
     TH0 = (unsigned char)((65535 - 50000) >> 8);  
     TL0 = (unsigned char)(65535 - 50000); 
     flag++; 
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章