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

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. ........................
相关推荐
喝醉酒的小白37 分钟前
PG最大连接数
数据库
Y123chang42 分钟前
学生表的DDL和DML
数据库·sql
程序员在线炒粉8元1份顺丰包邮送可乐1 小时前
已解决:macOS Navicat保存密码失败(Failed to save password Error code: -34018),错误代码34018
数据库·mysql·macos
disalong1 小时前
使用ig507金融数据库的股票API接口经验有感:Java与Python
java·数据库·金融·股票接口·股票api
文刀小桂1 小时前
详解 ClickHouse 的建表优化
大数据·数据库·clickhouse
ing657682 小时前
艺体培训机构管理系统的设计
java·数据库·spring boot·后端·课程设计
丁大校·2 小时前
用MySQL和navicatpremium做一个项目—(财务管理系统)。
数据库·mysql
Martin_wjc2 小时前
9. proxy sql实现读写分离
数据库·mysql·proxy sql
黑风风2 小时前
MySQL锁和使用
数据库·mysql
子非吾喵2 小时前
Spring系统学习 - 基于注解管理Bean
数据库·学习·spring