|
單片機源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #include <absacc.h>
- #include <math.h>
-
- #define uchar unsigned char
- #define uint unsigned int
- //定義四個輸出端口
- sbit Led_jiashi=P3^4; //加濕
- sbit Led_qushi=P3^3; //去濕
- sbit Led_jiangwen=P3^1; //降溫
- sbit Led_shengwen=P3^2; //升溫
- //定義三個設置按鍵
- sbit Key_SET = P2^0;
- sbit Key_ADD = P2^1;
- sbit Key_SUB = P2^2;
- sbit Key_OK = P2^3;
- //定義24C02數據口
- sbit SCL = P1^0;
- sbit SDA = P1^1;
- //定義DHT11數據口
- sbit DATA = P1^7;
- sbit buzz=P3^5;
- //定義LCD1602端口
- sbit E=P1^3; //1602使能引腳
- //sbit RW=P2^6; //1602讀寫引腳
- sbit RS=P1^2; //1602數據/命令選擇引腳
- //定義全局變量
- uchar U8FLAG,U8temp,U8comdata,U8RH_data_H_temp,U8RH_data_L_temp,U8T_data_H_temp,U8T_data_L_temp,U8checkdata_temp;
- uchar U8RH_data_H,U8RH_data_L,U8T_data_H,U8T_data_L,U8checkdata;
- uchar Mode,humidity,temperature;
- char TH,TL,HH,HL;
- bit bdata FlagStartRH,hot,cold,humid,dry,BJ;
- //定時器0初始化
- void Timer0_Init()
- {
- ET0 = 1; //允許定時器0中斷
- TMOD = 0x11; //定時器工作方式選擇
- TL0 = 0xFF;
- TH0 = 0x4B; //定時器賦予初值
- TR0 = 1; //啟動定時器
- }
- //定時器0中斷
- void Timer0_ISR (void) interrupt 1 using 0
- {
- uchar RHCounter;
- TL0 = 0xFF;
- TH0 = 0x4B; //定時器賦予初值
- RHCounter++;
- if(RHCounter%10==0&&BJ==1)
- buzz=!buzz;
- else if(BJ==0)
- buzz=1;
- //每2秒鐘啟動一次溫濕度轉換
- if (RHCounter >= 40)
- {
- FlagStartRH = 1;
- RHCounter = 0;
- }
- }
- /*********************************
- BASE DRIVE
- **********************************/
- void DELAY(unsigned int t)
- {
- while(t!=0)
- t--;
- }
- /******************************
- IIC DRIVE
- ******************************/
- void IICStart(void)
- {
- SCL=0;
- DELAY(1);
- SDA=1; SCL=1; DELAY(1);
- SDA=0; DELAY(1);
- SCL=0;
- }
- void IICStop(void)
- {
- SDA=0;SCL=1; DELAY(1);
- SDA=1; DELAY(1);
- SCL=0;
- }
- void SEND0(void)
- {
- SDA=0;
- SCL=1;
- DELAY(1);
- SCL=0;
- }
- void SEND1(void)
- {
- SDA=1;
- DELAY(1);
- SCL=1;
- DELAY(1);
- SCL=0;
- }
- bit Check_Ack(void)
- {
- unsigned char errtime=250;
- DELAY(1);
- SCL=1;
- DELAY(1);
- CY=SDA;
- while(CY)
- {
- errtime--;
- CY=SDA;
- if (!errtime)
- {
- IICStop();
- return 1;
- }
- }
- DELAY(1);
- SCL=0;
- return 0;
- }
- void Write_byte(unsigned char dat)
- {
- unsigned char i;
- for(i=0;i<8;i++)
- {
- if((dat<<i)&0x80)
- SEND1();
- else
- SEND0();
- }
- }
- unsigned char Read_byte(void)
- {
- unsigned char i,temp=0;
- for(i=0;i<8;i++)
- {
- SDA=1;
- SCL=1;
- DELAY(1);
- if(SDA==1)
- {
- temp=temp<<1;
- temp=temp|0x01;
- }
- else
- temp=temp<<1;
- SCL=0;
- }
- return temp;
- }
- /************************************
- EEPROM DRIVE
- Addr:from 0x00-->
- *************************************/
- unsigned char rdeeprom(unsigned char addr)
- {
- unsigned char temp=0;
- bit flag=0;
- IICStart();
- Write_byte(0xa0);
- Check_Ack();
- Write_byte(addr);
- Check_Ack();
- IICStart();
- Write_byte(0xa1);
- Check_Ack();
- temp=Read_byte();
- SEND1();
- IICStop();
- return temp;
- }
-
-
- void wrteeprom(unsigned char addr,unsigned char dat)
- {
- IICStart();
- Write_byte(0xa0);
- Check_Ack();
- Write_byte(addr);
- Check_Ack();
- Write_byte(dat);
- Check_Ack();
- IICStop();
- }
- void Delay1(uint j)
- {
- uchar i;
- for(;j>0;j--)
- {
- for(i=0;i<27;i++);
- }
- }
- void Delay_10us(void)
- {
- uchar i;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- }
- void COM(void)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- U8FLAG=2;
- while((!DATA)&&U8FLAG++);
- Delay_10us();
- Delay_10us();
- Delay_10us();
- U8temp=0;
- if(DATA)U8temp=1;
- U8FLAG=2;
- while((DATA)&&U8FLAG++);
- //超時則跳出for循環
- if(U8FLAG==1)break;
- //判斷數據位是0還是1
-
- // 如果高電平高過預定0高電平值則數據位為 1
-
- U8comdata<<=1;
- U8comdata|=U8temp; //0
- }//rof
- }
- //--------------------------------
- //-----溫濕度讀取子程序 ------------
- //--------------------------------
- //----以下變量均為全局變量--------
- //----溫度高8位== U8T_data_H------
- //----溫度低8位== U8T_data_L------
- //----濕度高8位== U8RH_data_H-----
- //----濕度低8位== U8RH_data_L-----
- //----校驗 8位 == U8checkdata-----
- //----調用相關子程序如下----------
- //---- Delay();, Delay_10us();,COM();
- //--------------------------------
- uchar RH(void)
- {
- //主機拉低18ms
- DATA=0;
- Delay1(180); //原來為5
- DATA=1;
- //總線由上拉電阻拉高 主機延時20us
- Delay_10us();
- Delay_10us();
- Delay_10us();
- Delay_10us();
- //主機設為輸入 判斷從機響應信號
- DATA=1;
- //判斷從機是否有低電平響應信號 如不響應則跳出,響應則向下運行
- if(!DATA) //T !
- {
- U8FLAG=2;
- //判斷從機是否發出 80us 的低電平響應信號是否結束
- while((!DATA)&&U8FLAG++);
- U8FLAG=2;
- //判斷從機是否發出 80us 的高電平,如發出則進入數據接收狀態
- while((DATA)&&U8FLAG++);
- //數據接收狀態
- COM();
- U8RH_data_H_temp=U8comdata;
- COM();
- U8RH_data_L_temp=U8comdata;
- COM();
- U8T_data_H_temp=U8comdata;
- COM();
- U8T_data_L_temp=U8comdata;
- COM();
- U8checkdata_temp=U8comdata;
- DATA=1;
- //數據校驗
- U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
- if(U8temp==U8checkdata_temp)
- {
- U8RH_data_H=U8RH_data_H_temp;
- U8RH_data_L=U8RH_data_L_temp;
- U8T_data_H=U8T_data_H_temp;
- U8T_data_L=U8T_data_L_temp;
- U8checkdata=U8checkdata_temp;
- }
- return 1;
- }
- else //傳感器不響應
- {
- return 0;
- }
- }
- /********************************************************************
- * 文件名 : 液晶1602顯示.c
- * 描述 : 該程序實現了對液晶1602的控制。
- ***********************************************************************/
- /********************************************************************
- * 名稱 : delay()
- * 功能 : 延時,延時時間大概為140US。
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void delay()
- {
- int i,j;
- for(i=0; i<=10; i++)
- for(j=0; j<=2; j++);
- }
-
- /********************************************************************
- * 名稱 : enable(uchar del)
- * 功能 : 1602命令函數
- * 輸入 : 輸入的命令值
- * 輸出 : 無
- ***********************************************************************/
- void enable(uchar del)
- {
- P0 = del;
- RS = 0;
- E = 1;
- delay();
- E = 0;
- delay();
- }
- /********************************************************************
- * 名稱 : write(uchar del)
- * 功能 : 1602寫數據函數
- * 輸入 : 需要寫入1602的數據
- * 輸出 : 無
- ***********************************************************************/
- void write(uchar del)
- {
- P0 = del;
- RS = 1;
- E = 1;
- delay();
- E = 0;
- delay();
- }
- /********************************************************************
- * 名稱 : L1602_init()
- * 功能 : 1602初始化,請參考1602的資料
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void L1602_init(void)
- {
-
- enable(0x38);
- enable(0x0c);
- enable(0x06);
- enable(0x01); //清屏要放在最后
- }
- /********************************************************************
- * 名稱 : L1602_char(uchar hang,uchar lie,char sign)
- * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符顯示"b" ,調用該函數如下
- L1602_char(1,5,'b')
- * 輸入 : 行,列,需要輸入1602的數據
- * 輸出 : 無
- ***********************************************************************/
- void L1602_char(uchar hang,uchar lie,char sign)
- {
- uchar a;
- if(hang == 1) a = 0x80;
- if(hang == 2) a = 0xc0;
- a = a + lie - 1;
- enable(a);
- write(sign);
- }
- /********************************************************************
- * 名稱 : L1602_string(uchar hang,uchar lie,uchar *p)
- * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調用該函數如下
- L1602_string(1,5,"ab cd ef;")
- * 輸入 : 行,列,需要輸入1602的數據
- * 輸出 : 無
- ***********************************************************************/
- void L1602_string(uchar hang,uchar lie,uchar *p)
- {
- uchar a;
- if(hang == 1) a = 0x80;
- if(hang == 2) a = 0xc0;
- a = a + lie - 1;
- enable(a);
- while(1)
- {
- if(*p == '\0') break;
- write(*p);
- p++;
- }
- }
- //顯示整型的溫濕度數據用,共占用4位,其中一位符號位
- void L1602_int(uchar hang, uchar lie, int num)
- {
- uint temp;
- uint gewei,shiwei,baiwei,sign;
- if (num >= 0)
- sign = 0;
- else
- sign = 1;
- temp = abs(num);
- baiwei = temp / 100;
- temp = temp - baiwei*100;
- shiwei = temp / 10;
- gewei = temp - shiwei*10;
- num = abs(num);
- if (num>=100)
- {
- // L1602_char(hang, lie+1, baiwei+48);
- L1602_char(hang, lie+2, shiwei+48);
- L1602_char(hang, lie+3, gewei+48);
- }
- else if (num>=10)
- {
- if (sign == 1)
- L1602_char(hang, lie+1, '-');
- L1602_char(hang, lie+2, shiwei+48);
- L1602_char(hang, lie+3, gewei+48);
- }
- else
- {
- if (sign == 1)
- L1602_char(hang, lie+2, '-');
- else
- L1602_char(hang, lie+2, ' ');
- L1602_char(hang, lie+3, gewei+48);
- }
- }
- void display()
- {
- if(Mode==0)
- {
- L1602_int(1,3,temperature);
- L1602_char(1,7,0xdf);
- L1602_int(1,12,humidity);
- if(hot==1&&cold==0&&humid==0&&dry==0)
- {L1602_string(2,1," It's very hot! ");BJ=1;}
- else if(hot==1&&cold==0&&humid==1&&dry==0)
- {L1602_string(2,1," Hot and humid! ");BJ=1;}
- else if(hot==1&&cold==0&&humid==0&&dry==1)
- {L1602_string(2,1," Hot and dry! ");BJ=1;}
- else if(hot==0&&cold==1&&humid==0&&dry==0)
- {L1602_string(2,1," It's very cold!");BJ=1;}
- else if(hot==0&&cold==1&&humid==1&&dry==0)
- {L1602_string(2,1," Cold and humid!");BJ=1;}
- else if(hot==0&&cold==1&&humid==0&&dry==1)
- {L1602_string(2,1," Cold and dry! ");BJ=1;}
- else if(hot==0&&cold==0&&humid==1&&dry==0)
- {L1602_string(2,1,"It's very humid!");BJ=1;}
- else if(hot==0&&cold==0&&humid==0&&dry==1)
- {L1602_string(2,1," It's very dry! ");BJ=1;}
- else if(hot==0&&cold==0&&humid==0&&dry==0)
- {L1602_string(2,1,"Good environment");BJ=0;}
- }
- }
- /***按鍵函數***/
- void KEY()
- {
- if(Key_SET==0)
- {
- Delay1(200);
- if(Key_SET==0)
- {
- Mode++;
- if(Mode==1)
- {
- L1602_string(1,1," TH: C HH: %");
- L1602_char(1,8,0xdf);
- L1602_string(2,1," TL: C HL: %");
- L1602_char(2,8,0xdf);
- L1602_int(1,4,TH);
- L1602_int(1,12,HH);
- L1602_int(2,4,TL);
- L1602_int(2,12,HL);
- enable(0x80+6);
- enable(0x0f);
- }
- else if(Mode==2)
- {
- enable(0x80+0x40+6);
- enable(0x0f);
- }
- else if(Mode==3)
- {
- enable(0x80+14);
- enable(0x0f);
- }
- else if(Mode==4)
- {
- enable(0x80+0x40+14);
- enable(0x0f);
- }
- else if(Mode>=5)
- {
- Mode=1;
- enable(0x80+6);
- enable(0x0f);
- }
- while(!Key_SET);
- }
- }
- else if(Key_ADD==0)
- {
- Delay1(200);
- if(Key_ADD==0)
- {
- if(Mode==1)
- {
- TH++;
- if(TH>=100)
- TH=99;
- L1602_int(1,4,TH);
- enable(0x80+6);
- }
- else if(Mode==2)
- {
- TL++;
- if(TL>=TH)
- TL=TH-1;
- L1602_int(2,4,TL);
- enable(0x80+0x40+6);
- }
- else if(Mode==3)
- {
- HH++;
- if(HH>=100)
- HH=99;
- L1602_int(1,12,HH);
- enable(0x80+14);
- }
- else if(Mode==4)
- {
- HL++;
- if(HL>=HH)
- HL=HH-1;
- L1602_int(2,12,HL);
- enable(0x80+0x40+14);
- }
- while(!Key_ADD);
- }
- }
- else if(Key_SUB==0)
- {
- Delay1(200);
- if(Key_SUB==0)
- {
- if(Mode==1)
- {
- TH--;
- if(TH<=TL)
- TH=TL+1;
- L1602_int(1,4,TH);
- enable(0x80+6);
- }
- else if(Mode==2)
- {
- TL--;
- if(TL<=0)
- TL=0;
- L1602_int(2,4,TL);
- enable(0x80+0x40+6);
- }
- else if(Mode==3)
- {
- HH--;
- if(HH<=HL)
- HH=HL+1;
- L1602_int(1,12,HH);
- enable(0x80+14);
- }
- else if(Mode==4)
- {
- HL--;
- if(HL<=0)
- HL=0;
- L1602_int(2,12,HL);
- enable(0x80+0x40+14);
- }
- while(!Key_SUB);
- }
- }
- if(Key_OK==0&&Mode!=0)
- {
- Delay1(200);
- if(Key_OK==0)
- {
- L1602_string(1,1,"Tem: C Hum: %");
- L1602_string(2,1,"Good environment");
- Mode=0;
- wrteeprom(0,TH);
- Delay1(20);
- wrteeprom(1,TL);
- Delay1(20);
- wrteeprom(2,HH);
- Delay1(20);
- wrteeprom(3,HL);
- enable(0x0c);
- while(Key_OK==0);
- }
- }
- }
- //數據初始化
- void Data_Init()
- {
- Led_qushi = 1;
- Led_jiashi=1;
- Led_jiangwen = 1;
- Led_shengwen = 1;
- }
- /********************************************************************
- * 名稱 : Main()
- * 功能 : 主函數
- ***********************************************************************/
- void main()
- {
- uint i, j, testnum;
- EA = 0;
- Timer0_Init();
- Data_Init();
- EA = 1;
- L1602_init();
- L1602_string(1,1," Welcome to T&H ");
- L1602_string(2,1," Control System!");
- for (i=0;i<1000;i++)
- for (j=0;j<1000;j++)
- {;}
-
- L1602_string(1,1," ");
- L1602_string(2,1," ");
- L1602_string(1,1,"Tem: C Hum: %");
- L1602_string(2,1,"Good environment");
-
-
- TH=rdeeprom(0);
- Delay1(20);
- TL=rdeeprom(1);
- Delay1(20);
- HH=rdeeprom(2);
- Delay1(20);
- HL=rdeeprom(3);
- while(1)
- {
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
下載:
溫濕度.rar
(1.19 MB, 下載次數: 44)
2018-4-1 11:31 上傳
點擊文件名下載附件
|
評分
-
查看全部評分
|