久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3093|回復: 3
打印 上一主題 下一主題
收起左側

at89c51溫濕度智能檢測,程序不會寫誰幫忙寫一下

[復制鏈接]
跳轉到指定樓層
樓主
求大神幫忙把程序寫一下

QQ截圖20160425144712.jpg (119.3 KB, 下載次數: 97)

51單片機溫濕度智能檢測

51單片機溫濕度智能檢測
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:116530 發表于 2016-4-25 14:51 | 只看該作者
報警的程序不會寫,sht10+1602的程序會寫,還有按鍵的程序
回復

使用道具 舉報

板凳
ID:1 發表于 2016-4-25 15:42 來自手機 | 只看該作者
sht10+1602這個程序你先發上來,然后大家可以在你的基礎上面修改
回復

使用道具 舉報

地板
ID:947480 發表于 2021-12-15 16:43 | 只看該作者
#include "reg52.H"
#include "stdio.h"
#include "intrins.h"
#include <math.h>

#define DB P0//液晶并行數據接口
sbit  RS = P2^0;//液晶指令數據信號
sbit  RW = P2^1;//液晶讀寫信號
sbit  E  = P2^2;//液晶使能信號


unsigned char  key_value;//獲取到按鍵的值

sbit Sck_P     = P1^1;                        // SHT11傳感器的時鐘管腳
sbit Data_P    = P1^0;                        // SHT11傳感器的數據管腳

unsigned char temp;                                                        // 保存溫度
unsigned char humi;                                                  // 保存濕度

enum { TEMP,HUMI };
typedef union                              //定義共用同類型
{
        unsigned int i;
        float f;
}value;

//是否應答
#define NACK        0
#define ACK                1
//SHT75傳感器命令集                地址                命令        讀/寫
#define MEASURE_TEMP        0x03        //000 0001  1
#define MEASURE_HUMI        0x05        //000 0010  1
#define STATUS_REG_W        0x06        //000 0011  0
#define STATUS_REG_R        0x07        //000 0011  1
#define RESET                        0x1E        //000 1111  0

unsigned char now_window;//當前顯示窗口
unsigned char curr_menu;
#define  normal_mode  0x10//輸入密碼狀態
#define  set_mode  0x20//輸入密碼狀態

signed char AlarmTL=10;                                // 溫度下限報警值
signed char AlarmTH=30;                                // 溫度上限報警值
signed char AlarmHL=40;                             // 濕度下限報警值
signed char AlarmHH=80;                                // 濕度上限報警值

unsigned char i;
unsigned char cnt_100ms;
unsigned char time_100ms_flag;
unsigned char open_del;//開鎖成功延時計數
unsigned char open_flag;//鎖狀態標志
sbit beep = P1^2;

sbit LedTL_P   = P1^3;                        // 溫度過低報警指示燈
sbit LedTH_P   = P1^4;                        // 溫度過高報警指示燈
sbit LedHL_P   = P1^5;                        // 濕度過低報警指示燈
sbit LedHH_P   = P1^6;                        // 濕度過高報警指示燈

/*******************************************************************************
* 函 數 名         : delay_ms
* 函數功能                   : 延時函數,延時1ms
* 輸    入         : cnt
* 輸    出         : 無
* 說    名         : 該函數是在12MHZ晶振下,12分頻單片機的延時。
*******************************************************************************/
void delay_ms(unsigned int cnt)   //
{
        unsigned int x;
        for( ; cnt>0; cnt--)
        {
                for(x=110; x>0; x--);//軟件延時為1MS
        }
}
#if 0
void delay_us(unsigned int cnt)   //
{
        while(cnt--);
}
#endif
/******************************************************
** 函數名:time_init
** 描述  :定時器初始化
** 輸入  :無
** 輸出  :無
******************************************************/
void time_init(void)
{
          TMOD |= 0x01;//time0 工作方式為1
          TH0 = 0xf8;//裝載初值
          TL0 = 0x2f;//裝載初值,為2ms(65535-63535)
      TR0 = 1;//開啟定時器
          ET0 = 1;//打開中斷
          EA=1;
}
/******************************************************
** 函數名:key_scan
** 描述  :按鍵掃描
** 輸入  :無
** 輸出  :無
******************************************************/
void key_scan(void)
{
        static unsigned char key_in_flag = 0;//按鍵按下標志
        unsigned char key_l;//存儲掃描到行列值。
        key_value = 20;//按鍵值清除
        if((P3 & 0x0f) != 0x0f)//按鍵按下
        {
                delay_ms(1);//按鍵消抖動
                if(((P3 & 0x0f) != 0x0f) && (key_in_flag == 1))
                {
                        key_in_flag = 0;//松手檢測防止一直觸發
                        P3 = 0x0f;
            //delay_ms(1);//按鍵消抖動
                        key_l = P3;//掃描得到按鍵值
                        switch(key_l)
                        {
                                //獲取按鍵值
                                case 0x0e:
                                {
                                        key_value = 1;
                                }
                                break;
                                case 0x0d:
                                {
                                        key_value = 2;
                                }
                                break;
                                case 0x0b:
                                {
                                        key_value = 3;
                                }
                                break;
                                //case 0x70:
                                //break;
                        }
                }
        }
        else
        {
                key_in_flag = 1;//(按鍵松開標志)
        }

}

/*******************************************************************************
* 函 數 名         : LcdWriteCom
* 函數功能                   : 向LCD寫入一個字節的命令
* 輸    入         : u8com
* 輸    出         : 無
*******************************************************************************/
void lcd_wri_com(unsigned char com)          //寫入命令
{
        E = 0;         //使能清零
        RS = 0;         //選擇寫入命令
        RW = 0;         //選擇寫入

        DB = com;
        delay_ms(1);

        E = 1;         //寫入時序
        delay_ms(5);
        E = 0;
}

/*******************************************************************************
* 函 數 名         : LcdWriteData
* 函數功能                   : 向LCD寫入一個字節的數據
* 輸    入         : u8dat
* 輸    出         : 無
*******************************************************************************/

void lcd_wri_data(unsigned char dat)//寫入數據
{
        E = 0;          //使能清零
        RS = 1;          //選擇寫入數據
        RW = 0;          //選擇寫入
        DB = dat;
        delay_ms(1);
        E = 1;          //寫入時序
        delay_ms(5);
        E = 0;
}
/*******************************************************************************
* 函 數 名         : WriString
* 函數功能                   : 刷新屏幕顯示
* 輸    入         : hang,add,*p
* 輸    出         : 無
*******************************************************************************/
void wri_string(unsigned char y,unsigned char x,unsigned char *p)
{
        if(y==1)//如果選擇第一行
                lcd_wri_com(0x80+x);//選中地址
        else
                lcd_wri_com(0xc0+x);//選中地址
                while(*p)
                {
                        lcd_wri_data(*p);//寫入數據
                        p++;
                }
}
/*******************************************************************************
* 函 數 名         : lcd_write_char
* 函數功能                   :
* 輸    入         :
* 輸    出         : 無
*******************************************************************************/
void lcd_write_char(unsigned char y, unsigned char x, unsigned char dat) //列x=0~15,行y=0,1
{
        unsigned char temp_l, temp_h;
        if(y==1)//如果選擇第一行
                lcd_wri_com(0x80+x);//選中地址
        else
                lcd_wri_com(0xc0+x);//選中地址
        temp_l = dat % 10;
    temp_h = dat / 10;
    lcd_wri_data(temp_h + 0x30);          //convert to ascii
    lcd_wri_data(temp_l + 0x30);
}
/*********************光標控制***********************/
void lcd1602_guanbiao(unsigned char y, unsigned char x,unsigned char on_off)
{
        if(on_off == 1)   //開光標
        {
                if(y==1)//如果選擇第一行
                lcd_wri_com(0x80+x);
            else
                lcd_wri_com(0xc0+x);//將光標移動到秒個位
                lcd_wri_com(0x0f);//顯示光標并且閃爍
        }
        else
        {
        if(y==1)//如果選擇第一行
                lcd_wri_com(0x80+x);
            else
                lcd_wri_com(0xc0+x);//將光標移動到秒個位
                lcd_wri_com(0x0c);   //關光標
        }
}

/*******************************************************************************
* 函 數 名       : LcdInit()
* 函數功能                 : 初始化LCD屏
* 輸    入       : 無
* 輸    出       : 無
*******************************************************************************/
void lcd_init(void)                                                  //LCD初始化子程序
{
        lcd_wri_com(0x38);//置功能8位雙行
        lcd_wri_com(0x0c);//顯示開關光標
        lcd_wri_com(0x06);//字符進入模式屏幕不動字符后移
        delay_ms(5);//延時5ms
        lcd_wri_com(0x01);  //清屏
        wri_string(1,0,"welcome user DHT");//初始化顯示
        wri_string(2,0,"H:   %RH T:   C ");//初始化顯示
}

/*********************************************************/
// 往SHT11寫入一個字節
/*********************************************************/
char ShtWriteByte(unsigned char value)
{
        unsigned char i,error=0;
        for(i=128;i>0;i>>=1)  // 高位為1,循環右移
        {
                if (i&value)
                        Data_P=1;               // 和要發送的數相與,結果為發送的位
                else
                        Data_P=0;
                Sck_P=1;
                _nop_();                                                // 延時3us
                _nop_();
                _nop_();
                Sck_P=0;
        }
        Data_P=1;                                            // 釋放數據線
        Sck_P=1;
        error=Data_P;                                  // 檢查應答信號,確認通訊正常
        _nop_();
        _nop_();
        _nop_();
        Sck_P=0;
        Data_P=1;
        return error;                                 // error=1 通訊錯誤
}


/*********************************************************/
// 從SHT11讀出一個字節
/*********************************************************/
char ShtReadByte(unsigned char ack)
{
        unsigned char i,val=0;
        Data_P=1;                                                 // 釋放數據線
        for(i=0x80;i>0;i>>=1)        // 高位為1,循環右移
        {
                Sck_P=1;
                if(Data_P)
                        val=(val|i);            // 讀一位數據線的值
                Sck_P=0;
        }
        Data_P=!ack;                            // 如果是校驗,讀取完后結束通訊
        Sck_P=1;
        _nop_();                                                        // 延時3us
        _nop_();
        _nop_();
        Sck_P=0;
        _nop_();
        _nop_();
        _nop_();
        Data_P=1;                                                 // 釋放數據線
        return val;
}


/*********************************************************/
// SHT11啟動傳輸
/*********************************************************/
void ShtTransStart(void)
{
        Data_P=1;
        Sck_P=0;
        _nop_();
        Sck_P=1;
        _nop_();
        Data_P=0;
        _nop_();
        Sck_P=0;
        _nop_();
        _nop_();
        _nop_();
        Sck_P=1;
        _nop_();
        Data_P=1;
        _nop_();
        Sck_P=0;
}


/*********************************************************/
// SHT11連接復位
/*********************************************************/
void ShtConnectReset(void)
{
        unsigned char i;
        Data_P=1;                                    //準備
        Sck_P=0;
        for(i=0;i<9;i++)          //DATA保持高,SCK時鐘觸發9次,發送啟動傳輸,通迅即復位
        {
                Sck_P=1;
                Sck_P=0;
        }
        ShtTransStart();           //啟動傳輸
}
/*********************************************************/
// SHT11溫濕度檢測
/*********************************************************/
char ShtMeasure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
{
        unsigned error=0;
        unsigned int i;
        ShtTransStart();                  // 啟動傳輸
        switch(mode)                       // 選擇發送命令
        {
                case 1 :                                           // 測量溫度
                        error+=ShtWriteByte(0x03);
                        break;
                case 2 :                                           // 測量濕度
                        error+=ShtWriteByte(0x05);
                        break;
                default:
                        break;
        }
        for(i=0;i<65535;i++)
                if(Data_P==0)
                        break;                                          // 等待測量結束
                if(Data_P)
                        error+=1;                           // 如果長時間數據線沒有拉低,說明測量錯誤
        *(p_value) =ShtReadByte(1);                  // 讀第一個字節,高字節 (MSB)
        *(p_value+1)=ShtReadByte(1);                 // 讀第二個字節,低字節 (LSB)
        *p_checksum =ShtReadByte(0);          // read CRC校驗碼
        return error;                                                                          // error=1 通訊錯誤
}
/*********************************************************/
// SHT11溫濕度值標度變換及溫度補償
/*********************************************************/
void CalcSHT11(float *p_humidity ,float *p_temperature)
{
        const float C1=-4.0;                                 // 12位濕度精度 修正公式
        const float C2=+0.0405;                        // 12位濕度精度 修正公式
        const float C3=-0.0000028;        // 12位濕度精度 修正公式
        const float T1=+0.01;                                 // 14位溫度精度 5V條件 修正公式
        const float T2=+0.00008;                 // 14位溫度精度 5V條件 修正公式
        float rh=*p_humidity;                                 // rh: 12位 濕度
        float t=*p_temperature;                        // t:  14位 溫度
        float rh_lin;                                                                // rh_lin: 濕度 linear值
        float rh_true;                                                        // rh_true: 濕度 ture值
        float t_C;                                                                         // t_C : 溫度 ℃
        t_C=t*0.01 - 40;                                                 //補償溫度
        rh_lin=C3*rh*rh + C2*rh + C1;                                        //相對濕度非線性補償
        rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;                //相對濕度對于溫度依賴性補償
        *p_temperature=t_C;                                         //返回溫度結果
        *p_humidity=rh_true;                                 //返回濕度結果
}
/*********************************************************/
// 溫度校正
/*********************************************************/
unsigned char TempCorrect(int temp)
{
        if(temp<0)        temp=0;
        if(temp>970)  temp=970;
        if(temp>235)  temp=temp+10;
        if(temp>555)  temp=temp+10;
        if(temp>875)  temp=temp+10;
        temp=(temp%1000)/10;
        return temp;
}
/*********************************************************/
// 濕度校正
/*********************************************************/
unsigned char HumiCorrect(unsigned int humi)
{
        if(humi>999)  humi=999;
        if((humi>490)&&(humi<951))  humi=humi-10;
        humi=(humi%1000)/10;
        return humi+4;
}
/*********************************************************/
// 讀取SHT11的溫濕度數據
/*********************************************************/
void ReadShtData()
{
        value humi_val,temp_val;          // 定義兩個共同體,一個用于濕度,一個用于溫度
        unsigned char error;                                                          // 用于檢驗是否出現錯誤
        unsigned char checksum;                                                  // CRC
        unsigned int temp1,humi1;                                                // 臨時讀取到的溫濕度數據

        error=0;                                                                                 //初始化error=0,即沒有錯誤
        error+=ShtMeasure((unsigned char*)&temp_val.i,&checksum,1);         //溫度測量
        error+=ShtMeasure((unsigned char*)&humi_val.i,&checksum,2);         //濕度測量

        if(error!=0)                                                           //如果發生錯誤,系統復位
                ShtConnectReset();
        else
        {
                humi_val.f=(float)humi_val.i;                                 //轉換為浮點數
                temp_val.f=(float)temp_val.i;                                  //轉換為浮點數
                CalcSHT11(&humi_val.f,&temp_val.f);          //修正相對濕度及溫度
                temp1=temp_val.f*10;
                temp=TempCorrect(temp1);
                humi1=humi_val.f*10-50;
                humi=HumiCorrect(humi1);
        humi = humi + 2;
        }

}
void AlarmJudge(void)
{
        if(temp>AlarmTH)                                // 溫度是否過高
        {
                LedTH_P=0;
                LedTL_P=1;
        }
        else if(temp<AlarmTL)                // 溫度是否過低
        {
                LedTL_P=0;
                LedTH_P=1;
        }
        else                                                                                // 溫度正常
        {
                LedTH_P=1;
                LedTL_P=1;
        }

        if(humi>AlarmHH)                           // 濕度是否過高
        {
                LedHH_P=0;
                  LedHL_P=1;
        }
        else if(humi<AlarmHL)                // 濕度是否過低
        {
                LedHL_P=0;
                LedHH_P=1;
        }
        else                                                                           // 濕度正常
        {
                LedHH_P=1;
                LedHL_P=1;
        }

        if((LedHH_P==0)||(LedHL_P==0)||(LedTH_P==0)||(LedTL_P==0))         // 蜂鳴器判斷,只要至少1個報警燈亮,蜂鳴器就報警
        {
                for(i=0;i<3;i++)
                {
                        beep=0;
                        delay_ms(100);
                        beep=1;
                        delay_ms(100);
                }
        }
}

/******************************************************
** 函數名:key_service
** 描述  :按鍵服務函數
** 輸入  :無
** 輸出  :無
** 調用  :主程序
******************************************************/
void key_service(void)
{
    switch (now_window)
    {
           case  normal_mode:
           {
              if (key_value == 1)
              {
                    now_window = set_mode;
                    curr_menu = 0;
                    wri_string(1,0,"T:  -           ");//初始化顯示
                    wri_string(2,0,"H:  -           ");//初始化顯示
                    lcd_write_char(1,2,AlarmTL);
                            lcd_write_char(1,6,AlarmTH);
                    lcd_write_char(2,2,AlarmHL);
                            lcd_write_char(2,6,AlarmHH);
                    lcd1602_guanbiao(1,3,1);
              }
           }
           break;
           case  set_mode:
           {
                    if (key_value == 1)
                    {
                            ++curr_menu;
                            if (curr_menu==1)
                            {
                                lcd1602_guanbiao(1,7,1);
                            }
                            else if(curr_menu==2)
                            {
                                lcd1602_guanbiao(2,3,1);
                            }
                            else if(curr_menu==3)
                            {
                                lcd1602_guanbiao(2,7,1);
                            }
                            if(curr_menu>3)
                            {
                                curr_menu = 0;
                                lcd1602_guanbiao(2,7,0);
                                now_window = normal_mode;
                                wri_string(1,0,"welcome user DHT");//初始化顯示
                                    wri_string(2,0,"H:   %RH T:   C ");//初始化顯示
                                    lcd_write_char(2,2,humi);
                                        lcd_write_char(2,11,temp);
                                        lcd_wri_com(0xcd);
                                        lcd_wri_data(0xdf);
                            }
                    }
                    if (key_value == 2)
                    {
                            if(curr_menu==0)
                            {
                                 if(++AlarmTL>99)
                                 {
                                     AlarmTL = 0;
                                 }
                                 lcd_write_char(1,2,AlarmTL);
                                 lcd1602_guanbiao(1,3,1);
                            }
                            else if (curr_menu==1)
                            {
                                 if(++AlarmTH>99)
                                 {
                                     AlarmTH = 0;
                                 }
                                 lcd_write_char(1,6,AlarmTH);
                                 lcd1602_guanbiao(1,7,1);
                            }
                            else if(curr_menu==2)
                            {
                                if(++AlarmHL>99)
                                 {
                                     AlarmHL = 0;
                                 }
                                 lcd_write_char(2,2,AlarmHL);
                                 lcd1602_guanbiao(2,3,1);
                            }
                            else if(curr_menu==3)
                            {
                                 if(++AlarmHH>99)
                                 {
                                     AlarmHH = 0;
                                 }
                                 lcd_write_char(2,6,AlarmHH);
                                 lcd1602_guanbiao(2,7,1);
                            }
                    }
                    if (key_value == 3)
                    {
                            if(curr_menu==0)
                            {
                                 if(--AlarmTL<0)
                                 {
                                     AlarmTL = 99;
                                 }
                                 lcd_write_char(1,2,AlarmTL);
                                  lcd1602_guanbiao(1,3,1);
                            }
                            else if (curr_menu==1)
                            {
                                 if(--AlarmTH<0)
                                 {
                                     AlarmTH = 99;
                                 }
                                 lcd_write_char(1,6,AlarmTH);
                                 lcd1602_guanbiao(1,7,1);
                            }
                            else if(curr_menu==2)
                            {
                                if(--AlarmHL<0)
                                 {
                                     AlarmHL = 99;
                                 }
                                  lcd_write_char(2,2,AlarmHL);
                                   lcd1602_guanbiao(2,3,1);
                            }
                            else if(curr_menu==3)
                            {
                                if(--AlarmHH<0)
                                 {
                                     AlarmHH = 99;

                                 }
                                 lcd_write_char(2,6,AlarmHH);
                                  lcd1602_guanbiao(2,7,1);
                            }
                    }
           }
           break;
    }
}
/******************************************************
** 函數名:alm
** 描述  :定時閃爍函數
** 輸入  : 無
** 輸出  :無
** 調用  :中斷調用
******************************************************/
void time_service(void)
{
                if(time_100ms_flag)
                {
                        time_100ms_flag = 0;
            if(now_window == normal_mode)
            {
                ReadShtData();
                lcd_write_char(2,2,humi);
                        lcd_write_char(2,11,temp);
                AlarmJudge();//報警函數
            }
                }

}

/******************************************************
** 函數名:init_all_hardware
** 描述  :初始化所有硬件,及其變量參數。
** 輸入  :無
** 輸出  :無
** 調用  :主程序
******************************************************/
void init_all_hardware(void)
{
                   delay_ms(100);
                time_init();//定時器初始化
                ShtConnectReset();
                ReadShtData();
                lcd_init();
                lcd_write_char(2,2,humi);
                lcd_write_char(2,11,temp);
                lcd_wri_com(0xcd);
                lcd_wri_data(0xdf);
                key_value = 20;
                now_window = normal_mode;
                cnt_100ms = 0;
                time_100ms_flag = 0;
        curr_menu = 0;
}
void main(void)
{
         init_all_hardware();//初始化硬件,IO和定時器
         while(1)
         {
                 key_scan();//按鍵掃描
                 key_service();//按鍵服務處理函數
                 time_service();//時間處理函數
         }
}
/******************************************************
** 函數名:time0_interrupt
** 描述  :按鍵掃描函數
** 輸入  :無
** 輸出  :無
******************************************************/
void time0_interrupt() interrupt 1
{
           TF0 = 0;//清除標志
           TR0 = 0;
           if (++cnt_100ms>50)
           {
                        cnt_100ms = 0;
                        time_100ms_flag = 1;
           }
           TR0 = 1;
           TH0 = 0xf8;
           TL0 = 0x2f;//裝載初值2ms(65535-63535)
}
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91av免费观看 | 精品久久久久久久久久 | 午夜看电影在线观看 | a黄视频| 深夜爽视频 | 超碰成人av | 黄色一级片视频 | 国产精品爱久久久久久久 | 91就要激情 | 黄网站免费观看 | 男女视频91 | 日韩欧美在 | 日韩成人av在线 | 97伦理| 日韩1区 | 狠狠av | 91麻豆精品国产91久久久久久 | caoporn视频在线 | 久久精品天堂 | 久久久国产一区二区三区 | 国产日韩欧美激情 | 手机看片在线播放 | 午夜一区二区三区在线观看 | 久久精品亚洲 | 99久久夜色精品国产亚洲96 | 在线视频a | 国产中文区二幕区2012 | 久久亚洲国产精品 | 97精品视频在线 | 国产精品成人品 | 国产日韩欧美一区二区 | 久久精品国产一区二区三区 | 成人99| 天天综合久久 | 国产一区二区在线视频 | 久久久久国产精品一区二区 | 欧美video | 日本五月婷婷 | 久久久久亚洲 | 日韩h | 日韩一级电影免费观看 |