标题: 使用单独按键实现渐亮渐灭 单片机程序有问题 [打印本页]

作者: daiwenping    时间: 2020-7-20 09:57
标题: 使用单独按键实现渐亮渐灭 单片机程序有问题
各位大虾,我是刚刚学单片机,如何使用单独按键实现渐亮渐灭(功能是用一个轻触开关,开灯时LED灯慢慢亮起和关灯时慢慢灭掉),我写程序但无法开关,为什么;
//功能为用S1控制LED渐亮渐灭//
#include <AT89X51.H>
unsigned char ID;
unsigned int T=500,Toff=0;
sbit LED=P1^0;         
sbit S1=P3^7;   
void no();
void off();
void Delay(unsigned int t);
void main(void)
{
   LED=1;
   while(1)
   {
     if(S1==0)
     {
       Delay(500);
       if(S1==0)
         {
          ID++;
          if(ID==2)
          {
           ID=0;
          }
           while(S1==0);
         }
      }
    switch(ID)
     {
      case 0:
      no();
      break;
      case 1:
      off();
      break;
      }
  }
}

/*以下为渐亮保持*/
void no (void)
{

     for(Toff=1;Toff<T;Toff++)  
      {
               LED=0;                    
               Delay(Toff);            
               LED=1;                  
              Delay(T-Toff);           
      }  

      LED=0;
         while (1);

}

/*以下为渐灭保持*/
void off (void)
{                        
   for(Toff=T-1;Toff>0;Toff--)   
    {
             LED=0;                     
             Delay(Toff);               
             LED=1;                    
            Delay(T-Toff);            
     }

      LED=1;
      while (1);
}
/*以下为延时函数*/
void Delay(unsigned int t)   
{                        
while(--t);                 
}


作者: 草草111111    时间: 2020-7-20 10:43
你这个没法做到渐亮渐灭吧,你这个直接拉低了,直接就灭了。你应该用PWM来做才能实现渐亮渐灭
作者: daiwenping    时间: 2020-7-20 11:01
渐亮渐灭这个子程序是没有问题的,我试验过OK的,主要是主程序有点问题
作者: CHEN--    时间: 2020-7-20 11:06
你这个程序只能渐亮  不能关闭渐灭吧
作者: SKYLAR123    时间: 2020-7-20 11:26
ID这个变量初始化为ID=0;然后如果可以按键改为标志位,而不是这种判断结束
作者: 就你****    时间: 2020-7-20 12:26
用定时器给一个值在那里++或--就是渐亮渐灭效果,当然按键要放到定时中断内做,而不是Delay按键,否则你按键控制不了要运行的程序
作者: 压着我头发啦    时间: 2020-7-20 14:00
  1. #include <reg52.h>
  2. unsigned char ID=0;
  3. unsigned int Toff=0;
  4. sbit LED=P1^0;         
  5. sbit S1=P3^7;   
  6. void no();
  7. void off();
  8. void Delay(unsigned int t);
  9. void main(void)
  10. {
  11.          S1=1;
  12.    LED=1;
  13.    while(1)
  14.    {
  15.      if(S1==0)
  16.      {
  17.        Delay(500);
  18.        if(S1==0)
  19.          {
  20.                                   while(S1==0);
  21.           ID++;
  22.           if(ID==3)
  23.           {
  24.            ID=0;
  25.           }
  26.          }
  27.                                         switch(ID)
  28.                                  {
  29.                                         case 1:
  30.                                         no();
  31.                                         break;
  32.                                         case 2:
  33.                                         off();
  34.                                         break;
  35.                                         }
  36.       }
  37.   }
  38. }

  39. /*???????*/
  40. void no(void)
  41. {
  42.      for(Toff=1;Toff<500;Toff++)  
  43.       {
  44.                LED=0;                    
  45.                Delay(Toff);            
  46.                LED=1;                  
  47.               Delay(500-Toff);           
  48.       }  
  49.       LED=0;
  50.                         Delay(1000);
  51. //      while (1);
  52. }
  53. /*???????*/
  54. void off(void)
  55. {                        
  56.    for(Toff=500;Toff>0;Toff--)   
  57.     {
  58.              LED=0;                     
  59.              Delay(Toff);               
  60.              LED=1;                    
  61.             Delay(500-Toff);            
  62.      }
  63.       LED=1;
  64.                  Delay(1000);
  65. //      while (1);
  66. }
  67. /*???????*/
  68. void Delay(unsigned int t)   
  69. {                        
  70. while(--t);                 
  71. }
  72. 随意改了下,做了仿真,你看看有啥区别,特别是no和off里的while。还有switch的位置
复制代码

作者: 556cv    时间: 2020-7-20 16:33
渐灭程序实现不了,还要用到中断,主程序好像有问题
作者: wulin    时间: 2020-7-20 17:31
这个不难,按键控制一个标志取反,定时器中断写PWM调光程序,判断标志改变占空比由0%逐渐到100%或由100%逐渐到0%。
作者: daiwenping    时间: 2020-7-21 11:15
压着我头发啦 发表于 2020-7-20 14:00

我按你程序试了一下,开关时会中跳一下,再开关
作者: daiwenping    时间: 2020-7-21 11:18
wulin 发表于 2020-7-20 17:31
这个不难,按键控制一个标志取反,定时器中断写PWM调光程序,判断标志改变占空比由0%逐渐到100%或由100%逐 ...

因刚学不太会,有参考的程序吗
作者: wulin    时间: 2020-7-21 14:24
daiwenping 发表于 2020-7-21 11:18
因刚学不太会,有参考的程序吗

渐亮渐暗5秒
  1. #include <reg51.H>
  2. sbit k1 =P3^0;
  3. sbit LED=P1^0;
  4. unsigned char i,num;
  5. bit flag=0;
  6. void keyscan()    //按键扫描
  7. {
  8.         static unsigned char count=0;
  9.         static bit sign=0;
  10.         if(!k1)
  11.         {
  12.                 count++;
  13.                 if(count>=100 && sign==0)
  14.                 {
  15.                         sign=1;
  16.                         flag=~flag;
  17.                 }
  18.         }
  19.         else
  20.         {
  21.                 count=0;
  22.                 sign=0;
  23.         }
  24. }
  25. void Timer0Init()                //500微秒@12.000MHz
  26. {

  27.         TMOD= 0x01;                //设置定时器模式
  28.         TL0 = 0x0C;                //设置定时初值
  29.         TH0 = 0xFE;                //设置定时初值
  30.         TF0 = 0;                //清除TF0标志
  31.         TR0 = 1;                //定时器0开始计时
  32.         EA = 1;
  33.         ET0 = 1;
  34. }

  35. void main(void)
  36. {
  37.     Timer0Init();
  38.         while(1)
  39.         {
  40.                 keyscan();
  41.         }
  42. }

  43. void Timer0Interrupt(void) interrupt 1
  44. {
  45.         TL0 = 0x0C;                //设置定时初值
  46.         TH0 = 0xFE;                //设置定时初值

  47.         if(i>=num)
  48.                 LED=1;
  49.         else LED=0;

  50.         i++;
  51.         if(i==100)
  52.         {
  53.                 i=0;
  54.                 if(flag)
  55.                 {
  56.                         if(num<100)
  57.                                 num++;
  58.                 }
  59.                 else
  60.                 {
  61.                         if(num>0)
  62.                                 num--;
  63.                 }
  64.         }
  65. }
复制代码

作者: daiwenping    时间: 2020-7-22 15:07
wulin 发表于 2020-7-21 14:24
渐亮渐暗5秒

吴工,您好!还是有问题,LED一直不亮;开关无作用;我有点不明白什么,void Timer0Interrupt(void) interrupt 1没有引用到程序中,是特意这样吗
作者: 权威人物    时间: 2020-7-22 16:40
daiwenping 发表于 2020-7-22 15:07
吴工,您好!还是有问题,LED一直不亮;开关无作用;我有点不明白什么,void Timer0Interrupt(void) inte ...

建议你回去看书,IO口控制部分和中断
作者: xianfajushi    时间: 2020-7-22 17:17
就是占空比可参https://blog.csdn.net/xianfajushi/article/details/81331101,其中c的值用按键控制即可。
作者: wulin    时间: 2020-7-22 21:26
daiwenping 发表于 2020-7-22 15:07
吴工,您好!还是有问题,LED一直不亮;开关无作用;我有点不明白什么,void Timer0Interrupt(void) inte ...

1.这个程序只能用于实物,仿真软件只能用虚拟示波器看波形,LED反映不了亮度变化。
2.定时器中断是独立于主程序按预设时间工作的,无须调用。
作者: xianfajushi    时间: 2020-7-23 14:24
更新了示例代码,自动调节占空比,演示如下:


作者: lxbhcy    时间: 2020-7-28 16:50
变量ID初始化改成0吧,switch哪里再加一个define





欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1