當前位置:
首頁 >
基于51单片机的智能窗帘设计
發布時間:2024/3/13
25
豆豆
生活随笔
收集整理的這篇文章主要介紹了
基于51单片机的智能窗帘设计
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、項目功能概述
1、使用DHT11獲取溫濕度
2、使用光照強度傳感器檢測環境光照
3、通過紅外遙控器切換自動模式和手動模式。
????????自動模式時,當環境中濕度小于60%、溫度大于20、光照強烈時,電機自動轉動。
????????手動模式時,通過遙控器控制電機啟動或停止。
4、LCD1602顯示相關數據
資料下載地址:基于51單片機智能窗簾設計
二、仿真圖片
自動模式
手動模式
?
三、程序
/******************************************************************************* * 函 數 名 : 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 工作方式為1TH0 = 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);//選中地址elselcd_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);//選中地址elselcd_wri_com(0xc0+x);//選中地址temp_l = dat % 10;temp_h = dat / 10;lcd_wri_data(temp_h + 0x30); //convert to asciilcd_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);elselcd_wri_com(0xc0+x);//將光標移動到秒個位lcd_wri_com(0x0f);//顯示光標并且閃爍}else{if(y==1)//如果選擇第一行lcd_wri_com(0x80+x);elselcd_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);//延時5mslcd_wri_com(0x01); //清屏wri_string(2,0,times);//初始化顯示wri_string(2,6,date);wri_string(1,0,"H: %RH T: C ");//初始化顯示 } void DHT11_delay_us(unsigned char n) {while(--n); }void DHT11_delay_ms(unsigned int z) {unsigned int i,j;for(i=z;i>0;i--)for(j=110;j>0;j--); }void DHT11_start() {Data=1;DHT11_delay_us(2);Data=0;DHT11_delay_ms(30); //延時18ms以上Data=1;DHT11_delay_us(30); }unsigned char DHT11_rec_byte() //接收一個字節 {unsigned char i,dat=0;for(i=0;i<8;i++) //從高到低依次接收8位數據{while(!Data); 等待50us低電平過去DHT11_delay_us(8); //延時60us,如果還為高則數據為1,否則為0dat<<=1; //移位使正確接收8位數據,數據為0時直接移位if(Data==1) //數據為1時,使dat加1來接收數據1dat+=1;while(Data); //等待數據線拉低}return dat; }void DHT11_receive() //接收40位的數據 {unsigned char 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); //拉高后延時80usR_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); //結束if((R_H+R_L+T_H+T_L)==revise) //校正{RH=R_H;RL=R_L;TH=T_H;TL=T_L;}humi_value = RH;temp_value = TH;} }void AlarmJudge(void) { // if(temp_value>AlarmTH)// 溫度是否過高 // { // LedTH_P=0; // LedTL_P=1; // } // else if(temp_value<AlarmTL)// 溫度是否過低 // { // LedTL_P=0; // LedTH_P=1; // } // else// 溫度正常 // { // LedTH_P=1; // LedTL_P=1; // }if(humi_value>AlarmHH)// 濕度是否過高{LedHH_P=0;LedHL_P=1;}else if(humi_value<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(20); // beep=1; // delay_ms(20); // } // } }void key_handle(void) {if(key_value == 1){mode = 0;wri_string(2,12,"Auto");//初始化顯示}if(key_value == 2){mode = 1;wri_string(2,12,"Manu");//初始化顯示}if(key_value == 3){if(motor_mode == 0){motor_mode = 1;}else{motor_mode = 0;}}}/******************************************************** 函數名: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(2,0,times);//初始化顯示wri_string(2,6,date);wri_string(2,0," ");//初始化顯示wri_string(1,0,"H: %RH T: C ");//初始化顯示lcd_write_char(1,2,humi_value);lcd_write_char(1,11,temp_value); // 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 (++cnt_500ms>5){cnt_500ms = 0;if(now_window == normal_mode){EA = 0;DHT11_receive();EA = 1;lcd_write_char(1,2,humi_value);lcd_write_char(1,11,temp_value);AlarmJudge();//報警函數}}}} void main(void) {init_all_hardware();//初始化硬件,IO和定時器while(1){key_scan();//按鍵掃描key_handle();time_service();//時間處理函數Get_Light();} }總結
以上是生活随笔為你收集整理的基于51单片机的智能窗帘设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spark系列十七:经典案列使用直连的方
- 下一篇: C 宏定义实现字符大小写转换