基于51单片机的智能晾衣架

资料下载地址:基于51单片机智能晾衣架

一、项目功能

1、实时测量DHT11温湿度传感器的数据并在LCD1602液晶屏上显示

2、实时检测光照强度传感器的数据并在LCD1602液晶屏上显示

3、无线遥控模块可以控制晾衣架分为自动模式和手动模式

自动模式下:当光照强度、温湿度在一定范围内时,电机正传,否则电机反转,实现自动晾衣和收回。

手动模式下:可以遥控电机正传,反转。实现手动晾衣和收回。

二、原理图

三、仿真图

 自动模式界面

扫描二维码关注公众号,回复: 13827026 查看本文章

手动模式界面

 四、实物照片

 五、程序

/*******************************************************************************
* 函 数 名         : 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(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,否则为0
      dat<<=1;           //移位使正确接收8位数据,数据为0时直接移位
      if(Data==1)    //数据为1时,使dat加1来接收数据1
         dat+=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);  //拉高后延时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);    //结束

        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 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();//报警函数
                    }
            }

		}

}

/******************************************************
 ** 函数名:init_all_hardware
 ** 描述  :初始化所有硬件,及其变量参数。
 ** 输入  :无
 ** 输出  :无
 ** 调用  :主程序
 ******************************************************/
void init_all_hardware(void)
{
   		 
		time_init();//定时器初始化
		lcd_init();
		lcd_write_char(1,2,humi_value);
		lcd_write_char(1,11,temp_value);
		wri_string(2,0,"Light:High  Auto");
		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_handle();
		
		 time_service();//时间处理函数
		 Get_Light();
	 }
}

猜你喜欢

转载自blog.csdn.net/qq_35654286/article/details/124225709