基于51單片機(jī)的蔬菜大棚溫濕度智能控制系統(tǒng)設(shè)計(jì)模塊使用:使用dht11、74hc595數(shù)碼管模塊、繼電器模塊
任務(wù)1)根據(jù)檢測(cè)到的溫濕度信息控制通風(fēng)與加熱; 2)采用MCU、溫濕度傳感器、繼電器、按鍵、數(shù)碼管等; 3)通過按鍵設(shè)定大棚溫濕度報(bào)警值; 4)上傳信息到PC機(jī); 5)當(dāng)溫度或適度超限時(shí)用繼電器控制小燈狀態(tài)模擬相應(yīng)動(dòng)作的發(fā)生。
230204B72FC083DD0A1F32DEA2FF975A.jpg (84.27 KB, 下載次數(shù): 51)
下載附件
2019-11-25 19:01 上傳
51.png (111.38 KB, 下載次數(shù): 46)
下載附件
2019-11-25 19:11 上傳
單片機(jī)源程序如下:
- ////////////////////////////////////////////////////10.3 17:58////////////////////////////////////////////////////////
- #include <reg52.h> //包含頭文件,一般情況不需要改動(dòng),頭文件包含特殊功能寄存器的定義
- #include <intrins.h>
- #include <math.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit RS = P1^0; //定義端口
- sbit RW = P1^1;
- sbit EN = P2^5;
- sbit DU = P2^0;
- sbit WE = P2^1;
- sbit Data = P3^6;//定義數(shù)據(jù)線
- uchar rec_dat[19]; //用于顯示的接收數(shù)據(jù)數(shù)組
-
- #define RS_CLR RS=0
- #define RS_SET RS=1
-
- #define RW_CLR RW=0
- #define RW_SET RW=1
-
- #define EN_CLR EN=0
- #define EN_SET EN=1
-
- #define DataPort P0
-
-
- void cmg88()//關(guān)數(shù)碼管,點(diǎn)陣函數(shù)
- {
- DU=1;
- P0=0X00;
- DU=0;
- }
- /*------------------------------------------------
- uS延時(shí)函數(shù),含有輸入?yún)?shù) unsigned char t,無返回值
- unsigned char 是定義無符號(hào)字符變量,其值的范圍是
- 0~255 這里使用晶振12M,精確延時(shí)請(qǐng)使用匯編,大致延時(shí)
- 長度如下 T=tx2+5 uS
- ------------------------------------------------*/
- void DelayUs2x(unsigned char t)
- {
- while(--t);
- }
- /*------------------------------------------------
- mS延時(shí)函數(shù),含有輸入?yún)?shù) unsigned char t,無返回值
- unsigned char 是定義無符號(hào)字符變量,其值的范圍是
- 0~255 這里使用晶振12M,精確延時(shí)請(qǐng)使用匯編
- ------------------------------------------------*/
- void DelayMs(unsigned char t)
- {
-
- while(t--)
- {
- //大致延時(shí)1mS
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- // 判忙函數(shù)
- bit LCD_Check_Busy(void)
- {
- DataPort= 0xFF;
- RS_CLR;
- RW_SET;
- EN_CLR;
- _nop_();
- EN_SET;
- return (bit)(DataPort & 0x80);
- }
- // 寫入命令函數(shù)
- void LCD_Write_Com(unsigned char com)
- {
- while(LCD_Check_Busy()); //忙則等待
- RS_CLR;
- RW_CLR;
- EN_SET;
- DataPort= com;
- _nop_();
- EN_CLR;
- }
- // 寫入數(shù)據(jù)函數(shù)
- void LCD_Write_Data(unsigned char Data)
- {
- while(LCD_Check_Busy()); //忙則等待
- RS_SET;
- RW_CLR;
- EN_SET;
- DataPort= Data;
- _nop_();
- EN_CLR;
- }
-
- // 清屏函數(shù)
- void LCD_Clear(void)
- {
- LCD_Write_Com(0x01);
- DelayMs(5);
- }
- // 寫入字符串函數(shù)
- void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
- {
- if (y == 0)
- {
- LCD_Write_Com(0x80 + x); //表示第一行
- }
- else
- {
- LCD_Write_Com(0xC0 + x); //表示第二行
- }
- while (*s)
- {
- LCD_Write_Data( *s);
- s ++;
- }
- }
- // 寫入字符函數(shù)
- void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
- {
- if (y == 0)
- {
- LCD_Write_Com(0x80 + x);
- }
- else
- {
- LCD_Write_Com(0xC0 + x);
- }
- LCD_Write_Data( Data);
- }
- // 初始化函數(shù)
- void LCD_Init(void)
- {
- LCD_Write_Com(0x38); /*顯示模式設(shè)置*/
- DelayMs(5);
- LCD_Write_Com(0x38);
- DelayMs(5);
- LCD_Write_Com(0x38);
- DelayMs(5);
- LCD_Write_Com(0x38);
- LCD_Write_Com(0x08); /*顯示關(guān)閉*/
- LCD_Write_Com(0x01); /*顯示清屏*/
- LCD_Write_Com(0x06); /*顯示光標(biāo)移動(dòng)設(shè)置*/
- DelayMs(5);
- LCD_Write_Com(0x0C); /*顯示開及光標(biāo)設(shè)置*/
- }
-
-
- /*------------------------------------------------
- DHT11延時(shí)函數(shù)
- ------------------------------------------------*/
- void DHT11_delay_us(uchar n)
- {
- while(--n);
- }
-
- void DHT11_delay_ms(uint z)
- {
- uint i,j;
- for(i=z;i>0;i--)
- for(j=110;j>0;j--);
- }
- /*------------------------------------------------
- DHT11開始信號(hào)
- ------------------------------------------------*/
- void DHT11_start()
- {
- Data=1;
- DHT11_delay_us(2);
- Data=0;
- DHT11_delay_ms(20); //延時(shí)18ms以上
- Data=1;
- DHT11_delay_us(30);
- }
- // 接收八位二進(jìn)制
- uchar DHT11_rec_byte() //接收一個(gè)字節(jié)
- {
- uchar i,dat=0;
- for(i=0;i<8;i++) //從高到低依次接收8位數(shù)據(jù)
- {
- while(!Data); ////等待50us低電平過去
- DHT11_delay_us(8); //延時(shí)60us,如果還為高則數(shù)據(jù)為1,否則為0
- dat<<=1; //移位使正確接收8位數(shù)據(jù),數(shù)據(jù)為0時(shí)直接移位
- if(Data==1) //數(shù)據(jù)為1時(shí),使dat加1來接收數(shù)據(jù)1
- dat+=1;
- while(Data); //等待數(shù)據(jù)線拉低
- }
- return dat;
- }
- // 接收40bit數(shù)據(jù)
- void DHT11_receive() //接收40位的數(shù)據(jù)
- {
- uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
- DHT11_start();
-
- if(Data==0)
- {
-
- while(Data==0); //等待拉高
-
- DHT11_delay_us(40); //拉高后延時(shí)80us
- R_H=DHT11_rec_byte(); //接收濕度高八位
- R_L=DHT11_rec_byte(); //接收濕度低八位
- T_H=DHT11_rec_byte(); //接收溫度高八位
- T_L=DHT11_rec_byte(); //接收溫度低八位
- revise=DHT11_rec_byte(); //接收校正位
-
- DHT11_delay_us(25); //結(jié)束
-
- if((R_H+R_L+T_H+T_L)==revise) //校正
- {
- RH=R_H;
- RL=R_L;
- TH=T_H;
- TL=T_L;
- }
- /*數(shù)據(jù)處理,方便顯示*/
- rec_dat[0]='0'+(RH/10);
- rec_dat[1]='0'+(RH%10);
- rec_dat[2] =' ';
- rec_dat[3] = 'R' ;
- rec_dat[4] = 'H';
- rec_dat[5]=' ';
- rec_dat[6]=' ';
- rec_dat[7]=' ';
- rec_dat[8]=' ';
- rec_dat[9]='0'+(TH/10);
- rec_dat[10]='0'+(TH%10);
- rec_dat[11] =' ';
- rec_dat[12] = 'C';
- rec_dat[13] = ' ' ;
- rec_dat[14]=' ';
- rec_dat[15] =(RH/10);
- rec_dat[16] =(RH%10);
- rec_dat[17] =(TH/10) ;
- rec_dat[18]=(TH%10);
- }
- }
- /////////////////數(shù)碼管///////////////////////////////////////////////
-
-
- unsigned char code fseg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- unsigned char code segbit[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
- unsigned char disbuf[8]={0,0,0,0,0,0,0,0};
- unsigned char code LED_0F[]; // LED字模表
- sbit DIO = P1^0; //串行數(shù)據(jù)輸入
- sbit rclck = P1^1; //時(shí)鐘脈沖信號(hào)——上升沿有效
- sbit SCLK = P1^2; //打入信號(hào)————上升沿有效
- //-----------------------------------------------------------------------------
- // 全局變量
- uchar LED[8]; //用于LED的8位顯示緩存
-
- unsigned char code LED_0F[] =
- {// 0 1 2 3 4 5 6 7 8 9 A b C d E F -
- 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0xFF,0xbf
- };
- void LED_OUT(uchar X)
- {
- uchar i;
- for(i=8;i>=1;i--)
- {
- if (X&0x80) DIO=1; else DIO=0;
- X<<=1;
- SCLK = 0;
- SCLK = 1;
- }
- }
- void LED8_Display (void)
- {
- unsigned char code *led_table; // 查表指針
- uchar i;
- //顯示第1位
- led_table = LED_0F + LED[0];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x01);
- rclck = 0;
- rclck = 1;
- //顯示第2位
- led_table = LED_0F + LED[1];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x02);
- rclck = 0;
- rclck = 1;
- //顯示第3位
- led_table = LED_0F + LED[2];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x04);
- rclck = 0;
- rclck = 1;
- //顯示第4位
- led_table = LED_0F + LED[3];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x08);
- rclck = 0;
- rclck = 1;
- led_table = LED_0F + LED[4];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x10);
- rclck = 0;
- rclck = 1;
-
- //顯示第6位
- led_table = LED_0F + LED[5];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x20);
- rclck = 0;
- rclck = 1;
- //顯示第7位
- led_table = LED_0F + LED[6];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x40);
- rclck = 0;
- rclck = 1;
- //顯示第8位
- led_table = LED_0F + LED[7];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x80);
- rclck = 0;
- rclck = 1;
- }
-
-
- void LED2_Display (uchar *wei)
- {
- unsigned char code *led_table; // 查表指針
- uchar i;
- if(wei==1)
- {
- //顯示第1位
- led_table = LED_0F + LED[0];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x01);
- rclck = 0;
- rclck = 1;
- //顯示第2位
- led_table = LED_0F + LED[1];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x02);
- rclck = 0;
- rclck = 1;
- }
- if(wei==2)
- {
- //顯示第3位
- led_table = LED_0F + LED[2];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x04);
- rclck = 0;
- rclck = 1;
- //顯示第4位
- led_table = LED_0F + LED[3];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x08);
- rclck = 0;
- rclck = 1;
- }
- if(wei==3)
- {
- led_table = LED_0F + LED[4];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x10);
- rclck = 0;
- rclck = 1;
-
- //顯示第6位
- led_table = LED_0F + LED[5];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x20);
- rclck = 0;
- rclck = 1;
- }
- if(wei==4)
- {
- //顯示第7位
- led_table = LED_0F + LED[6];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x40);
- rclck = 0;
- rclck = 1;
- //顯示第8位
- led_table = LED_0F + LED[7];
- i = *led_table;
- LED_OUT(i);
- LED_OUT(0x80);
- rclck = 0;
- rclck = 1;
- }
- }
- uchar wendu;
- uchar shidu;
- void shumaguan_show(void)
- {
- LED[1]=rec_dat[15];
- LED[0]=rec_dat[16];
- shidu=rec_dat[15]*10+rec_dat[16];
- LED[7]=rec_dat[17];
- LED[6]=rec_dat[18];
- wendu=rec_dat[17]*10+rec_dat[18];
- LED[2]=16;
- LED[3]=16;
- LED[4]=16;
- LED[5]=16;
- LED8_Display ();
-
- }
- //////////////////////////////////////////////////////////////////////////
- sbit Beep=P2^2; //設(shè)置蜂鳴器引腳
- sbit K1=P2^3;
- sbit K2=P2^4;
- sbit K3=P2^5;
- sbit K4=P2^6;
- sbit K5=P2^7;
- void key_init(void)
- {
- K1=1;
- K2=1;
- K3=1;
- K4=1;
- }
- uchar an=0;
- uchar move=0;
- void caidan(void)
- {
- if(K1==0&&an==0)
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K1); // 等待按鍵釋放
- DelayMs(10); // 去除按鍵松開的抖動(dòng)
- an=1;
-
- }
- if(K1==0&&an==1)
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K1); // 等待按鍵釋放
- DelayMs(10); // 去除按鍵松開的抖動(dòng)
- an=0;
- }
- }
- void move_2(void)
- {
- if(K2==0&&move==0)
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K2); // 等待按鍵釋放
- DelayMs(10); // 去除按鍵松開的抖動(dòng)
- move=1;
- }
-
- if(K2==0&&move==1)
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K2); // 等待按鍵釋放
- DelayMs(10); // 去除按鍵松開的抖動(dòng)
- move=2;
- }
- if(K2==0&&move==2)
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K2); // 等待按鍵釋放
- DelayMs(10); // 去除按鍵松開的抖動(dòng)
- move=3;
- }
- if(K2==0&&move==3)
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K2); // 等待按鍵釋放
- DelayMs(10); // 去除按鍵松開的抖動(dòng)
- move=0;
- }
-
- }
- uchar AlarmTL; // 溫度下限報(bào)警值
- uchar AlarmTH; // 溫度上限報(bào)警值
- uchar AlarmHL; // 濕度下限報(bào)警值
- uchar AlarmHH; // 濕度上限報(bào)警值
- void up_down(void)
- {
- ///////////////////////////////////////////////////////////////////////////////////////////////////////
- if(K4==0&&move==0)
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K4); // 等待按鍵釋放
- DelayMs(10); // 去除按鍵松開的抖動(dòng)
- if(AlarmTL>0) // 只有當(dāng)濕度上限值大于0時(shí),才能減1
- {
- AlarmTL--;
-
-
- }
- }
- if(K3==0&&move==0) // 判斷 “加按鍵“ 是否被按下
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K3); // 等待按鍵釋放
- DelayMs(10);
- if(AlarmTL<99) // 只有當(dāng)濕度上限值小于99時(shí),才能加1
- AlarmTL++;
-
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////
- if(K4==0&&move==1)
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K4); // 等待按鍵釋放
- DelayMs(10); // 去除按鍵松開的抖動(dòng)
- if(AlarmTH>0) // 只有當(dāng)濕度上限值大于0時(shí),才能減1
- {
- AlarmTH--;
-
-
- }
- }
- if(K3==0&&move==1) // 判斷 “加按鍵“ 是否被按下
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K3); // 等待按鍵釋放
- DelayMs(10);
- if(AlarmTH<99) // 只有當(dāng)濕度上限值小于99時(shí),才能加1
- AlarmTH++;
-
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////
- if(K4==0&&move==2)
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K4); // 等待按鍵釋放
- DelayMs(10); // 去除按鍵松開的抖動(dòng)
- if(AlarmHL>0) // 只有當(dāng)濕度上限值大于0時(shí),才能減1
- {
- AlarmHL--;
-
-
- }
- }
- if(K3==0&&move==2) // 判斷 “加按鍵“ 是否被按下
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K3); // 等待按鍵釋放
- DelayMs(10);
- if(AlarmHL<99) // 只有當(dāng)濕度上限值小于99時(shí),才能加1
- AlarmHL++;
-
- }
- ///////////////////////////////////////////////////////////////////////////////////////////
- if(K4==0&&move==3)
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K4); // 等待按鍵釋放
- DelayMs(10); // 去除按鍵松開的抖動(dòng)
- if(AlarmHH>0) // 只有當(dāng)濕度上限值大于0時(shí),才能減1
- {
- AlarmHH--;
-
-
- }
- }
- if(K3==0&&move==3) // 判斷 “加按鍵“ 是否被按下
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K3); // 等待按鍵釋放
- DelayMs(10);
- if(AlarmHH<99) // 只有當(dāng)濕度上限值小于99時(shí),才能加1
- AlarmHH++;
-
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////////
- }
- uchar TAB[8]={0x00,0x00,0x00,0x00,0x00};
- void send(uchar dat)
- {
- SBUF=dat;
- while(TI==0);
- TI=0;
- }
- sbit LED1=P0^6;
- sbit LED2=P0^7;
- sbit LED3=P0^4;
- sbit LED4=P0^5;
- void panduan(void)
- {
- if(wendu<AlarmTL)
- {
- LED1=0;
- Beep=0;
- DelayMs(2);
- Beep=1;
- }
- if(wendu>AlarmTL)
- {
- LED1=1;
- Beep=1;
- }
- if(wendu>AlarmTH)
- {
- LED2=0;
- Beep=0;
- DelayMs(2);
- Beep=1;
- }
- if(wendu<AlarmTH)
- {
- LED2=1;
- Beep=1;
- }
- if(shidu<AlarmHL)
- {
- LED3=0;
- Beep=0;
- DelayMs(2);
- Beep=1;
- }
- if(shidu>AlarmHL)
- {
- LED3=1;
- Beep=1;
- }
- if(shidu>AlarmHH)
- {
- LED4=0;
- Beep=0;
- DelayMs(2);
- Beep=1;
- }
- if(shidu<AlarmHH)
- {
- LED4=1;
- Beep=1;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- /*------------------------------------------------
- 主函數(shù)
- ------------------------------------------------*/
- void main(void)
- {
- uchar i;
- TMOD=0X20;
- SCON=0X40;
- PCON=0X00;
- TH1=0xfd;
- TL1=0xfd;
- TR1=1;
- key_init();
- AlarmTL=15;
- AlarmTH=50;
- AlarmHL=15;
- AlarmHH=50;
- DHT11_delay_ms(1000); //DHT11上電后要等待1S以越過不穩(wěn)定狀態(tài)在此期間不能發(fā)送任何指令
- P0=0xff;
- while (1)
- {
- caidan();
- if(an==0)
- {
- DHT11_receive();
- shumaguan_show();
- panduan();
- }
- if(an==1)
- {
- Beep=1;
- DelayMs(10);
- move_2(); //2位右移
- up_down();
- LED[1]=AlarmHH/10;// 濕度上限報(bào)警
- LED[0]=AlarmHH%10;
- LED[2]=AlarmHL%10; // 濕度下限報(bào)警
- LED[3]=AlarmHL/10;
- LED[7]=AlarmTL/10; // 溫度下限報(bào)警
- LED[6]=AlarmTL%10;
- LED[4]=AlarmTH%10;// 溫度上限報(bào)警
- LED[5]=AlarmTH/10;
-
- if(move==0) LED2_Display (4);
- if(move==1) LED2_Display (3);
- if(move==2) LED2_Display (2);
- if(move==3) LED2_Display (1);
- }
- if(K5==0)
- {
- DelayMs(10); // 去除按鍵按下的抖動(dòng)
- while(!K5); // 等待按鍵釋放
- DelayMs(10);
- TAB[0]=rec_dat[15];
- TAB[1]=rec_dat[16];
- TAB[2]=rec_dat[17];
- TAB[3]=rec_dat[18];
- TAB[4]=0x00;
- for(i=0;i<4;i++)
- {
- send(TAB[i]);
- DelayMs(200);
- }
- }
-
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
基于單片機(jī)的蔬菜大棚溫濕度智能控制系統(tǒng)設(shè)計(jì).rar
(708.89 KB, 下載次數(shù): 279)
2019-11-25 19:01 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|