C51智能窗帘项目完整工程

一,硬件条件及仿真

硬件

仿真图 

二,完成的功能 

 基本功能:

1.可实时显示年月日,时分秒,光照强度和控制模式

2.可通过手动控制窗帘的开启和关闭

3.可通过设置开启和关闭时间来控制窗帘

4.可通过检测光照强度的亮暗来控制窗帘

5.使用步进电机的正转和反转来模拟窗帘的开启和关闭

额外功能:

1.可显示窗帘目前所处的状态

2.可调节控制开关窗帘的光强阈值

三,按键模块设计

相关代码 :

key.h文件

#ifndef __KEY_H
#define __KEY_H
/* 头文件 */
#include <reg52.h>
#include "lcd1602.h"
#include "uln2003.h"

/* 10ms标志外部声明 */
extern unsigned char DelayFlag;

/* 模式切换变量 */
extern unsigned char ModFlag;

/* 闹钟存储变量 */
extern unsigned char AlarmClock[ 6 ];

/* 窗帘状态标志 */
extern unsigned char CurtainState;

/* 按键检测函数 */
void myKeyScan( void );

/* 按键事件实现函数 */
void myKeyProcess( void );

#endif

key.c文件

#include "key.h"

/* 相关按键变量定义 */
unsigned char cont,trg; 
unsigned char KeyValue;	

/* 10ms标志 */
unsigned char DelayFlag = 0;
/* LED */
sbit Led = P2^0;
/* 模式切换变量 0自动模式 1手动模式 2时间定时开模式 3定时关模式 */ 
unsigned char ModFlag = 0;
/* 闹钟存储变量 开 */
unsigned char AlarmClock[ 6 ] = { 10,30,10,10,30,20 };
/* 窗帘状态标志,0为开 */
unsigned char CurtainState = 0;

/*
名字:myKeyScan
参数:无
返回值:无
作用:按键扫描
*/
void myKeyScan( void )
{
	unsigned char ReadData = P3^0xff;
	trg = ReadData&( ReadData^cont );
	cont = ReadData;
}


/*
名字:myKeyProcess
参数:无
返回值:无
作用:实现按键对应的事件
*/
void myKeyProcess( void )
{
	if( DelayFlag == 1 )
	{
		DelayFlag = 0;
		myKeyScan();
		/* K1事件处理 */
		if( trg & 0x08 )
		{
			/* 清屏 */
			LcdWriteCmd(0x01);
			/* 模式切换 */
			ModFlag = (ModFlag+1)%4;
		}
		
		
		/* K2事件处理 */
		if( trg & 0x10 )
		{
			/* 模式1手动正转 */
			if( ModFlag == 1 && CurtainState == 1 )
			{
				/* 加载页面显示 */
				waitDisplay();
				Led = 0;
				Open();
				CurtainState = 0;
				/* 清屏 */
				LcdWriteCmd(0x01);
			}
			/* 模式2时加 */
			else if( ModFlag == 2 )
			{
				if( AlarmClock[0] >= 23 )
				{
					AlarmClock[0] = 0;
				}
				else
				{
					AlarmClock[0]++;
				}
			}
			/* 模式3时加 */
			else
			{
				if( AlarmClock[3] >= 23 )
				{
					AlarmClock[3] = 0;
				}
				else
				{
					AlarmClock[3]++;
				}
			}
		}
		
		
		/* K3事件处理 */
		if( trg & 0x20 )
		{
			/* 模式1手动反转 */
			if( ModFlag == 1 && CurtainState == 0 )
			{
				/* 加载页面显示 */
				waitDisplay();
				Led = 1;
				Close();
				CurtainState = 1;
				/* 清屏 */
				LcdWriteCmd(0x01);
			}
			/* 模式2分加 */
			else if( ModFlag == 2 )
			{
				if( AlarmClock[1] >= 59 )
				{
					AlarmClock[1] = 0;
				}
				else
				{
					AlarmClock[1]++;
				}
			}
			/* 模式3分加 */
			else
			{
				if( AlarmClock[4] >= 59 )
				{
					AlarmClock[4] = 0;
				}
				else
				{
					AlarmClock[4]++;
				}
			}
		}
		
		
		/* K4事件处理 */
		if( trg & 0x40 )
		{
			/* 模式2秒加 */
			if( ModFlag == 2 )
			{
				if( AlarmClock[2] >= 59 )
				{
					AlarmClock[2] = 0;
				}
				else
				{
					AlarmClock[2]++;
				}
			}
			/* 模式3秒加 */
			else if( ModFlag == 3 )
			{
				if( AlarmClock[5] >= 59 )
				{
					AlarmClock[5] = 0;
				}
				else
				{
					AlarmClock[5]++;
				}
			}
			/* 模式1关照阈值加 */
			else if( ModFlag == 1 )
			{
				if( LightThreshold<5 )
				{
					LightThreshold++;
				}
			}
		}
		
		
		/* K5事件处理 */
		if( trg & 0x80 )
		{
			/* 模式2清零 */
			if( ModFlag == 2 )
			{
				AlarmClock[0] = 0;
				AlarmClock[1] = 0;
				AlarmClock[2] = 0;
			}
			/* 模式3清零 */
			else if( ModFlag == 3 )
			{
				AlarmClock[3] = 0;
				AlarmClock[4] = 0;
				AlarmClock[5] = 0;
			}
			/* 模式1减光照阈值 */
			else if( ModFlag == 1 )
			{
				if( LightThreshold > 0 )
				{
					LightThreshold--;
				}
			}
		}
	}	
}

按键部分采用了三行按键法的写法

四,实时时钟模块

 

相关代码: 

ds1302.h文件

#ifndef __DS1302_H
#define __DS1302_H
#include "reg52.h"
#include "intrins.h"
#include "key.h"
#include "main.h"

/* 初始化DS1302 */
void DS1302_Init(void);

/* 从DS1302读出一字节数据 */
unsigned char DS1302_Read_Byte(unsigned char addr);

/* 向DS1302写入一字节数据 */
void DS1302_Write_Byte(unsigned char addr, unsigned char dat);

/* 向DS1302写入时间数据 */
void DS1302_Write_Time();

/* 从DS1302读出时间数据 */
void DS1302_Read_Time( unsigned char time[7] );  

/* 实现定时开关窗帘函数声明 */
void timedTasksProcess( void );

/* 定时任务允许标志 0为允许 */
extern unsigned char timedTFlag;

#endif

 ds1302.c文件

#include "ds1302.h"

/* 相关变量定义 */
sbit RST_P = P1^2;
sbit SCK_P = P1^0;
sbit SDA_P = P1^1;

// 设置时间数据       年月日星期时分秒
unsigned char TimeBuff[7] = {23,10,13,3,10,30,0};

/* 定时任务允许标志 0为允许 */
unsigned char timedTFlag = 0;

/* 
	*函数名:DS1302_Read_Byte
	*参数addr:地址
	*作用:从DS1302读出一字节数据
	*返回值:该地址的值
*/
unsigned char DS1302_Read_Byte(unsigned char addr) 
{
	unsigned char i;
	unsigned char temp;
	RST_P=1;								
	/* 写入目标地址:addr*/
	for(i=0;i<8;i++) 
	{     
		if(addr&0x01) 
			SDA_P=1;
		else 
			SDA_P=0;
		
		SCK_P=1;
		_nop_();
		SCK_P=0;
		_nop_();
		
		addr=addr>> 1;
	}
	/* 读出该地址的数据 */
	for(i=0;i<8;i++) 
	{
		temp=temp>>1;
		
		if(SDA_P) 
			temp|= 0x80;
		else 
			temp&=0x7F;
		
		SCK_P=1;
		_nop_();
		SCK_P=0;
		_nop_();
	}
	RST_P=0;
	return temp;
}


/* 
	*函数名:DS1302_Write_Byte
	*参数addr:地址
	*参数dat:数据
	*作用:向DS1302写入一字节数据
	*返回值:无
*/
void DS1302_Write_Byte(unsigned char addr, unsigned char dat)
{
	unsigned char i;
	RST_P = 1;
	/* 写入目标地址:addr*/
	for(i=0;i<8;i++) 
	{ 
		if(addr&0x01) 
			SDA_P=1;
		else 
			SDA_P=0;

		SCK_P=1;
		_nop_();
		SCK_P=0;
		_nop_();
		
		addr=addr>>1;
	}
	/* 写入数据:dat*/
	for(i=0;i<8;i++) 
	{
		if(dat&0x01) 
			SDA_P=1;
		else 
			SDA_P=0;
	
		SCK_P=1;
		_nop_();
		SCK_P=0;
		_nop_();	
		dat=dat>>1;
	}
	RST_P=0;					
}


/* 
	*函数名:DS1302_Write_Time
	*参数:无
	*作用:向DS1302写入时间数据
	*返回值:无
*/
void DS1302_Write_Time() 
{
  unsigned char i;
	unsigned char temp1;
	unsigned char temp2;
	// 十进制转BCD码
	for(i=0;i<7;i++)			
	{
		temp1=(TimeBuff[i]/10)<<4;
		temp2=TimeBuff[i]%10;
		TimeBuff[i]=temp1+temp2;
	}
	DS1302_Write_Byte(0x8E,0x00);								// 关闭写保护 
	DS1302_Write_Byte(0x80,0x80);								// 暂停时钟 
	DS1302_Write_Byte(0x8C,TimeBuff[0]);				// 年 
	DS1302_Write_Byte(0x88,TimeBuff[1]);				// 月 
	DS1302_Write_Byte(0x86,TimeBuff[2]);				// 日 
	DS1302_Write_Byte(0x8A,TimeBuff[3]);				// 星期
	DS1302_Write_Byte(0x84,TimeBuff[4]);				// 时 
	DS1302_Write_Byte(0x82,TimeBuff[5]);				// 分
	DS1302_Write_Byte(0x80,TimeBuff[6]);				// 秒
	DS1302_Write_Byte(0x80,TimeBuff[6]&0x7F);		// 运行时钟
	DS1302_Write_Byte(0x8E,0x80);								// 打开写保护  
}


/* 
	*函数名:DS1302_Read_Time
	*参数time[7]:需要传入存放时间的数组
	*作用:从DS1302读出时间数据
	*返回值:无
*/
void DS1302_Read_Time( unsigned char time[7] )  
{ 
	unsigned char i;
	time[0]=DS1302_Read_Byte(0x8D);						// 年 
	time[1]=DS1302_Read_Byte(0x89);						// 月 
	time[2]=DS1302_Read_Byte(0x87);						// 日 
	time[3]=DS1302_Read_Byte(0x8B);						// 星期
	time[4]=DS1302_Read_Byte(0x85);						// 时 
	time[5]=DS1302_Read_Byte(0x83);						// 分 
	time[6]=(DS1302_Read_Byte(0x81))&0x7F;		// 秒 
	for(i=0;i<7;i++)		// BCD转十进制
	{           
		time[i]=(time[i]/16)*10+time[i]%16;
	}
}


/* 
	*函数名:DS1302_Init
	*参数:无
	*作用:初始化DS1302
	*返回值:无
*/
void DS1302_Init(void)
{
	// RST脚置低
	RST_P = 0;
	// SCK脚置低	
	SCK_P = 0;
	// SDA脚置低	
	SDA_P = 0;
	//初始化时间
	DS1302_Write_Time();
}


/*
名字:timedTasksProcess
参数:无
返回值:无
作用:实现定时开关窗帘
*/
void timedTasksProcess( void )
{
	/* 窗帘状态为关 */
	if( CurtainState )
	{
		/* 开启时间比较 */
		if( dat[4]==AlarmClock[0] && dat[5]==AlarmClock[1] && dat[6]==AlarmClock[2] )
		{
			/* 加载页面显示 */
			waitDisplay();
			/* 开电机 */
			Open();
			/* 窗帘开标志 */
			CurtainState = 0;
			/* 定时任务允许标志 0为允许 */
			timedTFlag = 0;
			/* 清屏 */
			LcdWriteCmd(0x01);
		}
	}
	/* 窗帘状态为开 */
	else
	{
		/* 关闭时间比较 */
		if( dat[4]==AlarmClock[3] && dat[5]==AlarmClock[4] && dat[6]==AlarmClock[5] )
		{
			/* 加载页面显示 */
			waitDisplay();
			/* 关电机 */
			Close();
			/* 窗帘关标志 */
			CurtainState = 1;
			/* 定时任务允许标志 1为禁止 */
			timedTFlag = 1;
			/* 清屏 */
			LcdWriteCmd(0x01);
		}
	}
}

五,显示模块

相关代码:

lcd1602.h文件

#ifndef __LCD1602__H
#define __LCD1602__H
#include "reg52.h"
#include "intrins.h"
#include "ds1302.h"
#include "key.h"
#include "main.h"

/* 变量别名 */
typedef unsigned char uchar;

/* 光照电压阈值 */
extern float LightThreshold;

/* 1602液晶写命令函数,cmd就是要写入的命令 */
void LcdWriteCmd(uchar cmd);
	
/* 1602液晶写数据函数,dat就是要写入的数据 */
void LcdWriteData(uchar dat);

/* 1602液晶初始化函数 */
void LcdInit();

/* 液晶光标定位函数 */
void LcdGotoXY(uchar line,uchar column);

/* 显示字符串 */
void LcdPrintStr(uchar *str);

/* 显示数字 */
void LcdPrintNum(uchar num);

/* 延时2ms */
void delay2ms(void);

/* 显示函数 */
void lcdDisplayProcess( unsigned char tim[7], unsigned char mode, float lx ,unsigned char alarm[ 6 ] );

/* 加载显示函数 */
void waitDisplay( void );

#endif

lcd1602.c文件 

#include "lcd1602.h"

/* 相关变量定义 */
sbit LcdRs_P = P1^3;
sbit LcdRw_P = P1^4;
sbit LcdEn_P = P1^5;

unsigned char g;
unsigned char lx2;
/* 光照电压阈值 */
float LightThreshold = 3.0;

/* 
	*函数名:delay2ms
	*参数:无
	*作用:延时2ms
	*返回值:无
*/
void delay2ms(void)  
{
    unsigned char a,b;
    for(b=4;b>0;b--)
        for(a=248;a>0;a--);
    _nop_();  
}


/* 
	*函数名:LcdWriteCmd
	*参数cmd:命令
	*作用:1602液晶写命令函数,cmd就是要写入的命令
	*返回值:无
*/
void LcdWriteCmd(uchar cmd)
{ 
	LcdRs_P = 0;
	LcdRw_P = 0;
	LcdEn_P = 0;
	P0=cmd;
	delay2ms();
	LcdEn_P = 1;    
	delay2ms();
	LcdEn_P = 0;	
}


/* 
	*函数名:LcdWriteData
	*参数dat:数据
	*作用:1602液晶写数据函数,dat就是要写入的数据
	*返回值:无
*/
void LcdWriteData(uchar dat)
{
	LcdRs_P = 1; 
	LcdRw_P = 0;
	LcdEn_P = 0;
	P0=dat;
	delay2ms();
	LcdEn_P = 1;    
	delay2ms();
	LcdEn_P = 0;
}


/* 
	*函数名:LcdInit
	*参数:无
	*作用:1602液晶初始化函数
	*返回值:无
*/
void LcdInit()
{
	// 16*2显示,5*7点阵,8位数据口
	LcdWriteCmd(0x38);
	// 开显示,不显示光标	
	LcdWriteCmd(0x0C);
	// 地址加1,当写入数据后光标右移
	LcdWriteCmd(0x06);
	// 清屏
	LcdWriteCmd(0x01);        
}


/* 
	*函数名:LcdGotoXY
	*参数line:行值
	*参数column:列值
	*作用:液晶光标定位函数
	*返回值:无
*/
void LcdGotoXY(uchar line,uchar column)
{
	// 第一行
	if(line==0)        
		LcdWriteCmd(0x80+column); 
	// 第二行
	if(line==1)        
		LcdWriteCmd(0x80+0x40+column); 
}


/* 
	*函数名:LcdPrintStr
	*参数str:字符串
	*作用:显示字符串
	*返回值:无
*/
void LcdPrintStr(uchar *str)
{
	while(*str!='\0')
			LcdWriteData(*str++);
}


/* 
	*函数名:LcdPrintNum
	*参数num:数字
	*作用:显示数字
	*返回值:无
*/
void LcdPrintNum(uchar num)
{
	// 十位
	LcdWriteData(num/10+48);
	// 个位
	LcdWriteData(num%10+48); 		
}


/* 
	*函数名:lcdDisplayProcess
	*参数tim[7]:存储时间的数组指针
	*参数mode:模式 0为自动 1为手动
	*参数lx:光照强度
	*参数alarm:定时存储数组
	*作用:显示
	*返回值:无
*/
void lcdDisplayProcess( unsigned char tim[7], unsigned char mode, float lx ,unsigned char alarm[ 6 ] )
{
	/* 读取时间 */
	DS1302_Read_Time( tim );
	if( mode == 0 )
	{
		/* 显示位置 */
		LcdGotoXY( 0,0 );
		/* 显示年 */
		LcdPrintNum( 20 );
		LcdPrintNum( tim[0] );
		/* 显示月 */
		LcdPrintNum( tim[1] );
		/* 显示日 */
		LcdPrintNum( tim[2] );
		
		/* 显示模式 */
		LcdGotoXY( 0,10 );
		LcdPrintStr( "Mode:" );
		LcdWriteData(mode+48);
		
		LcdGotoXY( 1,0 );
		/* 显示时 */
		LcdPrintNum( tim[4] );
		LcdPrintStr( ":" );
		/* 显示分 */
		LcdPrintNum( tim[5] );
		LcdPrintStr( ":" );
		/* 显示秒 */
		LcdPrintNum( tim[6] );
		
		/* 显示光照强度 */
		LcdGotoXY( 1,10 );
		LcdPrintStr( "LX:" );
		lx2 = 10*lx;
		LcdWriteData(lx2/10+48);
		LcdPrintStr( "." );
		LcdWriteData(lx2%10+48);
	}
	else if( mode == 1 )
	{
		/* 模式显示 */
		LcdGotoXY( 0,5 );
		LcdPrintStr( "Mode:" );
		LcdWriteData(mode+48);
		/* 控制显示 */
		LcdGotoXY( 1,0 );
		LcdPrintStr( "cur:" );
		if( CurtainState == 0 )LcdPrintStr( "ON " );
		else LcdPrintStr( "OFF" );
		LcdGotoXY( 1,8 );
		LcdPrintStr( "SeLx:" );
		lx2 = 10*LightThreshold;
		LcdWriteData(lx2/10+48);
		LcdPrintStr( "." );
		LcdWriteData(lx2%10+48);
	}
	else if( mode == 2 )
	{
		/* 模式显示 */
		LcdGotoXY( 0,5 );
		LcdPrintStr( "Mode:" );
		LcdWriteData(mode+48);
		/* 时间显示 */
		LcdGotoXY( 1,0 );
		/* 显示时 */
		LcdPrintStr( "Open " );
		LcdPrintNum( alarm[0] );
		LcdPrintStr( ":" );
		/* 显示分 */
		LcdPrintNum( alarm[1] );
		LcdPrintStr( ":" );
		/* 显示秒 */
		LcdPrintNum( alarm[2] );
	}
	else
	{
		/* 模式显示 */
		LcdGotoXY( 0,5 );
		LcdPrintStr( "Mode:" );
		LcdWriteData(mode+48);
		/* 时间显示 */
		LcdGotoXY( 1,0 );
		/* 显示时 */
		LcdPrintStr( "Close " );
		LcdPrintNum( alarm[3] );
		LcdPrintStr( ":" );
		/* 显示分 */
		LcdPrintNum( alarm[4] );
		LcdPrintStr( ":" );
		/* 显示秒 */
		LcdPrintNum( alarm[5] );
	}
	
}


/* 
	*函数名:waitDisplay
	*参数:无
	*作用:显示加载页面
	*返回值:无
*/
void waitDisplay( void )
{
		/* 清屏 */
		LcdWriteCmd(0x01);
		/* 等待显示 */
		LcdGotoXY( 0,5 );
		LcdPrintStr( "Wait..." );
}

六,电机模块(四相五线电机) 

相关代码:

uln2003.h文件

#ifndef __ULN2003__H
#define __ULN2003__H
#include "reg52.h"

/* 延时3ms */
void delay3ms(void);

/* 开窗 */
void Open();

/* 关窗 */
void Close();

/* led初始化 */
void ledInit( void );

#endif

 uln2003.c文件

#include "uln2003.h"

/* LED */
sbit Led_P = P2^0;

/* 正转 */
unsigned char Clock[4] = { 0x80,0x40,0x20,0x10 };
/* 反转 */
unsigned char AntiClock[4] = { 0x10,0x20,0x40,0x80 };

/* 
	*函数名:delay3ms
	*参数:无
	*作用:延时3ms
	*返回值:无
*/
void delay3ms(void)   //误差 0us
{
    unsigned char a,b;
    for(b=111;b>0;b--)
        for(a=12;a>0;a--);
}


/* 
	*函数名:Open
	*参数:无
	*作用:开窗
	*返回值:无
*/
void Open()
{
	unsigned int i,j;
	// 控制步进电机正转
	for(j=0;j<255;j++)		
	{
		for(i=0;i<4;i++)
		{
			P2=Clock[i];
			delay3ms();
		}
		
	}
	P2 = 0;
	Led_P=0;
}


/* 
	*函数名:Close
	*参数:无
	*作用:关窗
	*返回值:无
*/
void Close()
{
	unsigned int i,j;
	// 控制步进电机反转
	for(j=0;j<255;j++)		
	{
		for(i=0;i<4;i++)
		{
			P2=AntiClock[i];
			delay3ms();
		}
	}
	P2 = 0;
	Led_P=1;
}


/* 
	*函数名:ledInit
	*参数:无
	*作用:led初始化
	*返回值:无
*/
void ledInit( void )
{
	Led_P=0;
}

七,采光模块及LED

相关代码: 

adc0832.h文件

#ifndef __DS1302__H
#define __DS1302__H
#include "reg52.h"
#include "key.h"
#include "ds1302.h"

/* 驱动0832函数 */
unsigned char ad0832read(bit SGL,bit ODD);

/* 读取电压 */
float getVProcess( void );

/* 模式0自动任务 */
void AutomaticControlProcess( float threshold );

#endif

adc0832.c文件 

#include "adc0832.h"

/* 相关变量定义 */
sbit SCL = 	P1^7;
sbit DO = P3^2;
sbit CS = P1^6;

/* 
	*函数名:ad0832read
	*参数SGL:单端输入   可设为:1
	*参数ODD:偶校验	    可设为:0
	*作用:驱动0832函数
	*返回值:代表转换后的数字信号
*/
unsigned char ad0832read(bit SGL,bit ODD)
{
	unsigned char i=0,value=0,value1=0;		
		SCL=0;
		DO=1;
		//开始
		CS=0;		
		//第一个上升沿	
		SCL=1;		
		SCL=0;
		DO=SGL;
		//第二个上升沿
		SCL=1;  	
		SCL=0;
		DO=ODD;
		//第三个上升沿
		SCL=1;
		//第三个下降沿
		SCL=0;	    
		DO=1;
		for(i=0;i<8;i++)
		{
			SCL=1;
			//开始从第四个下降沿接收数据
			SCL=0;
			value<<=1;
			if(DO)
				value++;						
		}
		for(i=0;i<8;i++)
		{	
			//接收校验数据
			value1>>=1;
			if(DO)
				value1+=0x80;
			SCL=1;
			SCL=0;
		}
		CS=1;
		SCL=1;
		//与校验数据比较,正确就返回数据,否则返回0	
		if(value==value1)				
			return value;
	return 0;
}

/*
名字:getVProcess
参数:无
返回值V:电压值
作用:读取电压
*/
float getVProcess( void )
{
	float V = 0;
	V = (float)ad0832read( 1,0 );
	V = (V/256.0f)*5.0f;
	return V;
}


/*
名字:AutomaticControlProcess
参数threshold:阈值电压
返回值:无
作用:模式0自动控制任务
*/
void AutomaticControlProcess( float threshold )
{
	/* 为模式一 */
	if( ModFlag == 0 )
	{
		/* 状态为1关,且定时任务允许 */
		if( CurtainState == 1 && timedTFlag == 0 )
		{
			/* 低过阈值 */
			if( lx_value <= threshold )
			{
				/* 加载页面显示 */
				waitDisplay();
				/* 开电机 */
				Open();
				/* 窗帘开标志 */
				CurtainState = 0;
				/* 清屏 */
				LcdWriteCmd(0x01);
			}
		}
		/* 状态为0开 */
		else if( CurtainState == 0 && timedTFlag == 0 )
		{
			/* 高于阈值 */
			if( lx_value >= threshold )
			{
				/* 加载页面显示 */
				waitDisplay();
				/* 关电机 */
				Close();
				/* 窗帘关标志 */
				CurtainState = 1;
				/* 清屏 */
				LcdWriteCmd(0x01);
			}
		}
	}
}

 八,主函数

相关代码:

 main.h文件

#ifndef __MAIN__H
#define __MAIN__H
#include "reg52.h"

/* 时间存储数组 */
extern unsigned char dat[7];

/* 光强存储变量 */
extern float lx_value;

#endif

 main.c文件

/* 头文件 */
#include "lcd1602.h"
#include "adc0832.h"
#include "ds1302.h"
#include "uln2003.h"
#include "key.h"
#include "main.h"

/* 时间存储数组 */
unsigned char dat[7];
/* 光强存储变量 */
float lx_value = 0;

/* 实现时钟10ms延时的初始化声明 */
void InitTimer0(void);

void main( void )
{
	/* LCD1602显示 */
	LcdInit();
	/* 初始化DS1302 */
	DS1302_Init();
	/* 实现时钟10ms延时的初始化 */
	InitTimer0();
    /* led初始化 */
	ledInit();
	
	while( 1 )
	{
		/* 光强采集 */
		lx_value = getVProcess();
		/* LCD显示 */
		lcdDisplayProcess( dat, ModFlag, lx_value, AlarmClock );
		/* 按键程序 */
		myKeyProcess();	
		/* 定时任务 */
		timedTasksProcess();
		/* 模式0自动任务 */
		AutomaticControlProcess( LightThreshold );
	}
}

/*
名字:InitTimer0
参数:无
返回值:无
作用:实现时钟10ms延时的初始化
*/
void InitTimer0(void)
{
    TMOD = 0x01;
    TH0 = 0x0D8;
    TL0 = 0x0F0;
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}


/*
名字:Timer0Interrupt
参数:无
返回值:无
作用:实现时钟中断的服务
*/
void Timer0Interrupt(void) interrupt 1
{
    TH0 = 0x0D8;
    TL0 = 0x0F0;
    DelayFlag = 1;
}

移植说明:将以上各个模块的代码加入你的工程,即可等到完整的keil的工程。 

九,效果说明

显示:

自动控制模式显示说明:

手动控制模式显示说明:

定时开模式显示说明:

定时关模式显示说明: 

 

加载显示:

 

控制: 

模式0下按键功能:

key1:模式切换

key2,key3,key4,key5:无

模式1下按键功能:

 key1:模式切换

key2:手动开窗帘

key3:手动关窗帘

key4:光强阈值加

key5:光强阈值减

模式2下按键功能:

 key1:模式切换

key2:开窗帘时加

key3:开窗帘分加

key4:开窗帘秒加

key5:开窗帘时,分,秒清零

模式3下按键功能:

 key1:模式切换

key2:关窗帘时加

key3:关窗帘分加

key4:关窗帘秒加

key5:关窗帘时,分,秒清零

一些使用说明:

1,如果窗帘处于开的状态,再要求其开窗口的相关指令是无效的,关窗同是。

2.定时开关的权限高于自动开关的权限,即在定时的时间段内,自动控制无效。

3.手动模式强制开或关窗帘后,请不要切到自动模式,否则可能会出现你刚刚给它关窗,自动模式马上帮你开窗。

十,结束语

   该程序为笔者自己写的,可能不太成熟,如果想要完整的仿真等工程可以私信笔者,有问题欢迎交流!!!!!

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值