健康节能台灯的设计电子实践

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 的了解与认识,为以后的毕业设计及往后的工作打下经验基础。

以上的程序见附录

实物图


仿真及实物演示视频见设计文件

系统连接图

附录

单片机源程序如下:

  1. #define uchar unsigned char
  2. #define uint unsigned int
  3. #define DQ P3_7
  4. #include<AT89X51.H>
  5. uint sec;
  6. uint min=05;
  7. uint hour=13;
  8. uint day=19;
  9. uint month=7;
  10. uint yearl=17;
  11. uint yearh=20;
  12. uint tcnt;
  13. uint cursor=0;
  14. uchar a=0xff;
  15. uchar code Seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  16. void delay(uint t)
  17. {
  18. uint i;
  19. while(t--)
  20. {for (i=0;i<125;i++);}
  21. }
  22. void Tdelay(unsigned int i)
  23. {
  24. while(i--);
  25. }
  26. void Kdelay()
  27. {
  28. uchar i,j;
  29. for(i=100;i>0;i--)
  30. for(j=248;j>0;j--);
  31. }
  32. Init_DS18B20(void)
  33. {
  34. unsigned char x=0;
  35. DQ = 1;
  36. Tdelay(8);
  37. DQ = 0;
  38. Tdelay(80);
  39. DQ = 1;
  40. Tdelay(14);
  41. Tdelay(20);
  42. }
  43. //读一个字节
  44. ReadOneChar(void)
  45. {
  46. unsigned char i=0;
  47. unsigned char dat = 0;
  48. for (i=8;i>0;i--)
  49. {
  50. DQ = 0;
  51. dat>>=1;
  52. DQ = 1;
  53. if(DQ)
  54. dat|=0x80;
  55. Tdelay(4);
  56. }
  57. return(dat);
  58. }
  59. //写一个字节
  60. WriteOneChar(unsigned char dat)
  61. {
  62. unsigned char i=0;
  63. for (i=8; i>0; i--)
  64. {
  65. DQ = 0;
  66. DQ = dat&0x01;
  67. Tdelay(5);
  68. DQ = 1;
  69. dat>>=1;
  70. }
  71. }
  72. //读取温度
  73. ReadTemperature(void)
  74. {
  75. unsigned char a=0;
  76. unsigned char b=0;
  77. unsigned int t=0;
  78. float tt=0;
  79. Init_DS18B20();
  80. WriteOneChar(0xCC);
  81. WriteOneChar(0x44);
  82. Init_DS18B20();
  83. WriteOneChar(0xCC);
  84. WriteOneChar(0xBE);
  85. a=ReadOneChar();
  86. b=ReadOneChar();
  87. t=b;
  88. t<<=8;
  89. t=t|a;
  90. tt=t*0.0625;
  91. t= tt*10+0.5;
  92. return(t);
  93. }
  94. 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)
  95. {
  96. P2=0x7F;P0=L1;delay(1); //yearh
  97. P2=0xBF;P0=L2;delay(1); //yearh
  98. if(cursor==6){P2=0xDF|a;P0=L3;delay(1);}else{P2=0xDF;P0=L3;delay(1);} //yearl
  99. if(cursor==6){P2=0xEF|a;P0=L4;delay(1);}else{P2=0xEF;P0=L4;delay(1);} //yearl
  100. if(cursor==5){P2=0xF7|a;P0=L5;delay(1);}else{P2=0xF7;P0=L5;delay(1);} //month
  101. if(cursor==5){P2=0xFB|a;P0=L6;delay(1);}else{P2=0xFB;P0=L6;delay(1);} //month
  102. if(cursor==4){P2=0xFD|a;P0=L7;delay(1);}else{P2=0xFD;P0=L7;delay(1);} //day
  103. if(cursor==4){P2=0xFE|a;P0=L8;delay(1);}else{P2=0xFE;P0=L8;delay(1);} //day
  104. P2=0xFF;
  105. if(cursor==3){P1=0x7F|a;P0=L9;delay(1);}else{P1=0x7F;P0=L9;delay(1);} //hour
  106. if(cursor==3){P1=0xBF|a;P0=L10;delay(1);}else{P1=0xBF;P0=L10;delay(1);} //hour
  107. if(cursor==2){P1=0xDF|a;P0=L11;delay(1);}else{P1=0xDF;P0=L11;delay(1);} //min
  108. if(cursor==2){P1=0xEF|a;P0=L12;delay(1);}else{P1=0xEF;P0=L12;delay(1);} //min
  109. if(cursor==1){P1=0xF7|a;P0=L13;delay(1);}else{P1=0xF7;P0=L13;delay(1);} //sec
  110. if(cursor==1){P1=0xFB|a;P0=L14;delay(1);}else{P1=0xFB;P0=L14;delay(1);} //sec
  111. P1=0xFD;P0=L15;delay(1); //temp
  112. P1=0xFE;P0=L16;delay(1); //temp
  113. P1=0xFF;
  114. }
  115. main()
  116. {
  117. uint i;
  118. TMOD=0x02; //设置模式为定时器T0的模式2 (8位自动重装计数初值的计数值)
  119. TH0=0x06; //设置计数器初值,靠TH0存储重装的计数值X0=256-250=6
  120. TL0=0x06;
  121. TR0=1; //启动T0
  122. ET0=1; //开启定时器T0中断允许
  123. EA=1; //开启中断总控制
  124. while(1)
  125. {
  126. if(P3_4==0)
  127. {if(P3_5==0)
  128. P3_6=1;}
  129. else P3_6=0;
  130. if(P3_0==0)
  131. {
  132. Kdelay();
  133. if(P3_0==0)
  134. {
  135. cursor++;
  136. if(cursor>=7){cursor=0;}
  137. }
  138. }
  139. if(P3_1==0)
  140. {
  141. Kdelay();
  142. if(P3_1==0)
  143. {
  144. if(cursor==1){sec++;if(sec==60)sec=0;}
  145. if(cursor==2){min++;if(min==60)min=0;}
  146. if(cursor==3){hour++;if(hour==24)hour=0;}
  147. if(cursor==4){day++;if(day==31)day=0;}
  148. if(cursor==5){month++;if(month==12)month=0;}
  149. if(cursor==6){yearl++;if(yearl==100)yearl=0;}
  150. if(cursor==7){yearh++;if(yearh==30)yearh=20;}
  151. }
  152. }
  153. if(P3_2==0)
  154. {
  155. Kdelay();
  156. if(P3_2==0)
  157. {
  158. if(cursor==1){sec--;}
  159. if(cursor==2){min--;}
  160. if(cursor==3){hour--;}
  161. if(cursor==4){day--;}
  162. if(cursor==5){month--;}
  163. if(cursor==6){yearl--;}
  164. if(cursor==7){yearh--;}
  165. }
  166. }
  167. i=ReadTemperature();
  168. 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]);
  169. }
  170. }
  171. void t0(void)interrupt 1 using 0 //t0的中断程序
  172. {
  173. tcnt++;
  174. if(tcnt==4000)//定时器的定时计数,4000次250us为1秒
  175. {
  176. tcnt=0;
  177. P3_3=0;
  178. a=~a;
  179. sec++;
  180. if(sec==60)
  181. {
  182. sec=0;
  183. min++;
  184. if(min==60)
  185. {
  186. min=0;
  187. P3_3=1;
  188. hour++;
  189. if(hour==24)
  190. {
  191. hour=0;
  192. day++;
  193. if(month==2&&((yearl==0&&yearh%4==0)||(yearl!=0&&yearl%4==0))&&day==30)day=1;
  194. ........................
相关推荐
Channing Lewis15 分钟前
sql server如何创建表导入excel的数据
数据库·oracle·excel
秃头摸鱼侠15 分钟前
MySQL安装与配置
数据库·mysql·adb
UGOTNOSHOT20 分钟前
每日八股文6.3
数据库·sql
行云流水行云流水43 分钟前
数据库、数据仓库、数据中台、数据湖相关概念
数据库·数据仓库
John Song1 小时前
Redis 集群批量删除key报错 CROSSSLOT Keys in request don‘t hash to the same slot
数据库·redis·哈希算法
IvanCodes1 小时前
七、Sqoop Job:简化与自动化数据迁移任务及免密执行
大数据·数据库·hadoop·sqoop
tonexuan1 小时前
MySQL 8.0 绿色版安装和配置过程
数据库·mysql
JohnYan1 小时前
工作笔记- 记一次MySQL数据移植表空间错误排除
数据库·后端·mysql
我最厉害。,。2 小时前
Windows权限提升篇&数据库篇&MYSQL&MSSQL&ORACLE&自动化项目
数据库·mysql·sqlserver
远方16092 小时前
20-Oracle 23 ai free Database Sharding-特性验证
数据库·人工智能·oracle