机械工程学院 小学期 电子实践论文 参赛课题:健康节能台灯
摘要 在现代城市中,随着人口和能源消耗的急剧增长,总用电量也在日益增加,要是没有节能措施,便会造成能源枯竭的不良后果。同时,人们长期久坐也会带来一系列的健康问题。因此,健康智能台灯便有了其设计的必要性。 本课程设计的任务就是设计一个健康智能台灯系统。鼓励学生在熟悉基本原理的前提下,与实际应用相联系,提出自己的方案,完善设计。 该设计是以 AT89C52 单片机为控制核心的集多种功能于一体的健康智能台灯。该台灯实现了自动检测桌前是否有人并自动开启/关闭功能;台灯光亮度具有手动\自动调节功能;具有时间显示功能;整点报时功能。硬件设计分为单片机控制模块、按键模块、台灯模块、时钟模块、报时模块、温度检测模块、显示模块,红外传感模块等七个部分。单片机控制就用 AT89C52,温度检测模块由DS18B20 完成,显示模块用数码管显示时间、日期及温度,按键模块用来调整时间、日期等,台灯模块自制的电路,用蜂鸣器发出整点报时,检测人的用FC-51避障模块。软件设计用单片机 C 语言编写,实现了全部控制功能。
目录
摘要2
目录3
第一章LED台灯功能描述及总体方案4
11功能描述4
12系统组成及工作过4
第二章硬件设计4
21单片机控制模块设4
22按键模块电路设5
23台灯模块电路设6
24时钟模块电路设7
25报时模块电路设7
26 温度模块程序设计8
27 红外传感器模块电路设计8
第三章软件设计9
31 主程序的设计9
32 按键模块程序设计9
33 台灯模块程序设计9
34 时钟模块程序设计9
35 报时模块程序设计9
36 温度模块程序设计10
37 红外传感器模块程序设计10
第四章总结10
实物图11
系统连接图12
附录13
第一章 LED 台灯功能描述及总体该方案
1.1 功能描述 根据主要功能要求,该设计利用 51 单片机实现了电子时钟、温度的显示以 及整点报时等功能。具体可分为一下几种: 1) 显示当前的日期及时间,24 时制的时、分、秒; 2) 可调节时间; 3) 整点报时并响铃。 4) 能检测桌前是否有人并自动开启/关闭; 5) 可自动\手动调节灯光亮度;
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;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载(仿真+源码+论文):
http://www.51hei.com/bbs/dpj-111625-1.html
|