功能描述

1、采用51/52单片机作为主控芯片;
2、采用1602液晶显示:当前日期和时间、控制模式、光照强度;
3、采用DS1302时钟芯片,日期时间可调;
4、共3种模式:手动模式(Manual)、光控模式(Liging)、定时模式(Timing);
5、在手动模式下,通过按键进行开关控制,亦可通过红外遥控器控制;
6、在光控模式下,光照强度大于设置值时开窗,否则关闭;
7、在定时模式下,通过按键设置开窗帘和关窗帘的时间;
8、电机正转半圈,模拟开窗,红色LED灯点亮;
9、电机反转半圈,模拟关窗,红色LED灯熄灭。

电路设计

采用Altium Designer作为电路设计工具。Altium Designer通过把原理图设计、PCB绘制编辑、拓扑逻辑自动布线、信号完整性分析和设计输出等技术的完美融合,为设计者提供了全新的设计解决方案,使设计者可以轻松进行设计,熟练使用这一软件必将使电路设计的质量和效率大大提高。

基于单片机的智能窗系统设计(#0525)_单片机

单片机管脚说明:

P0端口(P0.0-P0.7):P0口为一个8位漏极开路双向I/O口,每个引脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。

P1端口(P1.0-P1.7):P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高电平,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。

P2端口(P2.0-P2.7):P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口,用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。

P3端口(P3.0-P3.7):P3口管脚是一个带有内部上拉电阻的8位的双向I/O端口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入端时,由于外部下拉为低电平,P3口将输出电流(ILL)。P3口同时为闪烁编程和编程校验接收一些控制信号。

仿真设计

采用Proteus作为仿真设计工具。Proteus是一款著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。

基于单片机的智能窗系统设计(#0525)_初始化_02

主程序设计

void main()
{
	uchar light;
	
	LcdInit();			// 执行液晶初始化	
	DS1302_Init();	// 时钟芯片的初始化
	LcdShowInit();	// 液晶显示内容的初始化
	io_inithw();
	int_inithw();
	if(DS1302_Read_Byte(0x81)>=128)			// 判断时钟芯片是否正在运行
	{
		DS1302_Write_Time();							// 如果没有,则初始化一个时间
	}
	
	while(1)
	{
		DS1302_Read_Time();				// 获取当前时钟芯片的时间,存在数组time_buf中
		FlashTime();							// 刷新时间显示

		light=Get_ADC0832();			// 读取光照强度
		light=light/2.5;					// 缩小光照检测结果(在0-99)
		if(light>99)							// 如果大于99
			light=99;								// 则依然保持99
		LcdGotoXY(1,14);					// 光标定位
		LcdPrintNum(light);				// 显示光照强度
		
		KeyScanf1();							// 按键扫描(时间的设置)
		KeyScanf2();							// 按键扫描(阈值的设置)
		KeyScanf3();							// 按键扫描(模式切换)
	
		/*手动控制模式*/
		if(gMode==1)
		{
			if(closeflag==1)
			{
				if(Led_P==0)			// 如果窗帘当前是打开的
				{
					closeflag=0;
					Close();				// 则光标窗帘
				}else
				closeflag=0;
			}
			if(KeyDown_P==0)		// 如果关窗帘键按下了	
			{
				if(Led_P==0)			// 如果窗帘当前是打开的
				{
					Close();				// 则光标窗帘
				}
			}
			if(openflag==1)
			{
				if(Led_P==1)			// 如果窗帘当前是关闭的
				{
					openflag=0;
					Open();					// 则打开窗帘
				}else{
					openflag=0;
				}
				
			}
			if(KeyUp_P==0)			// 如果开窗帘键按下了
			{
				if(Led_P==1)			// 如果窗帘当前是关闭的
				{
					Open();					// 则打开窗帘
				}
			}	
		}
		
		/*时间控制模式*/
		if(gMode==2)
		{
			if((TimeBuff[4]==CloseHour)&&(TimeBuff[5]==CloseMinute)&&(TimeBuff[6]==0))	// 如果到了关窗帘的时间	
			{
				if(Led_P==0)			// 如果窗帘当前是打开的
				{
					Close();				// 则光标窗帘
				}
			}
			if((TimeBuff[4]==OpenHour)&&(TimeBuff[5]==OpenMinute)&&(TimeBuff[6]==0))		// 如果到了开窗帘的时间	
			{
				if(Led_P==1)			// 如果窗帘当前是关闭的
				{
					Open();					// 则打开窗帘
				}
			}	
		}
		
		/*光线控制模式*/
		if(gMode==3)
		{
			if(light<gLight)		// 当前光线小于设置的阈值
			{
				if(Led_P==0)			// 如果窗帘当前是打开的
				{
					Close();				// 则光标窗帘
				}
			}
			else								// 当前光线大于或等于设置的阈值
			{
				if(Led_P==1)			// 如果窗帘当前是关闭的
				{
					Open();					// 则打开窗帘
				}
			}	
		}
		
		DelayMs(100);							// 延时0.1秒
	}
}
void interrupt0()interrupt 0
{
	uchar i=0,j=0,k=0,us=0;
	uchar addr[4]={0};
int aa=0x00;

	EX0=0;

	for(i=0;i<255;i++)  //9ms内有高电平认为是干扰
	{
		if(P3&0x04)	    //255的值实际时间为800us
		{
			EX0=1;
			return;
		}
	}
	while(!(P3&0x04));	//等待9ms低电平过去
   	for(i=0;i<4;i++)
	{
		for(j=0;j<8;j++)
		{
			while(P3&0x04);	//等待4.5ms高电平过去	
			while(!(P3&0x04));	//等待0.56ms低电平后面的高电平
			while(P3&0x04)		//计算这个高电平的时间
			{
				for(us=0;us<=32;us++);	//100us的延时语句
				if((k++)>=30)		//高电平时间过长退出程序
				{
					EX0=1;
					return;
				}
			}

			if(k>=8)
				addr[i]=addr[i]|0x80;	//高电平大于0.56ms,则为1
			k=0;
		}
	}	

	aa=addr[2];	 //P2的LED显示二进制键值
	if(aa==0x07){
		if(gMode==1)
		{
			openflag=1;
		}
	//	Close();
	}
	if(aa==0x09){
		if(gMode==1)
		{
			closeflag=1;
		}
	//	Open();
}
	EX0=1;	
aa=0x00;
}

源文件获取

关注公众号-电子开发圈,首页发送 “智能窗” 获取;