找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 21296|回复: 23
收起左侧

51单片机智能调光台灯电路原理图+程序设计

  [复制链接]
ID:483213 发表于 2019-3-24 11:58 | 显示全部楼层 |阅读模式
1.功能介绍

      智能台灯可分成自动和手动两种模式。在自动模式下,台灯能根据环境光的亮暗与人是否被台灯所检测到(人是否在)来自动开启台灯。当人被微机检测到,环境光又达到某个程度的时候(可以设定与调节),台灯就会开启。如果环境光没有达到这个程度,台灯不会开启。当人没有被微机检测到,无论多暗,台灯也不会开。  手动模式是为了不习惯使用自动模式的人或是台灯中的微机出故障等紧急情况时用的。在手动模式下,智能台灯和普通台灯是一样使用的。
主要功能 :
(1)亮度不够且有人靠近时台灯自动亮;
(2)靠的太近会提醒坐姿不正(蜂鸣器)
(3)附近无人时台灯自动熄灭(30秒)  时间可调
(4)根据环境亮度调节等亮度
(5)可手动调节台灯亮度
(6)设定学习时间

2.硬件设计
(1)总体硬件设计
      整体硬件电路是以AT89C52单片机为控制核心,主要由热释电红外传感器,光敏电阻信号处理电路,提醒电路,灯光控制电路,故障报警电路等组成。单片机可将热释电红外传感器检测到的人体辐射红外信号及光强信号的模拟量转换成数字量。
1.jpg

(2)LED驱动电路
2.jpg
      LED驱动电路采用3路串联、每路4颗的LED灯,使用三极管S8050来控制LED灯的亮灭。在软件上采用PWM控制方式,以此达到控制LED灯的亮度。

(3)光敏感应电路
3.jpg
       对于台灯亮度的感应采用了光敏电阻,利用光敏电阻的阻值随着亮度的改变而改变,电阻值的改变会改变光敏电阻上的电压值。这时,通过AD转换器采集电压,转换成相应的光强数据传输给单片机。
4.jpg

(4)人体感应电路
5.jpg
      人体感应电路采用了HC-SR501基于红外线技术的数字传感器。当传感器感应到人体时,传感器IO引脚输出高电平;当无人体时,传感器输出低电平。

(5)红外接近传感器
6.jpg
       红外接近传感器采用了E18- D80NK数字型传感器,检测到目标是低电平输出,正常状态是高电平输出;此传感器的功能为检测用户是否坐于台灯前。

3.软件设计
(1)数码管驱动程序
  1. #define DUAN P0                                  //数码管段位
  2. sbit W0=P2^7;                //数码管位端
  3. sbit W1=P2^6;
  4. sbit W2=P2^5;
  5. sbit W3=P2^4;

  6. /**********************************************************************
  7. * 名称 : display();
  8. * 功能 : 数码管显示
  9. * 输入 : 无
  10. * 输出 : 无
  11. ***********************************************************************/         
  12. void display()
  13. {
  14.         if(flag_set==0)                           //正常模式下
  15.         {
  16.                 DUAN=tab[min/10];           //送入段码,秒数高位
  17.                 W0=0;                                   //打开位地址
  18.                 delay(1);                           //小延时
  19.                 W0=1;                                   //关闭位地址
  20.                 DUAN=tab_dian[min%10]; //送入段码,秒数低位
  21.                 W1=0;
  22.                 delay(1);
  23.                 W1=1;
  24.                 DUAN=tab[sec/10];           //送入段码,分钟数高位
  25.                 W2=0;
  26.                 delay(1);
  27.                 W2=1;
  28.                 DUAN=tab[sec%10];           //送入段码,分钟数高位
  29.                 W3=0;
  30.                 delay(1);
  31.                 W3=1;
  32.         }
  33.         else if(flag_set==1)           //设置模式下闪烁相应位
  34.         {
  35.                 if(ss==1)                           //闪烁标志  ss=1 正常显示
  36.                 {
  37.                         DUAN=~tab[min/10];
  38.                         W0=0;
  39.                         delay(1);
  40.                         W0=1;
  41.                         DUAN=~tab_dian[min%10];
  42.                         W1=0;
  43.                         delay(1);
  44.                         W1=1;
  45.                 }
  46.                 else                                   //闪烁标志  ss=0 熄灭相应位 达到闪烁效果         ss在定时器里500ms取反一次
  47.                 {
  48.                         DUAN=~tab[10];           //
  49.                         W0=0;
  50.                         delay(1);
  51.                         W0=1;
  52.                         DUAN=~tab_dian[10];
  53.                         W1=0;
  54.                         delay(1);
  55.                         W1=1;
  56.                 }
  57.                 DUAN=~tab[sec/10];
  58.                 W2=0;
  59.                 delay(1);
  60.                 W2=1;
  61.                 DUAN=~tab[sec%10];
  62.                 W3=0;
  63.                 delay(1);
  64.                 W3=1;
  65.         }
  66.         else
  67.         {
  68.                 DUAN=~tab[min/10];
  69.                 W0=0;
  70.                 delay(1);
  71.                 W0=1;
  72.                 DUAN=~tab_dian[min%10];
  73.                 W1=0;
  74.                 delay(1);
  75.                 W1=1;
  76.                 if(ss==1)
  77.                 {
  78.                         DUAN=~tab[sec/10];
  79.                         W2=0;
  80.                         delay(1);
  81.                         W2=1;
  82.                         DUAN=~tab[sec%10];
  83.                         W3=0;
  84.                         delay(1);
  85.                         W3=1;
  86.                 }
  87.                 else
  88.                 {
  89.                         DUAN=~tab[10];
  90.                         W2=0;
  91.                         delay(1);
  92.                         W2=1;
  93.                         DUAN=~tab[10];
  94.                         W3=0;
  95.                         delay(1);
  96.                         W3=1;
  97.                 }
  98.         }
  99. }
复制代码

(2)按键驱动程序
  1.     sbit change= P2^3;        //自动模式切换按键
  2.     sbit set = P2^2;        //设置按键
  3.     sbit add = P2^1;        //加按键
  4.     sbit sub = P2^0;        //减按键

  5.     /**********************************************************************
  6.     * 名称 : KEY();
  7.     * 功能 : 按键控制
  8.     * 输入 : 无
  9.     * 输出 : 无
  10.     ***********************************************************************/
  11.     void KEY()
  12.     {
  13.             uint lum_mean,lum_all;
  14.             uchar b,c;
  15.             if(change==0)                                  //自动切换按键按下
  16.             {
  17.                     delay(10);                                  //去抖
  18.                     if(change==0)                          //再次判断按键按下
  19.                     {
  20.                             buzz=0;                                  //蜂鸣器鸣响
  21.                             flag_auto=!flag_auto; //自动模式标志位取反
  22.                             if(flag_auto==1)          //当切换到手动模式时  首先将LED发光比例PWM设置在50%
  23.                             scale=20;
  24.                     }
  25.                     while(!change) display();buzz=1; //等待按键释放  松开按键后关闭蜂鸣器、刷新显示
  26.             }
  27.             if(jiejin==0&&flag_jiejin==1) //接近传感器检测到障碍时  开启报警
  28.             {
  29.                     buzz=0;
  30.                     flag_jiejin=0;
  31.             }
  32.             if(jiejin!=flag_jiejin)              //接近传感器检测不到障碍时  关闭报警
  33.             {
  34.                     buzz=1;
  35.                     flag_jiejin=1;
  36.             }
  37.             if(set==0)                                      //设置键按下时
  38.             {
  39.                     delay(10);
  40.                     if(set==0)
  41.                     {
  42.                             buzz=0;
  43.                             flag_set++;                          //设置变量++
  44.                             if(flag_set==3)                  //加到3时回复回正常模式
  45.                             flag_set=0;
  46.                             flag_bs=0;                          //按下设置 关闭报警
  47.                     }
  48.                     while(!set) display(); buzz=1;//等待按键释放  松开按键后关闭蜂鸣器、刷新显示
  49.             }
  50.             if(flag_set==1)                                          //加键按键只有在设置状态(flag_set!=0)时按下才有效          调分
  51.             {                                                                 
  52.                     if(add==0)                                          //加按键按下时
  53.                     {
  54.                             delay(10);                                  //消抖
  55.                             if(add==0)
  56.                             {
  57.                                     buzz=0;                                  //蜂鸣器响
  58.                                     min++;                                  //分++
  59.                                     if(min>=60)
  60.                                     min=0;
  61.                             }
  62.                             while(!add) display(); buzz=1;         //等待按键释放  松开按键后关闭蜂鸣器、刷新显示
  63.                     }
  64.                     if(sub==0)                                          //减按键按下时
  65.                     {
  66.                             delay(10);                                  //消抖
  67.                             if(sub==0)
  68.                             {
  69.                                     buzz=0;                                  //蜂鸣器响
  70.                                     min--;                                  //分--
  71.                                     if(min>0)
  72.                                     min=59;
  73.                             }
  74.                             while(!sub) display(); buzz=1;         //等待按键释放  松开按键后关闭蜂鸣器、刷新显示
  75.                     }
  76.             }
  77.             if(flag_set==2)                                        //调秒
  78.             {                                                               
  79.                     if(add==0)                                        //加键按下
  80.                     {                                                
  81.                             delay(10);                                //消抖
  82.                             if(add==0)
  83.                             {
  84.                                     buzz=0;                                //蜂鸣器响
  85.                                     sec++;                                //秒++
  86.                                     if(sec>=60)
  87.                                     sec=0;
  88.                             }
  89.                             while(!add) display(); buzz=1;          //等待按键释放  松开按键后关闭蜂鸣器、刷新显示
  90.                     }
  91.                     if(sub==0)                                         //减键按下
  92.                     {
  93.                             delay(10);
  94.                             if(sub==0)                                 //消抖
  95.                             {
  96.                                     buzz=0;                                 //蜂鸣器响
  97.                                     sec--;                                 //秒--
  98.                                     if(sec<0)
  99.                                     sec=59;
  100.                             }
  101.                             while(!sub) display();        buzz=1;          //等待按键释放  松开按键后关闭蜂鸣器、刷新显示
  102.                     }
  103.                     while(!sub);
  104.             }
  105.             if(flag_auto==0)                                        //自动模式
  106.             {
  107.                     if(flag_rsd==1)                                        //且有人在范围内时        环境发光强度控制灯光变化
  108.                     {
  109.                             for(b=0;b<49;b++)                         //将空数组tt[]内数值整体左移一位
  110.                             {
  111.                                     tt[ b]=tt[b+1];                        //将后一数值放到前一位置
  112.                             }
  113.                             tt[49]=ADC0809();                        //将读出的ad0809数值放入tt[49]
  114.                             for(c=0;c<50;c++)                        //将tt[]内数值相加
  115.                             {
  116.                                     lum_all=lum_all+tt[c];
  117.                             }
  118.                             lum_mean=lum_all/50;                //将总数/50取出平均值
  119.     //                        lum_all=0;                                        //将总数清零
  120.                             if(lum_mean<=30) scale=1;                           //判断取出平均值大小  小于30  发光强度0%
  121.                             else if(lum_mean>=150) scale=41;           //大于150  发光强度100%
  122.                             else scale=((lum_mean-30)/3)+1;                   //其他值时将其计算得到发光强度 (计算目的是为了得到一个1-41之间的数值 控制灯光变化)
  123.                     }
  124.                     else
  125.                     scale=1;                                         //没有人在范围内时 将灯光亮度调至0%
  126.             }
  127.             else                                                           //手动模式下
  128.             {
  129.                     if(flag_set==0)                                 //正常模式下
  130.                     {
  131.                             if(add==0)                                 //加键按下
  132.                             {
  133.                                     delay(10);
  134.                                     if(add==0)
  135.                                     {
  136.                                     //        buzz=0;           //蜂鸣器响
  137.                                             scale++;                  //灯光比例++
  138.                                             if(scale>=41)
  139.                                             scale=41;
  140.                                             display();
  141.                                     }
  142.                             //        while(!add) display();        buzz=1;
  143.                             }
  144.                             if(sub==0)                                  //减键按下时
  145.                             {
  146.                                     delay(10);
  147.                                     if(sub==0)
  148.                                     {
  149.                                     //        buzz=0;                           //蜂鸣器响
  150.                                             scale--;                   //灯光比例--
  151.                                             if(scale>1)
  152.                                             scale=1;
  153.                                             display();
  154.                                     }
  155.                     //                while(!sub) display(); buzz=1;
  156.                             }
  157.                     }
  158.             }
  159.     }
复制代码
(3)ADC控制程序
  1. #define Data_ADC0809 P1
  2. //ADC0809 控制引脚定义
  3. sbit ST=P3^1;
  4. sbit EOC=P3^2;
  5. sbit OE=P3^3;

  6. extern uchar ADC0809();           //函数声明
  7. /**********************************************************************
  8. * 名称 : ADC0809();
  9. * 功能 : ADC0809把模拟量转化为八位数字量
  10. * 输入 : 无
  11. * 输出 : 无
  12. ***********************************************************************/
  13. uchar ADC0809()
  14. {
  15.         uchar temp_=0x00;        
  16.         OE=0;                 //初始化高阻态           转化初始化   低电平,禁止输出允许
  17.         ST=0;
  18.         ST=1;                 //上升沿 清零   
  19.         ST=0;                 //下降沿 开始转换
  20.         while(EOC==0);            //外部中断 等待AD转换结束        EOC为1时AD转换结束跳出
  21.         OE=1;                                  //高电平,输出允许
  22.         temp_=Data_ADC0809;        //读取转换的AD值
  23.         OE=0;                                //低电平,禁止输出允许
  24.         return temp_;                //返回ADC读取值
  25. }
复制代码

(4)LED亮度控制程序
  1. //管脚声明
  2. sbit LED = P3^4;        //PWM输出
  3. sbit change= P2^3;        //自动模式切换按键
  4. sbit rsd = P3^6;    //热释电
  5. sbit jiejin=P3^5;   //接近开关
  6. sbit buzz=P3^7;     //蜂鸣器报警电路
  7. /**********************************************************************
  8. * 名称 : init();
  9. * 功能 : 初始化定时器
  10. * 输入 : 无
  11. * 输出 : 无
  12. ***********************************************************************/
  13. void init()
  14. {
  15.         TMOD=0x11;           //工作方式1
  16.         TH1=0x3c;
  17.         TL1=0xb0;           //T1赋初值50ms
  18.         TH0=0xff;
  19.         TL0=0xe7;           //T0赋初值25us         
  20.         ET0=1;
  21.         ET1=1;                   //打开中断允许开关
  22.         EA=1;                   //中断总开关
  23.         TR0=1;                   //开定时器0 开关
  24.         TR1=0;                   //关定时器0 开关
  25. }

  26. /**********************************************************************
  27. * 名称 : void time0() interrupt 1
  28. * 功能 : 定时器T0 中断服务函数:PWM脉冲发生函数
  29. * 输入 : 无
  30. * 输出 : 无
  31. ***********************************************************************/
  32. void time0() interrupt 1
  33. {
  34.         uchar n;
  35.         TH0=0xff;
  36.         TL0=0xe7;                 //重新赋初值
  37.         n++;                         //每25us  n++
  38.         if(n>scale)                 //n<设置比例时,打开灯
  39.         {
  40.                 LED=1;
  41.         }
  42.         else if(n<=scale)//n大于等于设置比例时 关闭灯
  43.         {
  44.                 LED=0;
  45.         }
  46.         if(n==40)                 //n==40  :25us*40=1ms   1kHZ
  47.         {
  48.                 n=0;                 //n=0
  49.         }
  50.         else ;        
  51. }

  52. /**********************************************************************
  53. * 名称 : void time1() interrupt 3
  54. * 功能 : 定时器T1 中断服务函数:计时和闪烁控制          红外热释
  55. * 输入 : 无
  56. * 输出 : 无
  57. ***********************************************************************/
  58. void time1() interrupt 3
  59. {
  60.         uchar m;
  61.         TH1=0x3c;
  62.         TL1=0xb0;                 //重新赋初值
  63.         m++;                         //50ms  m++
  64.         if((m==10||m==20)&&flag_set!=0)          //每过500ms  并且 在设置状态时
  65.         {
  66.                 ss=!ss;                                                  //闪烁变量取反
  67.         }
  68.         if(m==20)                                                  //到达1s时
  69.         {
  70.                 m=0;                                                  //m=0
  71.                 if(rsd==0)                                          //热释电无信号时
  72.                 rsd_sec++;                                          //热释电计时秒++
  73.                 if(rsd_sec<=30&&rsd==1)                  //热释电计时秒小于等于30 并且 热释电有信号时
  74.                 {
  75.                         rsd_sec=0;                                  //将热释电秒清零
  76.                         flag_rsd=1;                                  //标志位置1 控制AD0809采集数值 调节灯光亮度
  77.                 }
  78.                 else if(rsd_sec>30&&rsd==0)          //热释电计时秒大于30 并且 热释电无信号时
  79.                 {
  80.                         flag_rsd=0;                                  //标志位置0 停止ad0809转换 关闭灯光
  81.                         rsd_sec=0;                                  //热释电计时秒清零
  82.                 }
  83.                 if(flag_set==0&&flag_bs==0&&((min+sec)!=0))                 //正常模式下&&未报警&&定时时间不为零时
  84.                 {
  85.                         sec--;
  86.                         if(sec<0)                                                                         //定时秒--  小于0时
  87.                         {
  88.                                 sec=59;                                                                         //复位到59秒
  89.                                 min--;                                                                         //分--
  90.                         }
  91.                         if(min<=0&&sec==0)                                                         //分和秒都减到零时
  92.                         {
  93.                                 min=0;
  94.                                 flag_bs=1;
  95.                                 buzz=0;                                                                         //蜂鸣器报警提示时间到
  96.                         }
  97.                 }
  98. //                else buzz=1;        
  99.         }        
  100. }
复制代码


(5)主函数
  1. /**********************************************************************
  2. * 名称 : main();
  3. * 功能 : 主函数
  4. * 输入 : 无
  5. * 输出 : 无
  6. ***********************************************************************/
  7. void main()
  8. {
  9.         init();                  //调用初始化函数
  10.         flag_auto=1;  //初始化手动模式
  11.         rsd=0;                  //热释电引脚置低(有信号时时高电平)
  12.         delay(500);          //延时500ms后开机

  13.         while(1)          //大循环
  14.         {
  15.                 KEY();                 //调用按键函数
  16.                 display();         //调用显示函数
  17.         }
  18. }
复制代码
源码+AD电路图资料51hei下载地址:
智能台灯.rar (244.17 KB, 下载次数: 492)

评分

参与人数 2黑币 +60 收起 理由
a1075511750 + 10 很好
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:110278 发表于 2019-3-25 10:09 | 显示全部楼层
很不错的设计
回复

使用道具 举报

ID:487422 发表于 2019-4-2 15:13 | 显示全部楼层
太强了,我找这个找好久,一直在思考怎么加学习时间功能
回复

使用道具 举报

ID:497335 发表于 2019-5-8 14:03 来自手机 | 显示全部楼层
想要仿真图
回复

使用道具 举报

ID:532850 发表于 2019-5-11 01:05 | 显示全部楼层
能请教下lum_mean平均数为什么是all除以50得到的?这个50怎么来的?谢谢
回复

使用道具 举报

ID:546802 发表于 2019-5-25 20:42 | 显示全部楼层
这个和不错
回复

使用道具 举报

ID:548584 发表于 2019-5-27 17:57 | 显示全部楼层
ljx944848837 发表于 2019-4-2 15:13
太强了,我找这个找好久,一直在思考怎么加学习时间功能

你下载了没?
回复

使用道具 举报

ID:579808 发表于 2019-7-17 20:22 | 显示全部楼层
为什么仿真不出来
回复

使用道具 举报

ID:651341 发表于 2019-12-8 12:15 | 显示全部楼层
程序怎么有好多错误
回复

使用道具 举报

ID:676283 发表于 2019-12-29 18:15 | 显示全部楼层
这个压缩包里面都有哪些内容呢
回复

使用道具 举报

ID:65956 发表于 2019-12-30 09:05 | 显示全部楼层
根据你提供的原理来看,可省去检测光敏的芯片,用MCU自身的ADC功能代替就行了
回复

使用道具 举报

ID:758116 发表于 2020-5-22 18:05 | 显示全部楼层
有仿真吗?
回复

使用道具 举报

ID:781931 发表于 2020-6-18 11:27 | 显示全部楼层
楼主的东西很有用 真好
回复

使用道具 举报

ID:785330 发表于 2020-6-21 11:54 | 显示全部楼层
很nice,谢了大佬
回复

使用道具 举报

ID:797466 发表于 2020-8-11 20:26 来自手机 | 显示全部楼层
两个USB借口都是什么作用的
回复

使用道具 举报

ID:797466 发表于 2020-8-11 20:33 来自手机 | 显示全部楼层
小YY嘿 发表于 2019-5-27 17:57
你下载了没?

小哥哥能加加好友问几个问题吗?

回复

使用道具 举报

ID:846087 发表于 2020-11-25 22:38 | 显示全部楼层
仿真在哪里
回复

使用道具 举报

ID:733976 发表于 2020-12-18 15:45 | 显示全部楼层

楼主的东西很有用 真好
回复

使用道具 举报

ID:712560 发表于 2021-3-30 18:38 | 显示全部楼层
很好的贴子,正在学数码管
回复

使用道具 举报

ID:712560 发表于 2021-3-30 18:38 | 显示全部楼层
正在学数码管显示,很不错
回复

使用道具 举报

ID:97678 发表于 2021-3-31 08:22 | 显示全部楼层
这么强大的功能! 学习一下!
回复

使用道具 举报

ID:92810 发表于 2021-6-8 16:44 | 显示全部楼层
谢谢楼主分享了,先下载写来学习
回复

使用道具 举报

ID:935260 发表于 2021-6-9 10:14 | 显示全部楼层
aking991 发表于 2019-12-30 09:05
根据你提供的原理来看,可省去检测光敏的芯片,用MCU自身的ADC功能代替就行了

问题是一般的51没有啊,STC的可能有
回复

使用道具 举报

ID:942388 发表于 2021-6-22 13:26 来自手机 | 显示全部楼层
gemxie 发表于 2021-6-8 16:44
谢谢楼主分享了,先下载写来学习

请问这个压缩包怎么下载
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表