找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2620|回复: 17
打印 上一主题 下一主题
收起左侧

使用单独按键实现渐亮渐灭 单片机程序有问题

  [复制链接]
跳转到指定楼层
楼主
各位大虾,我是刚刚学单片机,如何使用单独按键实现渐亮渐灭(功能是用一个轻触开关,开灯时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);                 
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:733205 发表于 2020-7-20 10:43 | 只看该作者
你这个没法做到渐亮渐灭吧,你这个直接拉低了,直接就灭了。你应该用PWM来做才能实现渐亮渐灭
回复

使用道具 举报

板凳
ID:3241 发表于 2020-7-20 11:01 | 只看该作者
渐亮渐灭这个子程序是没有问题的,我试验过OK的,主要是主程序有点问题
回复

使用道具 举报

地板
ID:601837 发表于 2020-7-20 11:06 | 只看该作者
你这个程序只能渐亮  不能关闭渐灭吧
回复

使用道具 举报

5#
ID:636538 发表于 2020-7-20 11:26 | 只看该作者
ID这个变量初始化为ID=0;然后如果可以按键改为标志位,而不是这种判断结束
回复

使用道具 举报

6#
ID:475444 发表于 2020-7-20 12:26 | 只看该作者
用定时器给一个值在那里++或--就是渐亮渐灭效果,当然按键要放到定时中断内做,而不是Delay按键,否则你按键控制不了要运行的程序
回复

使用道具 举报

7#
ID:716656 发表于 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的位置
复制代码
回复

使用道具 举报

8#
ID:801957 发表于 2020-7-20 16:33 | 只看该作者
渐灭程序实现不了,还要用到中断,主程序好像有问题
回复

使用道具 举报

9#
ID:213173 发表于 2020-7-20 17:31 | 只看该作者
这个不难,按键控制一个标志取反,定时器中断写PWM调光程序,判断标志改变占空比由0%逐渐到100%或由100%逐渐到0%。
回复

使用道具 举报

10#
ID:3241 发表于 2020-7-21 11:15 | 只看该作者

我按你程序试了一下,开关时会中跳一下,再开关
回复

使用道具 举报

11#
ID:3241 发表于 2020-7-21 11:18 | 只看该作者
wulin 发表于 2020-7-20 17:31
这个不难,按键控制一个标志取反,定时器中断写PWM调光程序,判断标志改变占空比由0%逐渐到100%或由100%逐 ...

因刚学不太会,有参考的程序吗
回复

使用道具 举报

12#
ID:213173 发表于 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. }
复制代码
回复

使用道具 举报

13#
ID:3241 发表于 2020-7-22 15:07 | 只看该作者

吴工,您好!还是有问题,LED一直不亮;开关无作用;我有点不明白什么,void Timer0Interrupt(void) interrupt 1没有引用到程序中,是特意这样吗
回复

使用道具 举报

14#
ID:311846 发表于 2020-7-22 16:40 | 只看该作者
daiwenping 发表于 2020-7-22 15:07
吴工,您好!还是有问题,LED一直不亮;开关无作用;我有点不明白什么,void Timer0Interrupt(void) inte ...

建议你回去看书,IO口控制部分和中断
回复

使用道具 举报

15#
ID:332444 发表于 2020-7-22 17:17 | 只看该作者
就是占空比可参https://blog.csdn.net/xianfajushi/article/details/81331101,其中c的值用按键控制即可。
回复

使用道具 举报

16#
ID:213173 发表于 2020-7-22 21:26 | 只看该作者
daiwenping 发表于 2020-7-22 15:07
吴工,您好!还是有问题,LED一直不亮;开关无作用;我有点不明白什么,void Timer0Interrupt(void) inte ...

1.这个程序只能用于实物,仿真软件只能用虚拟示波器看波形,LED反映不了亮度变化。
2.定时器中断是独立于主程序按预设时间工作的,无须调用。
回复

使用道具 举报

17#
ID:332444 发表于 2020-7-23 14:24 | 只看该作者
更新了示例代码,自动调节占空比,演示如下:

回复

使用道具 举报

18#
ID:808700 发表于 2020-7-28 16:50 | 只看该作者
变量ID初始化改成0吧,switch哪里再加一个define
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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