目录
一、项目功能
二、原理图
三、仿真图
四、实物照片
五、程序
资料下载地址:基于51单片机智能晾衣架
一、项目功能
1、实时测量DHT11温湿度传感器的数据并在LCD1602液晶屏上显示
2、实时检测光照强度传感器的数据并在LCD1602液晶屏上显示
3、无线遥控模块可以控制晾衣架分为自动模式和手动模式
自动模式下:当光照强度、温湿度在一定范围内时,电机正传,否则电机反转,实现自动晾衣和收回。
手动模式下:可以遥控电机正传,反转。实现手动晾衣和收回。
二、原理图
三、仿真图
自动模式界面
手动模式界面
四、实物照片
五、程序
部分程序
/*******************************************************************************
* 函 数 名 : 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)
{}
void key_scan(void)
{static unsigned char key_in_flag = 0;//按键按下标志unsigned char key_l;//存储扫描到行列值。
// key_value = 20;//按键值清除
// if((P3 | 0xf0) != 0xf0)//按键按下
// {
// delay_ms(1);//按键消抖动
// if(((P3 | 0xf0) != 0xf0) && (key_in_flag == 1))
// {
// key_in_flag = 0;//松手检测防止一直触发
// P3 = 0xf0;
// //delay_ms(1);//按键消抖动
// key_l = P3;//扫描得到按键值
// switch(key_l)
// {
// //获取按键值
// case 0xf1:
// {
// key_value = 1;
// }
// break;
// case 0xf2:
// {
// key_value = 2;
// }
// break;
// case 0xf4:
// {
// key_value = 3;
// }
// break;
// //case 0x70:
// //break;
// }
// }
// }
// else
// {
// key_in_flag = 1;//(按键松开标志)// }if(KEY1 == 1){delay_ms(5);if(KEY1 == 1){mode = 0;wri_string(2,12,"Auto");//初始化显示while(KEY1);}}if(KEY2 == 1){delay_ms(5);if(KEY2 == 1){mode = 1;wri_string(2,12,"Manu");//初始化显示while(KEY2);}}if(KEY3 == 1){delay_ms(5);if(KEY3 == 1){motor_direc = 0;//正转if(motor_mode == 0){motor_mode = 1;}else{motor_mode = 0;}while(KEY3);}}if(KEY4 == 1){delay_ms(5);if(KEY4 == 1){motor_direc = 1;if(motor_mode == 0){motor_mode = 1;}else{motor_mode = 0;}while(!KEY4);}}}/******************************************************** 函数名: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 main(void)
{init_all_hardware();//初始化硬件,IO和定时器while(1){key_scan();//按键扫描key_handle();time_service();//时间处理函数Get_Light();}
}