本设计主要是解决普通家电的智能化控制,主要描述一个遥控定时插座的设计与制作。该定时插座可以弥补现实生活中普通插座功能的不足,能够通过外设按键或遥控器设置插座的供电时间,使外接电器可以按照一定规律工作,既可以达到智能控制的目的,又在很大程度上起到节能的作用。
本系统由STC8C52单片机电路+时钟DS1302电路+LCD1602液晶显示电路+按键电路+继电器控制电路+蜂鸣器报警电路+红外传感器电路+电源电路组成。
1、DS1302时钟芯片,准确计时,自带3V纽扣电池,当系统掉电后,纽扣电池供电给时钟芯片继续工作,再次上电无需重新设置时间。
2、LCD1602液晶可以显示时、分、秒、星期、年、月、日。
3、可以设置5个开关开的时间和5个开关关的时间,每一个时间都可以单独设置成是否工作有效(Y/N),设定的时间并具有掉电保存功能,保存在STC单片机的内部,上电无需重新设置。
4、继电器吸合指示灯亮实现开关开,继电器断开指示灯灭实现开关关,继电器可以外接其他的家用电器。
5、具有自动模式和手动模式,手动模式下按加、减键就可以实现开关的开和关。
6、开机默认是自动模式,当现在的时间和设置开的时间一致时,继电器工作打开开关,当现在的时候和设置关的时间一致时继电器断开关闭开关。
7、开关的开和关蜂鸣器的提示声不同,当开关开时,蜂鸣器会发出滴滴的提示声,开关关时,蜂鸣器会长鸣一声。
8、具有红外遥控功能,可以用红外遥控器完成整个产品的操作。“|<<”标识手动或切换,“>>|”表示设置或换页,“—”表示手动情况关闭或设置值--,“+”表示手动情况打开或设置值++。
源程序(C语言含详细备注)单片机源程序如下:
- #include <reg52.h> //调用单片机头文件
- #define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
- #define uint unsigned int //无符号整型 宏定义 变量范围0~65535
- bit flag_200ms ; //200ms标志
- bit flag_100ms ; //100ms标志
- sbit beep = P3^7; //蜂鸣器定义
- bit flag_beep_en; //蜂鸣器使能标志
- uint clock_value; //用作闹钟用的
- uchar menu_1,menu_2; //菜单选项
- sbit relay = P2^0;//继电器
- bit flag_moshi;
- sbit IR=P3^2; //红外接口标志
- uchar key_time,flag_value; //用做连加的中间变量
- bit key_500ms ;
- void Ircordpro(void);//红外码值处理函数
- unsigned char irtime;//红外用全局变量
- bit irpro_ok,irok;
- unsigned char IRcord[4];
- unsigned char irdata[33];
- //#include "key.h"
- #include "ds1302.h"
- #include "lcd1602.h"
- bit open1,open2,open3,open4,open5,open6,open7,open8,open9,open10,open11,open12;
- uchar fen1=0x30,shi1=0x06; //第1个开关的时间 开
- uchar fen2=0x30,shi2=0x07; //第2个开关的时间 闭
- uchar fen3=0x10,shi3=0x08; //第3个开关的时间
- uchar fen4=0x20,shi4=0x08; //第4个开关的时间
- uchar fen5=0x00,shi5=0x09; //第5个开关的时间
- uchar fen6=0x10,shi6=0x09; //第6个开关的时间
- uchar fen7=0x50,shi7=0x09; //第7个开关的时间
- uchar fen8=0x00,shi8=0x10; //第8个开关的时间
- uchar fen9=0x40,shi9=0x10; //第9个开关的时间
- uchar fen10=0x50,shi10=0x10; //第10个开关的时间
- /******************1ms 延时函数*******************/
- void delay_1ms(uint q)
- {
- uint i,j;
- for(i=0;i<q;i++)
- for(j=0;j<120;j++);
- }
- /*************定时器0初始化程序***************/
- void init_1602_ds1302()
- {
- write_sfm2_ds1302(2,3,nian);
- write_sfm2_ds1302(2,6,yue);
- write_sfm2_ds1302(2,9,ri);
- write_sfm2_ds1302(1,2,shi);
- write_sfm2_ds1302(1,5,fen);
- write_sfm2_ds1302(1,8,miao);
- write_sfm1(1,14,week);
- }
- /*************开关函数***************/
- void menu_dis()
- {
-
- if(miao == 0)
- {
- if(((fen == fen1) && (shi == shi1) && (open1 == 1)) ||
- ((fen == fen3) && (shi == shi3) && (open3 == 1)) ||
- ((fen == fen5) && (shi == shi5) && (open5 == 1)) ||
- ((fen == fen7) && (shi == shi7) && (open7 == 1)) ||
- ((fen == fen9) && (shi == shi9) && (open9 == 1)))
- { //打开开关
- relay = 0;
- for(i=0;i<4;i++)
- {
- beep = ~beep;
- delay_1ms(200);
- }
- beep = 1;
- }
- if(((fen == fen2) && (shi == shi2) && (open2 == 1)) ||
- ((fen == fen4) && (shi == shi4) && (open4 == 1)) ||
- ((fen == fen6) && (shi == shi6) && (open6 == 1)) ||
- ((fen == fen8) && (shi == shi8) && (open8 == 1)) ||
- ((fen == fen10) && (shi == shi10) && (open10 == 1)))
- { //关闭开关
- relay = 1;
- beep = 0;
- delay_1ms(1000);
- beep = 1;
- }
- }
- }
- /********************独立按键程序*****************/
- uchar key_can; //按键值
- void key() //独立按键程序
- {
- static uchar key_new;
- if((P3 & 0x78) != 0x78) //按键按下,
- {
- delay_1ms(1); //按键消抖动
- if(((P3 & 0x78) != 0x78) && (key_new == 1))
- { //确认是按键按下
- key_new = 0;
- switch(P3 & 0x78)
- {
- case 0x70: key_can = 4; break; //得到按键值
- case 0x68: key_can = 3; break; //得到按键值
- case 0x58: key_can = 2; break; //得到按键值
- case 0x38: key_can = 1; break; //得到按键值
- }
- }
- }
- else
- key_new = 1;
- }
- /**********************设置函数************************/
- void key_with()
- {
- if(menu_1 == 0)
- {
- if(key_can == 2)
- {
- flag_moshi = !flag_moshi;
- if(flag_moshi == 0) //自动模式
- write_string(2,13," ");
- if(flag_moshi == 1) //手动模式
- write_string(2,13,"sd ");
- }
- if(flag_moshi == 1)
- {
- if(key_can == 3)
- relay = 0; //开
- if(key_can == 4)
- relay = 1; //关
- }
- }
- if(key_can == 1) //设置键
- {
- menu_1++;
- if(menu_1 == 1) //设置时间
- {
- menu_2 = 1;
- write_string(1,0," : : W: ");
- write_string(2,0," 20 - - ");
- }
- menu_2 = 1;
- if(menu_1 > 6) //回到正常显示
- {
- menu_1 = 0;
- write_guanbiao(1,2,0); //关闭光标
- init_1602_dis_csf(); //初始化液晶显示
- }
- }
- if(key_can == 2) //选择键
- {
- flag_200ms = 1;
- if(menu_1 == 1) //设置时间
- {
- menu_2 ++;
- if(menu_2 > 7)
- menu_2 = 1;
- }
- if(menu_1 != 1) //设置
- {
- menu_2 ++;
- if(menu_2 > 6)
- menu_2 = 1;
- }
- }
- if(menu_1 == 1)
- {
- if(menu_2 == 1) //设置时
- {
- if(key_can == 3) //加
- set_ds1302time(1,&shi,0x24);
- if(key_can == 4) //减
- set_ds1302time(0,&shi,0x24);
- }
- if(menu_2 == 2) //设置分
- {
- if(key_can == 3) //加
- set_ds1302time(1,&fen,0x60);
- if(key_can == 4) //减
- set_ds1302time(0,&fen,0x60);
- }
- if(menu_2 == 3) //设置秒
- {
- if(key_can == 3) //加
- set_ds1302time(1,&miao,0x60);
- if(key_can == 4) //减
- set_ds1302time(0,&miao,0x60);
- }
- if(menu_2 == 4) //设置星期
- {
- if(key_can == 3) //加
- set_ds1302time(1,&week,8);
- if(key_can == 4) //减
- set_ds1302time(0,&week,8);
- }
- if(menu_2 == 5) //设置年
- {
- if(key_can == 3) //加
- set_ds1302time(1,&nian,0x9A);
- if(key_can == 4) //减
- set_ds1302time(0,&nian,0x9A);
- }
- if(menu_2 == 6) //设置月
- {
- if(key_can == 3) //加
- set_ds1302time(1,&yue,0x13);
- if(key_can == 4) //减
- set_ds1302time(0,&yue,0x13);
- }
- if(menu_2 == 7) //设置日
- {
- if(key_can == 3) //加
- set_ds1302time(1,&ri,0x32);
- if(key_can == 4) //减
- set_ds1302time(0,&ri,0x32);
- }
- write_time(); //把时间写进去1302RAM
- write_sfm2_ds1302(1,2,shi); //显示时 1302RAM显示出来
- write_sfm2_ds1302(1,5,fen); //显示分
- write_sfm2_ds1302(1,8,miao); //显示秒
- write_sfm1(1,14,week); //显示星期
- write_sfm2_ds1302(2,3,nian); //显示年
- write_sfm2_ds1302(2,6,yue); //显示月
- write_sfm2_ds1302(2,9,ri); //显示日
- switch(menu_2) // 光标显示
- {
- case 1: write_guanbiao(1,2,1); break;
- case 2: write_guanbiao(1,5,1); break;
- case 3: write_guanbiao(1,8,1); break;
- case 4: write_guanbiao(1,14,1); break;
- case 5: write_guanbiao(2,3,1); break;
- case 6: write_guanbiao(2,6,1); break;
- case 7: write_guanbiao(2,9,1); break;
- }
- }
- /***************设置1开关时间*********************/
- if(menu_1 == 2)
- {
- ///////////////////// 第1个开关时间 kai时间
- if(menu_2 == 1) //设置开关时
- {
- if(key_can == 3) //加
- set_ds1302time(1,&shi1,0x24);
- if(key_can == 4) //减
- set_ds1302time(0,&shi1,0x24);
- }
- if(menu_2 == 2) //设
- {
- if(key_can == 3) //加
- set_ds1302time(1,&fen1,0x60);
- if(key_can == 4) //减
- set_ds1302time(0,&fen1,0x60);
- }
- if(menu_2 == 3) //设
- {
- if(key_can == 3)
- open1 = ~open1;
- if(key_can == 4)
- open1 = ~open1;
- }
-
- ///////////////////// 第2个开关时间 闭时间
- if(menu_2 == 4) //设置开关分
- {
- if(key_can == 3) //加 第2个开关时间
- set_ds1302time(1,&shi2,0x24);
- if(key_can == 4) //减
- set_ds1302time(0,&shi2,0x24);
- }
- if(menu_2 == 5) //设
- {
- if(key_can == 3) //加
- set_ds1302time(1,&fen2,0x60);
- if(key_can == 4) //减
- set_ds1302time(0,&fen2,0x60);
- }
- if(menu_2 == 6) //设
- {
- if(key_can == 3)
- open2 = ~open2;
- if(key_can == 4)
- open2 = ~open2;
- }
- write_string(1,0,"OPEN1 00:00 Y ");
- write_string(2,0," OFF1 00:00 N ");
- write_sfm2_ds1302(1,6,shi1); //显示时
- write_sfm2_ds1302(1,9,fen1); //显示分
- write_sfm2_ds1302(2,6,shi2); //显示时
- write_sfm2_ds1302(2,9,fen2); //显示分
- if(open1 == 1)
- write_string(1,11," Y ");
- else
- write_string(1,11," N ");
- if(open2 == 1)
- write_string(2,11," Y ");
- else
- write_string(2,11," N ");
- }
- /***************设置2开关时间*********************/
- if(menu_1 == 3)
- {
- ///////////////////// 第1个开关时间
- if(menu_2 == 1) //设置开关时
- {
- if(key_can == 3) //加
- set_ds1302time(1,&shi3,0x24);
- if(key_can == 4) //减
- set_ds1302time(0,&shi3,0x24);
- }
- if(menu_2 == 2) //设
- {
- if(key_can == 3) //加
- set_ds1302time(1,&fen3,0x60);
- if(key_can == 4) //减
- set_ds1302time(0,&fen3,0x60);
- }
- if(menu_2 == 3) //设
- {
- if(key_can == 3)
- open3 = ~open3;
- if(key_can == 4)
- open3 = ~open3;
- }
- ///////////////////// 第2个开关时间
- if(menu_2 == 4) //设置开关分
- {
- if(key_can == 3) //加 第2个开关时间
- set_ds1302time(1,&shi4,0x24);
- if(key_can == 4) //减
- set_ds1302time(0,&shi4,0x24);
- }
- if(menu_2 == 5) //设
- {
- if(key_can == 3) //加
- set_ds1302time(1,&fen4,0x60);
- if(key_can == 4) //减
- set_ds1302time(0,&fen4,0x60);
- }
- if(menu_2 == 6) //设
- {
- if(key_can == 3)
- open4 = ~open4;
- if(key_can == 4)
- open4 = ~open4;
- }
- write_string(1,0,"OPEN2 00:00 ");
- write_string(2,0," OFF2 00:00 ");
- write_sfm2_ds1302(1,6,shi3); //显示时
- write_sfm2_ds1302(1,9,fen3); //显示分
- write_sfm2_ds1302(2,6,shi4); //显示时
- write_sfm2_ds1302(2,9,fen4); //显示分
- if(open3 == 1)
- write_string(1,11," Y ");
- else
- write_string(1,11," N ");
- if(open4 == 1)
- write_string(2,11," Y ");
- else
- write_string(2,11," N ");
- }
- /***************设置3开关时间*********************/
- if(menu_1 == 4)
- {
- ///////////////////// 第1个开关时间
- if(menu_2 == 1) //设置开关时
- {
- if(key_can == 3) //加
- set_ds1302time(1,&shi5,0x24);
- if(key_can == 4) //减
- set_ds1302time(0,&shi5,0x24);
- }
- if(menu_2 == 2) //设
- {
- if(key_can == 3) //加
- set_ds1302time(1,&fen5,0x60);
- if(key_can == 4) //减
- set_ds1302time(0,&fen5,0x60);
- }
- if(menu_2 == 3) //设
- {
- if(key_can == 3)
- open5 = ~open5;
- if(key_can == 4)
- open5 = ~open5;
- }
- ///////////////////// 第2个开关时间
- if(menu_2 == 4) //设置开关分
- {
- if(key_can == 3) //加 第2个开关时间
- set_ds1302time(1,&shi6,0x24);
- if(key_can == 4) //减
- set_ds1302time(0,&shi6,0x24);
- }
- if(menu_2 == 5) //设
- {
- if(key_can == 3) //加
- set_ds1302time(1,&fen6,0x60);
- if(key_can == 4) //减
- set_ds1302time(0,&fen6,0x60);
- }
- if(menu_2 == 6) //设
- {
- if(key_can == 3)
- open6 = ~open6;
- if(key_can == 4)
- open6 = ~open6;
- }
- write_string(1,0,"OPEN3 00:00 ");
- write_string(2,0," OFF3 00:00 ");
- write_sfm2_ds1302(1,6,shi5); //显示时
- write_sfm2_ds1302(1,9,fen5); //显示分
- write_sfm2_ds1302(2,6,shi6); //显示时
- write_sfm2_ds1302(2,9,fen6); //显示分
- if(open5 == 1)
- write_string(1,11," Y ");
- else
- write_string(1,11," N ");
- if(open6 == 1)
- write_string(2,11," Y ");
- else
- write_string(2,11," N ");
- }
- /***************设置4开关时间*********************/
- if(menu_1 == 5)
- {
- ///////////////////// 第4个开关时间
- if(menu_2 == 1) //设置开关时
- {
- if(key_can == 3) //加
- set_ds1302time(1,&shi7,0x24);
- if(key_can == 4) //减
- set_ds1302time(0,&shi7,0x24);
- }
- if(menu_2 == 2) //设
- {
- if(key_can == 3) //加
- set_ds1302time(1,&fen7,0x60);
- if(key_can == 4) //减
- set_ds1302time(0,&fen7,0x60);
- }
- if(menu_2 == 3) //设
- {
- if(key_can == 3)
- open7 = ~open7;
- if(key_can == 4)
- open7 = ~open7;
- }
-
- ///////////////////// 第4个开关时间
- if(menu_2 == 4) //设置开关分
- {
- if(key_can == 3) //加
- set_ds1302time(1,&shi8,0x24);
- if(key_can == 4) //减
- set_ds1302time(0,&shi8,0x24);
- }
- if(menu_2 == 5) //设
- {
- if(key_can == 3) //加
- set_ds1302time(1,&fen8,0x60);
- if(key_can == 4) //减
- set_ds1302time(0,&fen8,0x60);
- }
- if(menu_2 == 6) //设
- {
- if(key_can == 3)
- open8 = ~open8;
- if(key_can == 4)
- open8 = ~open8;
- }
- write_string(1,0,"OPEN4 00:00 ");
- write_string(2,0," OFF4 00:00 ");
- write_sfm2_ds1302(1,6,shi7); //显示时
- write_sfm2_ds1302(1,9,fen7); //显示时
- write_sfm2_ds1302(2,6,shi8); //显示时
- write_sfm2_ds1302(2,9,fen8); //显示分
- if(open7 == 1)
- write_string(1,11," Y ");
- else
- write_string(1,11," N ");
- if(open8 == 1)
- write_string(2,11," Y ");
- else
- write_string(2,11," N ");
- }
- /***************设置5开关时间*********************/
- if(menu_1 == 6)
- {
- ///////////////////// 第5个开关时间
- if(menu_2 == 1) //设置开关时
- {
- if(key_can == 3) //加
- set_ds1302time(1,&shi9,0x24);
- if(key_can == 4) //减
- set_ds1302time(0,&shi9,0x24);
- }
- if(menu_2 == 2) //设
- {
- if(key_can == 3) //加
- set_ds1302time(1,&fen9,0x60);
- if(key_can == 4) //减
- set_ds1302time(0,&fen9,0x60);
- }
- if(menu_2 == 3) //设
- {
- if(key_can == 3)
- open9 = ~open9;
- if(key_can == 4)
- open9 = ~open9;
- }
-
- ///////////////////// 第5个开关时间
- if(menu_2 == 4) //设置开关分
- {
- if(key_can == 3) //加
- set_ds1302time(1,&shi10,0x24);
- if(key_can == 4) //减
- set_ds1302time(0,&shi10,0x24);
- }
- if(menu_2 == 5) //设
- {
- if(key_can == 3) //加
- set_ds1302time(1,&fen10,0x60);
- if(key_can == 4) //减
- set_ds1302time(0,&fen10,0x60);
- }
- if(menu_2 == 6) //设
- {
- if(key_can == 3)
- open10 = ~open10;
- if(key_can == 4)
- open10 = ~open10;
- }
- write_string(1,0,"OPEN5 00:00 ");
- write_string(2,0," OFF5 00:00 ");
- write_sfm2_ds1302(1,6,shi9); //显示时
- write_sfm2_ds1302(1,9,fen9); //显示时
- write_sfm2_ds1302(2,6,shi10); //显示时
- write_sfm2_ds1302(2,9,fen10); //显示分
- if(open9 == 1)
- write_string(1,11," Y ");
- else
- write_string(1,11," N ");
- if(open10 == 1)
- write_string(2,11," Y ");
- else
- write_string(2,11," N ");
- }
- if((menu_1 >= 2))
- {
- switch(menu_2) // 光标显示
- {
- case 1: write_guanbiao(1,6,1); break;
- case 2: write_guanbiao(1,9,1); break;
- case 3: write_guanbiao(1,12,1); break;
- case 4: write_guanbiao(2,6,1); break;
- case 5: write_guanbiao(2,9,1); break;
- case 6: write_guanbiao(2,12,1); break;
- }
- }
- }
- /***********红外遥控程序**************/
- void hongwai_dis()
- {
- // unsigned char tab[3];
- if(irok) //如果接收好了进行红外处理
- {
- Ircordpro();
- irok=0;
- if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
- {
- beep = 0; //蜂鸣器叫一声
- delay_1ms(50);
- beep = 1;
- switch(IRcord[2])
- {
- case 0x40: key_can = 1; break; //得到按键值
- case 0x44: key_can = 2; break; //得到按键值
- case 0x15: key_can = 3; break; //得到按键值
- case 0x07: key_can = 4; break; //得到按键值
- case 0x43: key_can = 5;
- menu_1 = 0;
- write_guanbiao(1,2,0); //关闭光标
- init_1602_dis_csf(); //初始化液晶显示
- break; //得到按键值
- }
-
- // tab[0]=IRcord[2]/100+'0';
- // tab[1]=IRcord[2]/10%10+'0';
- // tab[2]=IRcord[2]%10+'0';
- // write_string(2,12,tab);
- irpro_ok=0;//处理完成标志
- }
- }
- }
- /***********外部中断0初始化程序****************/
- void init_int0() //外部中断0初始化程序
- {
- EX0=1; //允许外部中断0中断
- EA=1; //开总中断
- IT0 = 1; //外部中断0负跳变中断
- }
- /*************定时器0初始化程序***************/
- void init_time0();
- /*****************主函数********************/
- void main()
- {
- beep = 0; //开机蜂鸣器叫一声
- delay_1ms(200);
- P0 = P1 = P2 = P3 = 0xff; //初始化IO口
- init_int0();
- init_time0(); //初始化定时器
- init_ds1302(); //ds1302初始化
- init_1602(); //lcd1602初始化
- write_string(1,0," : : W: ");
- write_string(2,0," 20 - - ");
- while(1)
- {
- key(); //按键程序
- hongwai_dis();
- if(key_can < 10)
- {
- beep = 0;
- delay_1ms(50);
- beep = 1;
- key_with();
- }
- key_can = 11;
- if(flag_200ms == 1)
- {
- flag_200ms = 0;
- if(menu_1 == 0)
- {
- read_time(); //读时间
- init_1602_ds1302(); //显示时钟
- }
- if(flag_moshi == 0) //自动模式
- if(menu_1 == 0)
- menu_dis(); //开关函数
- }
- delay_1ms(1);
- }
- }
- /*************定时器0初始化程序***************/
- void init_time0()
- {
- TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
- TH0=0x00; //重载值
- TL0=0x00; //初始化值
- ET0=1; //开中断
- TR0=1;
- }
- void time0() interrupt 1
- {
- static unsigned int num;
- irtime++; //用于计数2个下降沿之间的时间
- num++;
- if(num>=600)
- {flag_200ms=1;}
- }
- /*****************红外解码程序********************/
- void int0() interrupt 0
- {
- static unsigned char i; //接收红外信号处理
- static bit startflag; //是否开始处理标志位
-
- if(startflag)
- {
- if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
- i=0;
- irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
- irtime=0;
- i++;
- if(i==33)
- {
- irok=1;
- i=0;
- }
- }
- else
- {
- irtime=0;
- startflag=1;
- }
- }
- /*------------------------------------------------
- 红外码值处理
- ------------------------------------------------*/
- void Ircordpro(void)//红外码值处理函数
- {
- unsigned char i, j, k;
- unsigned char cord,value;
- k=1;
- for(i=0;i<4;i++) //处理4个字节
- {
- for(j=1;j<=8;j++) //处理1个字节8位
- {
- cord=irdata[k];
- if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
- value|=0x80;
- if(j<8)
- {
- value>>=1;
- }
- k++;
- }
- IRcord[i]=value;// 四个字节每个字节依次放在数组里
- value=0;
- }
- irpro_ok=1;//处理完毕标志位置1
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
源程序.zip
(85.75 KB, 下载次数: 192)
|