找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2833|回复: 8
收起左侧

单片机按键调光程序,调光正常,但就是不能关灯

[复制链接]
ID:585365 发表于 2019-10-17 19:36 | 显示全部楼层 |阅读模式
#include "reg52.h"                //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;          //对数据类型进行声明定义
typedef unsigned char u8;

sbit k1=P1^0;
sbit k2=P1^1;
sbit led=P0^0;
sbit k3=P1^2;
u16 count,value,timer1;

void delayms(u16 ms)
{
        int i,j;
        for(i=ms;i>0;i--)
                for(j=110;j>0;j--);
}
void Timer1Init()
{
        TMOD|=0X10;//选择为定时器1模式,工作方式1,仅用TR1打开启动。

        TH1 = 0xFF;
        TL1 = 0xff;   //1us

        ET1=1;//打开定时器1中断允许
        EA=1;//打开总中断
        TR1=1;//打开定时器                        
}

void tiaoguang()
{
if(count>100)                                                        
                {  
                        count=0;
                        if(k1==0)                                //DIR控制增加
                        {
                          value++;
                        }                        
                        if(k2==0)
                        {
                          value--;
                        }

                }                                                                                                                                    

                if(value>=990)
                {
                 value=990;
                }
                if(value<=10)
                {
                  value=10;
                }            

                if(timer1>1000)  //PWM周期为1000*1us
                {
                        timer1=0;
                }

                if(timer1 <value)        
                {
                        led=1;               
                }
                else
                {
                        led=0;
                }        
}



void main()
{        
        u8 a;
        Timer1Init();  //定时器1初始化
        while(1)
        {
                        if(k3==0)
                        {
                          delayms(10);
                                if(k3==1)
                                        a++;
                                if(a>1)
                                        a=0;
                        }
                                switch(a)        
                {
                        case(0): tiaoguang() ;break;//恢复亮度
                        case(1): led=0 ;break;//熄灭LED

                }        
        }               
}


void Time1(void) interrupt 3    //3 为定时器1的中断号  1 定时器0的中断号 0 外部中断1 2 外部中断2  4 串口中断
{
        TH1 = 0xFF;
        TL1 = 0xff;   //1us
        timer1++;
    count++;

}
程序运行的时候不能关灯,用实验板进行实验的,调光正常,但就是不能关灯,不明白哪里错了,像大神们请教下

回复

使用道具 举报

ID:213173 发表于 2019-10-18 06:56 | 显示全部楼层
错误1.k3是控制亮灭,你不可能在10ms内做到if(k3==0)--delayms(10)--if(k3==1),所以不可能有a++;
错误2.定时器1中断设置1us,但是完成中断内指令需要16us,CPU没有时间正常执行主循环任务
回复

使用道具 举报

ID:138097 发表于 2019-10-18 08:09 | 显示全部楼层
PWM好像就是无法关灯,以前我也关不了。你可以调节PWM的频率使其关灯啊,调到最小不是和关灯一个现象吗
回复

使用道具 举报

ID:616759 发表于 2019-10-18 09:00 | 显示全部楼层
变量的定义最好赋初值,然后你的k3==1的时候的按键抖动延时没有设,看你k1,k2的抖动延时也没有设,除了这些暂时还没看出有什么不妥当的地方,主要我对中断这个定义不熟,没办法通篇理解程序
回复

使用道具 举报

ID:259898 发表于 2019-10-18 10:07 | 显示全部楼层
按键要延时抖动
回复

使用道具 举报

ID:259898 发表于 2019-10-18 10:08 | 显示全部楼层
按键要延时抖动
回复

使用道具 举报

ID:585365 发表于 2019-10-27 09:31 | 显示全部楼层
更正,经过调试,如果想要按k3关闭led的灯光可以将主程序判断k3==1处改为k3==0 如下:
void main()
{        
        u8 a;
        Timer1Init();  //定时器1初始化
        while(1)
        {
                        if(k3==0)
                        {
                          delayms(10);
                                if(k3==0)
                                        a++;
                                if(a>1)
                                        a=0;
                        }
                                switch(a)        
                {
                        case(0): tiaoguang() ;break;//恢复亮度
                        case(1): led=0 ;break;//熄灭LED

                }        
        }               
}
现在还有一个问题是,在调暗led灯是在20%的亮度左右会闪烁。我看了下有人说做进中断里就可以解决。但不太了解运行的方式(程序)
望各位可以指导一下。谢谢
回复

使用道具 举报

ID:585365 发表于 2019-10-27 09:31 | 显示全部楼层
在硬件上,开关是做了处理的了,程序里就不在写延时了
回复

使用道具 举报

ID:140489 发表于 2019-11-4 15:29 | 显示全部楼层
  1. //短按开关灯,开灯状态下,长按调光         2019/10/22 调试完成
  2. #include<reg51.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char

  5. sbit OUT=P1^1;//  P1.1输出pwm
  6. sbit OUT1=P1^2;//  P1.1输出pwm
  7. //sbit LED3=P1^7;//  

  8. sbit KEY1 = P3^0;

  9. #define const_key_time1 100   //短按去抖动延时的时间
  10. #define const_key_time2 2000  //长按延时的时间

  11. uint uiKeyTimeCnt1=0; //按键去抖动延时计数器
  12. uint uiKeyTimeCnt2=0; //调光速度变量
  13. uint uiKeyTimeCnt3=0; //调光速度变量
  14. uchar ucKeyLock1=0;   //按键触发后自锁的变量标志
  15. uchar pwm_t;              //pwm周期
  16. bit flag;                      //调光加减标志
  17. uchar pwm_led_val = 50;//LED占空比值
  18. bit flag1;                                //开关灯标志
  19. bit flag2;                                //短按触发标志
  20. bit flag3;                                //长按调光启停标志

  21. void keyscan()
  22. {
  23.         if(KEY1==1)        //按键没按下 要及时清零一些标志
  24.         {

  25.                 ucKeyLock1=0;   //按键自锁标志清零
  26.                 uiKeyTimeCnt1=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。
  27.                 flag3=0;                //长按松手,停止调光
  28.                 if(flag2 == 1)        //短按触发标志
  29.                 {
  30.                         flag2=0;
  31.                         flag1 = !flag1;//开关灯标志,松手后才开灯
  32.                 }
  33.        
  34.         }
  35.         else if(ucKeyLock1==0)//按键按下,且是第一次感应
  36.         {       
  37.                 ++uiKeyTimeCnt1;  //延时计数器
  38.                 if(uiKeyTimeCnt1>const_key_time1)//短按
  39.                 {       
  40.                         flag2 = 1;//
  41.                         OUT= OUT1=0; //按下就把灯打开
  42.                 }               
  43.                 if(uiKeyTimeCnt1>const_key_time2)//长按
  44.                 {
  45.                        
  46.                         flag2=0;                //清除短按标志
  47.                         ucKeyLock1=1; //自锁按键置位,避免一直触发
  48.        
  49.                         uiKeyTimeCnt1=0;
  50.        
  51.                         flag3=1;  //启动调光
  52.                        
  53.                 }
  54.         }
  55.        
  56. //------------------调光-----------------------       
  57.         if(flag3)
  58.         {
  59.                 ++uiKeyTimeCnt2;  //延时计数器
  60.                 if(uiKeyTimeCnt2==100)
  61.                 {
  62.                         uiKeyTimeCnt2=0;
  63. //                        ++uiKeyTimeCnt3;
  64. //                        if(uiKeyTimeCnt3==10)//10ms调一步,此处调节调光速度,值越大,调光越慢
  65.                         {

  66.                                  uiKeyTimeCnt3=0;
  67.                      if(flag == 0)
  68.                       {
  69.        
  70.                          if(pwm_led_val < 100)
  71.        
  72.                           {
  73.                               pwm_led_val++;        //亮度变暗
  74.        
  75.                               if(pwm_led_val==99)//此处赋值100可以调灭
  76.                                   flag = 1;
  77.                           }
  78.                       }
  79.        
  80.                       if( flag ==1 )
  81.                       {
  82.                           if(pwm_led_val > 0)
  83.                           {
  84.                               pwm_led_val--;        //亮度变亮
  85.                               if(pwm_led_val==0)//
  86.                                   flag = 0;
  87.                           }
  88.                       }               
  89.                          }
  90.                 }
  91.         }
  92.        
  93. }


  94. void main()
  95. {
  96.         TMOD |= 0x02;        //设置定时器模式 8为自动重装
  97.         TL0 = 0xF7;                //设置定时初值        10us   @11.0592M
  98.         TH0 = 0xF7;                //设置定时重载值
  99.     EA=1;//开总中断
  100.     ET0=1;//开定时器0中断
  101.     TR0=1;//启动定时器0
  102. //        LED3=0;
  103.     while(1)
  104.     {
  105.                 keyscan();
  106.     }                        
  107. }

  108. void tim0() interrupt 1
  109. {
  110.         if(flag1)

  111.         {
  112.                 pwm_t++;
  113.                 if(pwm_t==100)//周期1ms   频率1000Hz
  114.                 {pwm_t=0;}
  115.                 if( pwm_led_val < pwm_t )
  116.                 {OUT = 0; OUT1 = !OUT;}
  117.                 else {OUT=1; OUT1 = !OUT;}
  118.         }
  119.         else OUT=OUT1=1;

  120. //        if(flag3)
  121. //        {
  122. //                ++uiKeyTimeCnt2;  //延时计数器
  123. //                if(uiKeyTimeCnt2==100)
  124. //                {
  125. //                        uiKeyTimeCnt2=0;
  126. //                        ++uiKeyTimeCnt3;
  127. //                        if(uiKeyTimeCnt3==10)//10ms调一步,此处调节调光速度,值越大,调光越慢
  128. //                        {
  129. //
  130. //                                 uiKeyTimeCnt3=0;
  131. //                     if(flag == 0)
  132. //                      {
  133. //       
  134. //                         if(pwm_led_val < 100)
  135. //       
  136. //                          {
  137. //                              pwm_led_val++;        //亮度变暗
  138. //       
  139. //                              if(pwm_led_val==99)//此处赋值100可以调灭
  140. //                                  flag = 1;
  141. //                          }
  142. //                      }
  143. //       
  144. //                      if( flag ==1 )
  145. //                      {
  146. //                          if(pwm_led_val > 0)
  147. //                          {
  148. //                              pwm_led_val--;        //亮度变亮
  149. //                              if(pwm_led_val==0)//
  150. //                                  flag = 0;
  151. //                          }
  152. //                      }               
  153. //                         }
  154. //                }
  155. //        }

  156. }
复制代码
看我这个程序,你就知道怎么关灯了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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