找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

单片机光敏电阻自动调光器--不能自动进行调光了(台灯)

查看数: 4957 | 评论数: 8 | 收藏 2
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2019-10-27 12:27

正文摘要:

该产品时在那个宝上买的(是散件)现在实验板是测试,怎么也测试不过,重新做好电路依然如此。 对硬件已经做了全部的测试,以可以确定电路没有问题,芯片也没有坏。现在的状况如下: 1,按按键进入自动调光下不起 ...

回复

ID:713781 发表于 2020-4-6 16:55
wulin 发表于 2019-11-1 14:51
原来的程序有缺陷,这是优化过的程序。如果再把按键程优化为短按加/减,长按连加/减更好。

我试了一下,按键没反应啊,你工程文件还在吗
ID:713781 发表于 2020-3-31 13:14
这个仿真要怎么看啊,怎么看出亮度变化呢
ID:213173 发表于 2019-11-1 14:51
本帖最后由 wulin 于 2019-11-1 20:56 编辑
247015164 发表于 2019-10-28 20:37
就是不知道为什么不能进入到自动调光的模式
原来的程序有缺陷,这是优化过的程序。如果再把按键程优化为短按加/减,长按连加/减更好。
  1. //头函数
  2. #include <reg52.h>               
  3. //宏定义
  4. #define uint unsigned int
  5. #define uchar unsigned char
  6. //uchar pdata tt[51];          //定义空数组用于AD0832取平均值
  7. uchar data  tt[51];
  8. uchar scale,rsd_sec;         //定义占空比比例,热释电计时秒变量
  9. uchar sec;
  10. bit flag_auto=0,flag_rsd=0;//位定义自动切换,热释电动作标志

  11. //uint lum;                    //ad0832读出值
  12. uchar m;
  13. uchar n;
  14. //管脚声明
  15. sbit LED = P2^5;                        //灯光控制输出
  16. sbit rsd = P1^5;                                  //热释电
  17. sbit qiehuan=P3^7;                                //手动/自动切换
  18. sbit add=P3^6;                                                //增加
  19. sbit dec=P3^5;                                                //减小

  20. sbit CS=P1^3;                //CS定义脚,连接ADC0832CS脚
  21. sbit SCL=P1^0;               //SCL定义脚,连接ADC0832SCL脚
  22. sbit DO=P1^1;                //DO定义脚,连接ADC0832DO脚

  23. /*****************延时函数:大约1ms************************/
  24. /*
  25. void delay(uchar i)
  26. {
  27.   uchar j,k;
  28.   for(j=i;j>0;j--)
  29.     for(k=125;k>0;k--);
  30. }*/
  31. /***********读数模转换数据********************************************************/        
  32. //请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,
  33. //本函数是模拟0832的串行协议进行的
  34. uchar ad0832read(bit SGL,bit ODD)
  35. {
  36.         uchar i=0,value=0,value1=0;               
  37.         SCL=0;
  38.         DO=1;
  39.         CS=0;                //开始
  40.         SCL=1;                //第一个上升沿        
  41.         SCL=0;
  42.         DO=SGL;
  43.         SCL=1;          //第二个上升沿
  44.         SCL=0;
  45.         DO=ODD;
  46.         SCL=1;            //第三个上升沿
  47.         SCL=0;            //第三个下降沿
  48.         DO=1;
  49.         for(i=0;i<8;i++)
  50.         {
  51.                 SCL=1;
  52.                 SCL=0; //开始从第四个下降沿接收数据
  53.                 value<<=1;
  54.                 if(DO)
  55.                         value++;
  56.         }
  57.         for(i=0;i<8;i++)
  58.         {                        //接收校验数据
  59.                 value1>>=1;
  60.                 if(DO)
  61.                         value1+=0x80;
  62.                 SCL=1;
  63.                 SCL=0;
  64.         }
  65.         CS=1;
  66.         SCL=1;        
  67.         if(value==value1) //与校验数据比较,正确就返回数据,否则返回0        
  68.                 return value;
  69.         return 0;
  70. }
  71. /*****************按键函数*****************/
  72. void work()
  73. {
  74.         static bit key_sign1=0,key_sign2=0,key_sign3=0;        //按键自锁标志
  75.         static uchar count1=0,count2=0,count3=0;                //计数变量       
  76.         uint lum_mean,lum_all;
  77.         uchar b,c;       
  78.         if(qiehuan==0)              //自动切换按键按下
  79.         {
  80.                 if(++count1==100&&key_sign1==0)           //再次判断按键按下
  81.                 {
  82.                         key_sign1=1;
  83.                         flag_auto=~flag_auto; //自动模式标志位取反
  84.                         if(flag_auto==1)      //当切换到手动模式时  首先将LED发光比例设置在50%
  85.                                 scale=20;
  86.                 }
  87.         }
  88.         else          //按键释放
  89.         {
  90.                 key_sign1=0;
  91.                 count1=0;
  92.         }
  93.         if(flag_auto==1)
  94.         {
  95.                 if(add==0)               //加键按下
  96.                 {
  97.                         if(++count2==100&&key_sign2==0)
  98.                         {
  99.                                 key_sign2=1;
  100.                                 if(scale<41)//灯光比例++
  101.                                         scale++;
  102.                         }
  103.                 }
  104.                 else          //按键释放
  105.                 {
  106.                         key_sign2=0;
  107.                         count2=0;
  108.                 }
  109.                 if(dec==0)               //减键按下时
  110.                 {
  111.                         if(++count3==100&&key_sign3==0)
  112.                         {
  113.                                 key_sign3=1;        
  114.                                 if(scale>1)//灯光比例--
  115.                                         scale--;
  116.                         }
  117.                 }
  118.                 else          //按键释放
  119.                 {
  120.                         key_sign3=0;
  121.                         count3=0;
  122.                 }
  123.         }
  124.         else
  125.         {
  126.                 if(flag_rsd==1)          //有人在范围内时
  127.                 {         
  128.                         for(b=0;b<49;b++)     //将空数组tt[]内数值整体左移一位
  129.                         {
  130.                                 tt[b]=tt[b+1];     //将后一数值放到前一位置
  131.                         }        
  132.                         tt[49] = ad0832read(1,0);//将读出的ad数值放入tt[49]
  133.                         for(c=0;c<50;c++)     //将tt[]内数值相加
  134.                         {
  135.                                 lum_all=lum_all+tt[c];
  136.                         }
  137.                         lum_mean=lum_all/50;  //将总数/50取出平均值
  138.                         lum_all=0;            //将总数清零
  139.                         if(lum_mean<=30) scale=1;//判断取出平均值大小  小于30  发光强度0%
  140.                         else if(lum_mean>=150) scale=41;//大于150  发光强度100%
  141.                         else scale=((lum_mean-30)/3)+1;//其他值时将其计算得到发光强度 (计算目的是为了得到一个1-41之间的数值 控制灯光变化)        
  142.                 }
  143.                 else
  144.                 {
  145.                         scale=1;               //没有人在范围内时 将灯光亮度调至0%
  146.                 }        
  147.         }
  148. }
  149. /*********定时器初始化函数**********/
  150. void init()
  151. {
  152.         TMOD=0x12;                   //T1方式1,T0方式2
  153.         TH1=0x3c;
  154.         TL1=0xb0;                    //T1赋初值50ms
  155.         TH0=0xce;                                                  //8位自动重载
  156.         TL0=0xce;                    //T0赋初值50us         
  157.         ET0=1;
  158.         ET1=1;                       //打开中断允许开关
  159.         EA=1;                        //中断总开关
  160.         TR0=1;
  161.         TR1=1;                       //定时器定时开关
  162. }

  163. /****************主函数**********************/
  164. void main()
  165. {
  166.         init();                     //调用初始化函数       
  167.         while(1)                    //循环
  168.         {
  169.                 work();                 //调用函数
  170.         }
  171. }

  172. /******************定时器T0服务函数:脉冲发生函数*******************/
  173. void time0() interrupt 1
  174. {
  175. //        TH0=0xff;
  176. //        TL0=0xe7;                 //重新赋初值
  177.         n++;                      //每50us  n++
  178.         if(n<scale)               //n<设置比例时,打开灯
  179.         {
  180.                 LED=0;
  181.         }
  182.         else if(n>=scale)//n大于等于设置比例时 关闭灯
  183.         {
  184.                 LED=1;
  185.         }
  186.         if(n>=40)                 //n==40  :50us*40=2ms   500HZ
  187.         {
  188.                 n=0;                 //n=0
  189.         }
  190. }  
  191. /********************定时器T0服务函数:计时和闪烁控制********************/
  192. void time1() interrupt 3
  193. {
  194.         TH1=0x3c;
  195.         TL1=0xb0;                 //重新赋初值
  196.         if(rsd==1)
  197.         {
  198.                 flag_rsd=1;
  199.                 rsd_sec=0;
  200.                 m=0;
  201.         }
  202.         else
  203.         {
  204.                 m++;                      //50ms  m++
  205.                 if(m==20)                 //到达1s时
  206.                 {
  207.                         m=0;                  //m=0
  208.                         rsd_sec++;            //热释电计时秒++
  209.                         if(rsd_sec>=20)       //热释电计时秒小于等于20 并且 热释电有信号时
  210.                         {
  211.                                 flag_rsd=0;       //标志位置0 停止ad0832转换 关闭灯光
  212.                                 rsd_sec=0;        //热释电计时秒清零
  213.                         }
  214.                 }
  215.         }
  216. }
复制代码




ID:213173 发表于 2019-11-1 11:33
247015164 发表于 2019-10-28 20:37
就是不知道为什么不能进入到自动调光的模式

仿真查看确实不能自动调光,临时屏蔽滤波部分可以自动调光,说明AD转换没有问题。更改缓冲数组uchar pdata tt[51]; 为  uchardata tt[51];,一切正常。


ID:585365 发表于 2019-10-28 20:37
就是不知道为什么不能进入到自动调光的模式
ID:213173 发表于 2019-10-27 19:52
不知道硬件电路。单从程序看,T0中断中的uchar n;明显不妥,应该是static uchar n;或声明全局变量。但不像是导致不能自动进行调光的主因,需要配合热释电部分判断AD转换是否正常。
ID:190577 发表于 2019-10-27 17:06
电路图有吗?提供下

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

Powered by 单片机教程网

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