1.1 功能描述
根据主要功能要求,该设计利用 51 单片机实现了电子时钟、温度的显示以
及整点报时等功能。具体可分为一下几种:
- 显示当前的日期及时间,24 时制的时、分、秒;
- 可调节时间;
- 整点报时并响铃。
- 能检测桌前是否有人并自动开启/关闭;
- 可自动\手动调节灯光亮度;
1.2 系统组成及工作过程
六大模块以 AT89C52单片机为控制核心,实现了该智能台灯的各项要求,外接一个5V 的直流电源,为整个系统供电。
2 硬件设计
2.1 单片机控制模块设计
硬件电路如图 2
图 2 单片机控制模块电路(最小系统)
这里我们选用 12M 的晶振,晶振系统由两个 30pF 的电容 CAP 和晶振组成,
接到单片机的 18、19 两管脚。晶振给单片机提供硬件本身的时钟振荡。一个 10μF
的电解电容和一个 1k 的电阻组成复位电路,接至单片机的第 9 管脚。P0 口加上
排阻,即其就是 P0 口的上拉电阻,这就是给 P0 加驱动电路,电源通过排阻向
P0 口供电,使其能够驱动与 P0 口相连的元件。
2.2 按键模块电路设计
按键模块电路
三个按键分别用来选取需要调节的数码管、增加数值及减少数值,即设置日期时间当前。
两个开关控制灯电路的开通或是关闭状态,上方以开关代替模拟FC-51模块的状态(proteus中无相似元件),当模块检测到有人时输出低电平;下方开关为手动开关(开关灯)。
按键及开关均采用低电平有效连接方式。
2.3 台灯模块电路设计
台灯模块电路如图 4,
3.1 主程序的设计
主程序流程图
主程序如图,一给单片机上电,单片机就初始化。然后扫描各个按键、开关的状态,检测开关是否打开、屋内是否有人,若同时满足则给台灯电路上电。同时向数码管输出时间初值,随后时间计时子函数运行,时钟正常工作。然后检测时间调整按键是否按下,判断修改哪个数据,扫描调整按键,增加或减少数值。单片机接收并处理来自 DS18B20 传过来的数据在数码管上显示当时的室内温度,最后进入循环。
3.2 按键模块程序设计
按键用来调整时间和日期,各键功能在介绍硬件部分已描述。
因为有年月日,时分秒几个参数要调,所以设置这几个参数的计数。当按模式
键时,单片机进行相应的操作。
3.3 台灯模块程序设计
该模块只需给 P3.6 到送高电平即可,再通过手动旋钮\环境光强调整灯光亮度。
3.4 时钟模块程序设计
分别出写时间、日期的函数,再写出时间、日期的显示函数。设计时、分、
秒,年、月、日几个变量分别表示时分秒,年月日。
3.5 报时模块程序设计
对蜂鸣器,在其所接的 I/O 口P3.3写 1 即可实现它的蜂鸣,当分钟数增加到60时响铃,写程序时给它加了个1s延时,实现整点报时。
3.6 温度模块程序设计
设计初始化函数,设计读 DS18B20 数据和对 DS118B20 写数据的函数,再写出
从 DS18B20 读温度并转换为十进制的函数,最后逐位显示温度的函数。
3.7 红外传感器模块程序设计
编写一个读端口P3.4的函数,即FC-51模块OUT端口状态,检测有人与否,若有人,传感器发给单片机一个低电平,单片机同时判断灯开关是否打开,使得单片机P3.6口为高电平,控制台灯电路上电;若人离开桌前,则P3.4为高电平,台灯断电。这就实现了检测屋内有人与否并自动开启或关闭的智能节能的台灯。
4 总结
该设计实现了日期、时间及温度检测和显示电路,具备整点报时功能,以提醒用户久坐时长,避免长期久坐导致的一系列健康问题。同时自动检测桌前是否有人并自动开启/关闭功能;台灯具有光亮度自动\手动调节功能;但在细节
方面还有不足之处。灯光亮度达不到很亮的程度,只能在一个很小的范围变化,
以致于光亮度不够。关闭的功能。该传感器检测距离通过调节FC-1模块上变阻器可在1m-20m间调节。蜂鸣器在仿真过程中不响,多次排查后仍没有找到原因,在设计答辩完成后,我们会继续寻找问题的源头,争取解决。在实际的实物制作过程中,因材料的限制,触发台灯所用的三极管使用了双向可控硅代替,这带来了一系列问题:1可控硅的参数不明,导致了变阻器在调节过程中无法精确到具体值,只能不断尝试2可控硅的负载能力小,使得灯在长时间运行后出现过载现象,自动熄灭。
原本的设计是只有台灯电路,毕竟节能台灯的节能应考虑设计简化,但为提升本次设计作业的复杂性,加入了更多其他模块,虽有些本末倒置的意味,但锻炼了我们的动手能力、单片机编程能力,更提升了我们对MC-51系列单片机、数码管及DS18B20 的了解与认识,为以后的毕业设计及往后的工作打下经验基础。
以上的程序见附录
实物图
仿真及实物演示视频见设计文件
系统连接图
附录
单片机源程序如下:
- #define uchar unsigned char
- #define uint unsigned int
- #define DQ P3_7
- #include<AT89X51.H>
- uint sec;
- uint min=05;
- uint hour=13;
- uint day=19;
- uint month=7;
- uint yearl=17;
- uint yearh=20;
- uint tcnt;
- uint cursor=0;
- uchar a=0xff;
- uchar code Seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- void delay(uint t)
- {
- uint i;
- while(t--)
- {for (i=0;i<125;i++);}
- }
- void Tdelay(unsigned int i)
- {
- while(i--);
- }
- void Kdelay()
- {
- uchar i,j;
- for(i=100;i>0;i--)
- for(j=248;j>0;j--);
- }
- Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1;
- Tdelay(8);
- DQ = 0;
- Tdelay(80);
- DQ = 1;
- Tdelay(14);
- Tdelay(20);
- }
- //读一个字节
- ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0;
- dat>>=1;
- DQ = 1;
- if(DQ)
- dat|=0x80;
- Tdelay(4);
- }
- return(dat);
- }
- //写一个字节
- WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- Tdelay(5);
- DQ = 1;
- dat>>=1;
- }
- }
- //读取温度
- ReadTemperature(void)
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned int t=0;
- float tt=0;
- Init_DS18B20();
- WriteOneChar(0xCC);
- WriteOneChar(0x44);
- Init_DS18B20();
- WriteOneChar(0xCC);
- WriteOneChar(0xBE);
- a=ReadOneChar();
- b=ReadOneChar();
- t=b;
- t<<=8;
- t=t|a;
- tt=t*0.0625;
- t= tt*10+0.5;
- return(t);
- }
- void display(uchar L1,uchar L2,uchar L3,uchar L4,uchar L5,uchar L6,uchar L7,uchar L8,uchar L9,uchar L10,uchar L11,uchar L12,uchar L13,uchar L14,uchar L15,uchar L16)
- {
- P2=0x7F;P0=L1;delay(1); //yearh
- P2=0xBF;P0=L2;delay(1); //yearh
- if(cursor==6){P2=0xDF|a;P0=L3;delay(1);}else{P2=0xDF;P0=L3;delay(1);} //yearl
- if(cursor==6){P2=0xEF|a;P0=L4;delay(1);}else{P2=0xEF;P0=L4;delay(1);} //yearl
- if(cursor==5){P2=0xF7|a;P0=L5;delay(1);}else{P2=0xF7;P0=L5;delay(1);} //month
- if(cursor==5){P2=0xFB|a;P0=L6;delay(1);}else{P2=0xFB;P0=L6;delay(1);} //month
- if(cursor==4){P2=0xFD|a;P0=L7;delay(1);}else{P2=0xFD;P0=L7;delay(1);} //day
- if(cursor==4){P2=0xFE|a;P0=L8;delay(1);}else{P2=0xFE;P0=L8;delay(1);} //day
- P2=0xFF;
- if(cursor==3){P1=0x7F|a;P0=L9;delay(1);}else{P1=0x7F;P0=L9;delay(1);} //hour
- if(cursor==3){P1=0xBF|a;P0=L10;delay(1);}else{P1=0xBF;P0=L10;delay(1);} //hour
- if(cursor==2){P1=0xDF|a;P0=L11;delay(1);}else{P1=0xDF;P0=L11;delay(1);} //min
- if(cursor==2){P1=0xEF|a;P0=L12;delay(1);}else{P1=0xEF;P0=L12;delay(1);} //min
- if(cursor==1){P1=0xF7|a;P0=L13;delay(1);}else{P1=0xF7;P0=L13;delay(1);} //sec
- if(cursor==1){P1=0xFB|a;P0=L14;delay(1);}else{P1=0xFB;P0=L14;delay(1);} //sec
- P1=0xFD;P0=L15;delay(1); //temp
- P1=0xFE;P0=L16;delay(1); //temp
- P1=0xFF;
- }
- main()
- {
- uint i;
- TMOD=0x02; //设置模式为定时器T0的模式2 (8位自动重装计数初值的计数值)
- TH0=0x06; //设置计数器初值,靠TH0存储重装的计数值X0=256-250=6
- TL0=0x06;
- TR0=1; //启动T0
- ET0=1; //开启定时器T0中断允许
- EA=1; //开启中断总控制
- while(1)
- {
- if(P3_4==0)
- {if(P3_5==0)
- P3_6=1;}
- else P3_6=0;
- if(P3_0==0)
- {
- Kdelay();
- if(P3_0==0)
- {
- cursor++;
- if(cursor>=7){cursor=0;}
- }
- }
- if(P3_1==0)
- {
- Kdelay();
- if(P3_1==0)
- {
- if(cursor==1){sec++;if(sec==60)sec=0;}
- if(cursor==2){min++;if(min==60)min=0;}
- if(cursor==3){hour++;if(hour==24)hour=0;}
- if(cursor==4){day++;if(day==31)day=0;}
- if(cursor==5){month++;if(month==12)month=0;}
- if(cursor==6){yearl++;if(yearl==100)yearl=0;}
- if(cursor==7){yearh++;if(yearh==30)yearh=20;}
- }
- }
- if(P3_2==0)
- {
- Kdelay();
- if(P3_2==0)
- {
- if(cursor==1){sec--;}
- if(cursor==2){min--;}
- if(cursor==3){hour--;}
- if(cursor==4){day--;}
- if(cursor==5){month--;}
- if(cursor==6){yearl--;}
- if(cursor==7){yearh--;}
- }
- }
- i=ReadTemperature();
- display(Seg[yearh/10],Seg[yearh%10],Seg[yearl/10],Seg[yearl%10],Seg[month/10],Seg[month%10],Seg[day/10],Seg[day%10],Seg[hour/10],Seg[hour%10],Seg[min/10],Seg[min%10],Seg[sec/10],Seg[sec%10],Seg[i/100],Seg[i/10%10]);
- }
- }
- void t0(void)interrupt 1 using 0 //t0的中断程序
- {
- tcnt++;
- if(tcnt==4000)//定时器的定时计数,4000次250us为1秒
- {
- tcnt=0;
- P3_3=0;
- a=~a;
- sec++;
- if(sec==60)
- {
- sec=0;
- min++;
- if(min==60)
- {
- min=0;
- P3_3=1;
- hour++;
- if(hour==24)
- {
- hour=0;
- day++;
- if(month==2&&((yearl==0&&yearh%4==0)||(yearl!=0&&yearl%4==0))&&day==30)day=1;
- ........................