找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6186|回复: 2
收起左侧

单片机自动感应环境光的调光控制器程序+电路设计

[复制链接]
ID:559365 发表于 2019-6-12 14:59 | 显示全部楼层 |阅读模式
1)设计一个环境光亮度检测电路,并根据环境亮度进行台灯光照强度的自动调节;
2)采用多只LED指示亮度等级,环境亮度达到最高时,自动关闭;
3)拓展部分:具有LED数码显示亮度等级功能;
4)安装、调试电路,记录调零、测试的数据,进行测试、分析。

2.1 设计的总体方案
无论LED是经由降压、升压、降压/升压或线性稳压器驱动,连接每一个驱动电路最常见的线程就是须要控制光的输出。。目前,针对亮度控制方面,主要的两种解决方案为线性调节LED的电流(模拟调光)或在肉眼无法察觉的高频下,让驱动电流从0到目标电流值之间来回切换(数字调光)。利用脉冲宽度调变(PWM)来设定循环和工作周期可能是实现数字调光的最简单的方法。
PWM方法的基本思想是利用单片机具有的PWM端口,在不改变PWM方波周期的前提下,通过软件的方法调整单片机的PWM控制寄存器来调整PWM的占空比,从而控制充电电流。本方法把设定的充电电流与实际读取到的充电电流进行比较,若实际电流偏小则向增加充电电流的方向调整PWM的占空比,LED灯光度变亮;若实际电流偏大则向减小充电电流的方向调整PWM的占空比,LED灯光度变暗。本文介绍了以STC12C5A60S2为控制核心,通过光敏电阻感应光度,并利用PWM调光技术对LED进行光度的自动调节。
2.2 设计的总体构思及框图
基于STC单片机的PWM调光是以STC12C5A60S2作为主控芯片,设置了手动控制和自动控制。在手动控制时,分为三档,输出不同的PWM占空比对LED的电流进行控制,从而实现了对光度的手动调节。在自动控制时,通过STC12C5A60S2内部模拟-数字不断检验光敏电阻的电压来间接测量感应光度,将电压和预设的阈值进行对比,调整PWM的占空比对LED的电流进行控制,从而实现了对光度的自动调节。如图2-1所示为设计的总体框图。

图2-1 总体框图

第3章 系统硬件电路设计

3.1 STC12C5A60S2单片机简介
STC12C5A60S2是STC生产的单时钟/机器周期(1T)的单片机,是高速、低功耗、超强抗干扰的新一代8051单片机,指令代码完全兼容传统8051,但速度快8-12倍。内部集成MAX810专用复位电路,2路PWM,8路高速10位A/D转换,针对电机控制,强干扰场合。

    利用STC12C5A60S2的IO口P1.1接收光敏电阻采集的当前光照测检测输出数据。IO口P1.3产生产生相应的PWM波,给高亮度LED,从而有不同的光照。IO口P0作为LCD液晶显示器的数据/指令输入端口。

STC12C5A60S2单片机的时钟电路采用的是内部的时钟电路,利用单片机内部的振荡电路,并在XLAT1和XLAT2两引脚间外接石英晶体和电容构成的并联谐振电路,使内部振荡器产生自激振荡。石英晶体Y1频率是12.0M,C1和C2是30pf。STC12C5A60S2单片机最小系统线路图如图3-1所示。

      

  图3-1  STC12C5A60S2单片机最小系统线路图

3.2 A/D转换电路
A/D转换是用来通过一定的电路将模拟量转变为数字量。模拟量可以是电压、电流等电信号,也可以是压力、温度、湿度、位移、声音等非电信号。但在A/D转换前,输入到A/D转换器的输入信号必须经各种传感器把各种物理量转换成电压信号。

将模拟量或连续变化的量进行量化(离散化),转换为相应的数字量的电路。 A/D变换包含三个部分:抽样、量化和编码。一般情况下,量化和编码是同时完成的。 抽样是将模拟信号在时间上离散化的过程; 量化是将模拟信号在幅度上离散化的过程; 编码是指将每个量化后的样值用一定的二进制代码来表示。

采集光照强度运用光敏电阻和电位器来构成信号采集电路。AD转换电路有STC12内部10位AD组成。STC125A60S2内部AD基准电压5V,输入电压范围为0~5V,输出数字量最大值为1024。如图3-2所示为信号采集电路。

图3-2 信号采集电路
3.3 LED驱动
脉宽调制(PWM)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换及LED照明等许多领域中。通过以数字方式控制模拟电路,可以大幅度降低系统的成本和功耗。LED器件对驱动电源的要求近乎于苛刻,LED不像普通的白炽灯泡,可以直接连接220V的交流市电。LED是2~3伏的低电压驱动,必须要设计复杂的变换电路,不同用途的LED灯,要配备不同的电源适配器。
电流控制LED的亮度,通过控制电流调节LED灯的亮度。利用公式i*t/T可知,利用调整PWM不同的占空比t/T就可以控制电流的大小。电流由三极管9013提供驱动,PWM由P1.3输出,低电平有效。如图3-3所示为PWM电路。

         

图3-3 PWM电路

3.4 LCD显示电路
1602采用标准的16脚接口,本设计当前光照采用的是LCD1602显示检测信息。所以单片机需要给LCD分配3位个控制信号IO口和8位数据传输IO口,LCD的EN控制端连接P2.2,RS控制端连接P2.0,RW控制端连接P2.1,8位据总线连接PO口。如图3-4所示为LCD电路。

         

图3-4 LCD电路

3.5 按键切换手动和自动
K3按下为自动控制,K4按下为手动控制,来回按K3、K4切换。当手动按键按下时,K1为LED亮度增加,当增加到最大值自动为最小,K2为LED亮度减小,当减少到最小值时自动为最大。
按键电路的工作原理:芯片的控制器通过读取I/O口的信息(可采用逐位读入,或者整个字节读入的方法),来判断哪一个按键被按下(或哪几个按键被同时按下),按下按键时I/O位的信息为”高电位“。然后根据内部设定的判断,转去执行相应的程序。如图3-5所示为按键电路:

            

图3-5 按键电路

3.6 光敏电阻
光敏电阻器是利用半导体的光电导效应制成的一种电阻值随入射光的强弱而改变的电阻器,又称为光电导探测器;入射光强,电阻减小,入射光弱,电阻增大。还有另一种入射光弱,电阻减小,入射光强,电阻增大。
光敏电阻器一般用于光的测量、光的控制和光电转换(将光的变化转换为电的变化)。常用的光敏电阻器硫化镉光敏电阻器,它是由半导体材料制成的。光敏电阻器对光的敏感性(即光谱特性)与人眼对可见光(0.4~0.76)μm的响应很接近,只要人眼可感受的光,都会引起它的阻值变化。设计光控电路时,都用白炽灯泡(小电珠)光线或自然光线作控制光源,使设计大为简化。光敏电路如图3-6所示:

  

   图3-6 光敏电路

3.7 电源设计

电源电路是指提供给用电设备电力供应的电源部分的电路设计,使用的电路形式和特点。常见的电源电路有交流电源电路、直流电源电路等。

此次采用 78XX系列固定三端稳压器稳压,三端正稳压电路,能提供多种固定的输出电压,应用范围广,内含过流,过热和过载保护电路。降压稳压部分由三端稳压管7805、电解电容组成,将9V转换成稳定的5V。如图3-7所示为电源电路。

   

图3-7 电源电路

第4章 系统软件设计

4.1 系统流程图
  此次系统软件设计利用信号采集电路读取当前亮度,并通过程序及系统判断其亮度是否大于设定亮度,是则减小PWM输出,否则增大PWM输出,通过程序所得PWM值调节LED亮度,从而控制系统达到调光功能。程序流程图如图4-1所示:

图4-1 程序流程图

4.2 系统程序

  1. #include" STC12c5a.h" //stc头文件
  2. #include"intrins.h" //包含_nop_空操作的定义
  3. typedef unsigned char uchar;
  4. typedef unsigned int  uint;
  5. sbit RW=P2^1;//写入时一直为低电平,读出时为高。
  6. sbit RS=P2^0; //指令数据选择端
  7. sbit LCDEN=P2^2;//使能端
  8. sbit key1=P3^0;
  9. sbit key2=P3^1;
  10. sbit key3=P3^2;
  11. sbit key4=P3^3;
  12. uchar j=0;
  13. void AD_init();//AD初始化
  14. //函数声明
  15. void delay(uint a);
  16. uint AD_work(uchar channel);
  17. uint  AD_get(uchar channel);
  18. uchar disbuf[]=" illumin: .    ";
  19. uchar PWM[]={0xec,0xe7,0xe0,0xda,0xd3,0xcd,0xc0,0xa6,0x9a,0x80,0x33,0x00} ;              //                92.5%-0%
  20. void pwm_set(unsigned char a);
  21. void pwm_init()
  22. {
  23. CCON=0; //PCA初始化
  24. CH=0;                //PCA              高8位
  25. CL=0;                //PCA              低8位
  26. CMOD=0x00;  //f=sysclk/256/12
  27. CCAPM0=0x42;              //p1.3
  28. PCA_PWM0=0x00;
  29. CR=1;  //启动PCA计数器
  30. }
  31. void pwm_set(unsigned char a)              //占空比设置
  32. {
  33. CCAP0H=CCAP0L=a;
  34. }
  35. void write_com(uchar com )
  36. {
  37. RS=0;
  38. RW=0;
  39. LCDEN=0;
  40. P0=com ;
  41. delay(5);
  42. LCDEN=1;
  43. delay(5);
  44. LCDEN=0;
  45. }
  46. void write_dat(uchar date)
  47. {
  48. RW=0;
  49. RS=1;
  50. LCDEN=0;
  51. P0=date;
  52. delay(5);
  53. LCDEN=1;
  54. delay(5);
  55. LCDEN=0;
  56. }
  57. //液晶初始化
  58. void LCDinit()
  59. {
  60. write_com(0x0c);
  61. write_com(0x06);
  62. write_com(0x01);
  63. write_com(0x38);
  64. }
  65. void  display(unsigned int z)
  66. {
  67. uchar i;
  68. disbuf[9]=z%1000/100+0x30;
  69. disbuf[11]=z%100/10+0x30;
  70. disbuf[12]=z%10+0x30;
  71. for(i=0;i<13;i++)
  72. write_dat(disbuf[i]);
  73. }
  74. void main()
  75. {
  76. AD_get(1);
  77. AD_init(); //A/D转换初始化
  78. LCDinit(); //液晶初始化
  79. pwm_init();//照度检测
  80. pwm_set(0xda);
  81. delay(200);
  82. while(1)
  83. {
  84. write_com(0x80);
  85. display(AD_work(1));
  86. if(key3==0)
  87. {
  88. delay(5);
  89. if(key3==0)                                                                                    //自动模式
  90. {
  91. while(key4==1)
  92. {
  93. write_com(0x80);
  94. display(AD_work(1));
  95. if(AD_work(1)>=900)
  96. pwm_set(0xEC);                 
  97. if((850<=AD_work(1))&&(AD_work(1)<900))
  98. pwm_set(0xE7);
  99. if((750<=AD_work(1))&&(AD_work(1)<850))
  100. pwm_set(0xe0);
  101. if((700<=AD_work(1))&&(AD_work(1)<750))
  102. pwm_set(0xda);
  103. if((600<=AD_work(1))&&(AD_work(1)<700))
  104. pwm_set(0xd3);
  105. if((500<=AD_work(1))&&(AD_work(1)<600))
  106. pwm_set(0xCD);
  107. if((400<=AD_work(1))&&(AD_work(1)<500))
  108. pwm_set(0xC0);
  109. if((300<=AD_work(1))&&(AD_work(1)<400))
  110. pwm_set(0xA6);
  111. if((200<=AD_work(1))&&(AD_work(1)<300))
  112. pwm_set(0x9A);
  113. if((150<=AD_work(1))&&(AD_work(1)<200))
  114. pwm_set(0x80);
  115. if((100<=AD_work(1))&&(AD_work(1)<150))
  116. pwm_set(0x33);
  117. if(AD_work(1)<100 )
  118. pwm_set(0x00);
  119. }
  120. }
  121. }
  122. if(key4==0)                                                                                    // 手动模式
  123. {
  124. delay(5);
  125. if(key4==0)
  126. {
  127. while(key3==1)
  128. {
  129. write_com(0x80);
  130. display(AD_work(1));
  131. if(key1==0)
  132. {
  133. delay(5);
  134. if(key1==0)
  135. {
  136. if(j==11)
  137. j=0;
  138. pwm_set((PWM[j++]));
  139. }
  140. }
  141. if(key2==0)
  142. {
  143. delay(5);
  144. if(key2==0)
  145. {
  146. if(j==0)
  147. j=11;
  148. pwm_set((PWM[j--]));
  149. }
  150. }
  151. }
  152. }
  153. }
  154. }
  155. }
  156. uint AD_get(uchar channel)
  157. {
  158. ADC_CONTR=0x88|channel;    //开启AD转换1000 1000 即POWER SPEED1 SPEED0 ADC_FLAG   ADC_START CHS2 CHS1 CHS0
  159. _nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器
  160. while(!(ADC_CONTR&0x10));    //等待转换完成
  161. ADC_CONTR&=0xe7;      //关闭AD转换,ADC_FLAG位由软件清0
  162. return(ADC_RES*4+ADC_RESL);   //返回AD转换完成的10位数据(16进制)
  163. }
  164. /*unsigned char GETADCResult()//AD转换
  165. {
  166. unsigned char AD;
  167. ADC_CONTR=ADC_POWER|ADC_SPEEDHH|ADC_START;
  168. _nop_();
  169. _nop_();
  170. _nop_();
  171. _nop_();
  172. while(!(ADC_CONTR&ADC_FLAG));
  173. ADC_CONTR&=~ADC_FLAG;//关闭AD
  174. Vo=ADC_RES*5*10/256              ;
  175. return Vo;
  176. }
  177. uint AD_work(uchar channel)
  178. {
  179. float AD_val;     //定义处理后的数值AD_val为浮点数
  180. uchar i;
  181. uint AD_V;
  182. for(i=0;i<100;i++)
  183. AD_val+=AD_get(channel); //转换100次求平均值(提高精度)
  184. AD_val/=100;
  185. AD_V=(uint)AD_val;
  186. return AD_V;
  187. }
  188. void delay(uint a) //延时约1ms
  189. {
  190. uint i;
  191. while (--a!=0)
  192. for(i=600;i>0;i--);   //1T单片机i=600,若是12T单片机i=125
  193. }
  194. void AD_init()
  195. {
  196. P1ASF=0x02; //P1.1 作为模拟功能AD使用                                                                                                
  197. ADC_RES=0;   //清零转换结果寄存器高8位
  198. ADC_RESL=0; //清零转换结果寄存器低2位
  199. ADC_CONTR=0x80;//开启AD电源
  200. delay(2);   //等待1ms,让AD电源稳定
  201. ES=1;
  202. EA=1;
  203. }
复制代码

第5章 系统仿真及调试
5.1 软件调试
软件程序设计对单片机的I/O接口的控制,智能光控台灯主要通过光控电路对光的感应以达到输出端口的控制,在黑暗时光控部分输出高电平,通过单片机内部程序的控制以光控输出高电平为准,给输出端口定义低电平,台灯是以低电平有效,当单片机输出端达到低电平时台灯亮。
5.2 系统仿真
系统的硬件及软件都已经调试完成,然后利用protues进行系统仿真。在仿真中,利用光敏电阻模拟天黑天亮,用滑动变阻器来调整光亮的强度。
仿真图如图5-1所示。

   

图5-1 光照强度强仿真图

然后,调整光敏电阻阻值,使之达到天黑的效果。此时,单片机控制台灯亮,仿真效果图如图5-2所示。

图5-2 光照强度弱仿真图


完整的Word格式文档51黑下载地址:

自动感应环境光的调光控制器.docx (202.95 KB, 下载次数: 73)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:585365 发表于 2019-9-16 20:15 | 显示全部楼层
谢谢楼主的分享
回复

使用道具 举报

ID:713781 发表于 2020-3-30 15:24 | 显示全部楼层
求楼主程序头文件
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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