找回密码
 立即注册

QQ登录

只需一步,快速开始

帖子
查看: 1835|回复: 16
打印 上一主题 下一主题
收起左侧

谁帮我看看这个单片机按键处理程序,为什么不灵敏?需要按几次的

  [复制链接]
跳转到指定楼层
楼主
ID:72649 发表于 2024-12-29 09:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
void Test(void)                        //按键处理
{
        if( Mode == 0  )                //模式键
        {        
                delay_ms(20);                        //延时10ms
                if(Mode==0)
                while(Mode==0);
         if( Run_Flag==0 )                        //Run_Flag==0制冷
                 {
                  SEG0 = 20;            //千位显示P
                     SEG1 = 22;            //百位显示-
                  SEG2 = 22;            //十位显示-
              SEG3 = 12;              //个位显示C        
                  DspTemp();                      //显示模式
             }
         else
          {
                 SEG0 = 20;            //显示P
                 SEG1 = 22;            //显示-
                 SEG2 = 22;            //显示-
             SEG3 = 16;              //显示H        
                 DspTemp();                      //显示模式         
          }
           delay_ms(10);                        //延时10ms               
          while(  Mode == 0 );                //按钮按下,并等待按钮松开                                          
                        if( Run_Flag==0 )                        //Run_Flag==0制冷
                        { //-------默认是制冷模式---------------------               
                                Run_Flag = 1;                        //Run_Flag==1制热
                                SEG0 = 20;            //千位显示P
                            SEG1 = 22;            //显示-
                        SEG2 = 22;            //显示-
                    SEG3 = 16;              //显示H
                            DspTemp();                    //显示模式                                       
                                BEEP = 0;                                //打开蜂鸣
                                delay_ms(20);                        //延时10ms
                                BEEP = 1;                                //关闭蜂鸣
                        }
           else   //-如果已是制热模式则转换到制冷模式---------------------        
                        {
                                Run_Flag = 0;         //Run_Flag==0制冷
                                SEG0 = 20;            //显示P
                            SEG1 = 22;            //显示-
                        SEG2 = 22;            //显示-
                    SEG3 = 12;            //显示C
                                DspTemp();                    //显示模式        
                                BEEP = 0;                         //打开蜂鸣
                                delay_ms(20);                 //延时10ms
                                BEEP = 1;                        //关闭蜂鸣               
                        }               
        }
        if( Set == 0 )                //设置键
        {
                delay_ms( 10 );
                if( Set == 0 )
                {
                    BEEP = 0;                                //打开蜂鸣
                        delay_ms(10);                        //延时10ms
                        BEEP = 1;                                //关闭蜂鸣                        
                        Set_Mode ++;        
                        SEG0 = 20;            //显示P
                        SEG1 = 22;           //显示模式
                    SEG2 = 22;            //显示-
                SEG3 = Set_Mode;      //显示-
                    DspTemp();                      //显示模式                                       
                        delay_ms(1000);         
                        //模式选择
                        if( Set_Mode>3 )                //如果模式>8
                                Set_Mode = 0;                //回到模式1               
                         de=0;
                        while( Set == 0)                //等待松开执行了
                        {
                                 de++;
                                 SEG0 = 13;   //显示d
                                 SEG3 = de/10;   
                                 DspTemp();                    //显示模式               
              //BEEP = 0;                   //打开蜂鸣
                            delay_ms(100);                        //延时10ms
                          //    BEEP = 1;                                //关闭蜂鸣                        
                                if(de>=100)                                //按住Set键2秒以上保存参数                        
                            {                        
                  EA=0;
                        //P6 =        0XFE;   P6<<1+1
                                IapErase(SECTOR0);                                        // 擦除第0扇区                                       
                    IapProgram(SECTOR0+10,ydsx);        // 保存温度上限
                IapProgram(SECTOR0+12,ydxx);        // 保存温度下限
                IapProgram(SECTOR0+14,ydjz);        // 保存温度校准
                        // 在第0扇区,第10字节,写入ydsx        
                BEEP = 0;                                //打开蜂鸣
                            delay_ms(10);                        //延时10ms
                            BEEP = 1;                                //关闭蜂鸣                        
               delay_ms(10);        
                BEEP = 0;                                //打开蜂鸣
                            delay_ms(10);                        //延时10ms
                        BEEP = 1;                                //关闭蜂鸣                        
                        EA=1;        
                    delay_ms(10);                        //延时10ms        
                        de=0;               
                        }                                
                                 delay_ms(10);
                        //de=0;
                        }        
                        de=0;               
                }
        }
   if( Up == 0  )                //增加键处理
        {
                SEG0 = 20;            //显示P
                SEG1 = 22;            //显示-
            SEG2 = 22;            //显示-
            SEG3 = Set_Mode;      //显示模式
            DspTemp();                    //显示模式               
                BEEP = 0;                                //打开蜂鸣
                delay_ms(50);                        //延时10ms
            BEEP = 1;                                //关闭蜂鸣        
                delay_ms(50);                        //延时10ms
                while(  Up == 0 )
                {                                
                        switch(Set_Mode)              //选择设置参数                                
                        {
                      case  1:                      //温度上限设置                                                      
                            ydsx++;                      //温度上限加1
                                if( ydsx >= 1200  ) //温度上限大于120度
                              {
                                    ydsx=-450;        //温度上限设置为-45度
                               }
                           
                        if        (ydsx<=0)              //温度上限小于0时   
                                  {
                                SEG0 = 22;             //数码管千位显示“-”   
                                    ydsxx=abs(ydsx);           //取温度上限绝对值
                                    SEG1 =ydsxx/100%10;      //百位 计算  
                        SEG2 = ydsxx/10%10;     //十位 计算
                        SEG3 = ydsxx/1%10;      //个位 计算
                            DspTemp();        
                              }                                
                else
                             {        
                           ydsxx=ydsx;        
                               SEG0 = ydsxx/1000%10;     //千位计算
                                   if (SEG0==0)
                                           SEG0=23;              //千位为0时 ,消隐不显        
                       SEG1 =ydsxx/100%10;       //百位 计算  
                       SEG2 = ydsxx/10%10;       //十位 计算
                       SEG3 = ydsx/1%10;         //个位 计算
                           DspTemp();        
                             }
                                  delay_ms(30);         
                                break;
                          case  2:                           //温度下限设置                                             
                            ydxx++;                       //温度下限加1
                                if( ydxx >= 1200  )        
                              {
                                     ydxx=-450;
                               }
                          
                            if        (ydxx<=0)       //温度下限小于0时   
                                  {
                                SEG0 = 22;        //数码管第一位显示“-”
                                    ydxxx=abs(ydxx);         //取温度下限绝对值
                        SEG1 =ydxxx/100%10;       //百位 计算  
                        SEG2 = ydxxx/10%10;    //十位 计算
                        SEG3 = ydxxx/1%10;       //个位 计算
                            DspTemp();        
                              }                                
                else
                             {        
                           ydxxx=ydxx;        
                               SEG0 = ydxxx/1000%10;     //千位计算
                                          if (SEG0==0)
                                           SEG0=23;              //千位为0时 ,消隐不显                                                  
                       SEG1 =ydxxx/100%10;       //百位 计算
                       SEG2 = ydxxx/10%10;       //十位 计算
                       SEG3 = ydxxx/1%10;      //个位 计算
                           DspTemp();        
                             }
                                  delay_ms(30);         
                                break;  
                  case  3:                           //温度校准设置                                                      
                            ydjz++;                       //温度校准加1
                                if( ydjz>= 100  )        
                              {
                                    ydjz=-100;
                              }
                           
                            if (ydjz<=0)            //温度校准小于0时         
                                 {
                               SEG0 = 22;                 //为负时数码管千位显示“-”               
                                   ydjzx=abs(ydjz);           //取温度校准绝对值
                                   SEG1 =ydjzx/100%10;       //百位 计算
                       SEG2 = ydjzx/10%10;      //十位 计算
                       SEG3 = ydjzx/1%10;    //个位 计算
                           DspTemp();        
                             }                                
                else
                             {        
                            ydjzx=ydjz;        
                                SEG0 = ydjzx/1000%10;   //千位计算
                                        if (SEG0==0)
                                           SEG0=23;              //千位为0时 ,消隐不显      
                        SEG1 =ydjzx/100%10;      //百位 计算
                        SEG2 = ydjzx/10%10;     //十位 计算
                        SEG3 = ydjzx/1%10;    //个位 计算
                            DspTemp();        
                              }
                                  delay_ms(30);         
                                break;                                    
                        default:
                    Set_Mode=0;               
                        }                                
                    delay_ms(50);        
                 }                        
                }
if(Down == 0  )                          //减少键处理
        {
                SEG0 = 20;            //显示P
                SEG1 = 22;            //显示-
                SEG2 = 22;            //显示-
            SEG3 = Set_Mode;      //显示模式
                DspTemp();                      //显示模式               
            BEEP = 0;                                //打开蜂鸣
                delay_ms(50);                        //延时50ms
            BEEP = 1;                                //关闭蜂鸣        
                delay_ms(50);                        //延时50ms
                while(Down == 0 )
                {
                  switch(Set_Mode)               //选择设置参数               
                        {
                          case  1:                       //温度上限设置            
                             ydsx--;                   //温度上限减1
                                 if( ydsx <= -450  )        
                               {
                                     ydsx=1200;
                                }
                             delay_ms(10);         
                            if        (ydsx<=0)        //温度上限小于0时   
                                  {
                                SEG0 = 22;        //数码管第一位显示“-”   
                                    ydsxx=abs(ydsx);         //取温度上限绝对值
                                    SEG1 =ydsxx/100%10;      //百位 计算
                        SEG2 = ydsxx/10%10;     //十位 计算
                        SEG3 = ydsxx/1%10;       //个位 计算
                            DspTemp();        
                              }                                
                else
                             {        
                           ydsxx=ydsx;        
                               SEG0 = ydsxx/1000%10;   //千位计算
                                        if (SEG0==0)
                                           SEG0=23;              //千位为0时 ,消隐不显      
                       SEG1 =ydsxx/100%10;      //百位 计算
                       SEG2 = ydsxx/10%10;     //十位 计算
                       SEG3 = ydsx/1%10;       //个位 计算
                           DspTemp();        
                             }
                                break;
                          case  2:                           //温度下限设置
                       ydxx--;               //温度下限减1
                                if( ydxx <= -450 )        
                             {
                                   ydxx=1200;
                              }
                            delay_ms(10);         
                            if        (ydxx<=0)       //温度下限小于0时   
                                 {
                               SEG0 = 22;        //数码管第一位显示“-”
                                   ydxxx=abs(ydxx);         //取温度下限绝对值
                       SEG1 =ydxxx/100%10;      //百位 计算
                       SEG2 = ydxxx/10%10;     //十位 计算
                       SEG3 = ydxxx/1%10;       //个位 计算
                           DspTemp();        
                             }                                
                else
                              {        
                           ydxxx=ydxx;        
                               SEG0 = ydxxx/1000%10;   //千位计算
                                        if (SEG0==0)
                                           SEG0=23;              //千位为0时 ,消隐不显         
                       SEG1 =ydxxx/100%10;      //百位 计算
                       SEG2 = ydxxx/10%10;     //十位 计算
                       SEG3 = ydxxx/1%10;       //个位 计算
                           DspTemp();        
                              }
                                break;  
                  case  3:                           //温度校准设置                                                      
                            ydjz--;               //温度校准减1
                                if( ydjz<= -100  )        
                              {
                                     ydjz=100;
                               }
                            delay_ms(10);         
                            if (ydjz<=0)         //温度校准小于0时         
                                  {
                                 SEG0 = 22;
                                     ydjzx=abs(ydjz);           //取温度校准绝对值
                                     SEG1 =ydjzx/100%10;      //百位 计算
                         SEG2 = ydjzx/10%10;     //十位 计算
                         SEG3 = ydjzx/1%10;       //个位 计算
                             DspTemp();        
                              }                                
                else
                             {        
                           ydjzx=ydjz;        
                               SEG0 = ydjzx/1000%10;   //千位计算
                                        if (SEG0==0)
                                           SEG0=23;            //千位为0时 ,消隐不显        
                       SEG1 =ydjzx/100%10;     //百位 计算
                       SEG2 = ydjzx/10%10;     //十位 计算
                       SEG3 = ydjzx/1%10;      //个位 计算
                           DspTemp();        
                             }
                                break;                                    
                        default:
                    Set_Mode=0;
                }
                  delay_ms(50);        
                }        
        }
}

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

举报

沙发
ID:235200 发表于 2024-12-29 10:28 | 只看该作者
这种顺序判断的方法一般都会不灵敏,只有采取中断方式,或定时扫描立即判断按键才会灵敏
回复

举报

板凳
ID:731755 发表于 2024-12-29 11:57 来自触屏版 | 只看该作者
我喜欢用中断来操作按键,不然就会出现你的这种情况。
回复

举报

地板
ID:1133081 发表于 2024-12-29 13:00 | 只看该作者
不要把与按键识别与其它功能混在一起,更不要滥用阻滞延时。
回复

举报

5#
ID:332444 发表于 2024-12-29 13:14 | 只看该作者
阻塞延时通病
回复

举报

6#
ID:71233 发表于 2024-12-29 13:39 | 只看该作者
太复杂了,我一般是先用一个按键函数返回键值,然后再键值不同分别做处理
  1. unsigned char key()
  2. {
  3.         if(K1==0)                //检测按键K1是否按下
  4.         {
  5.                 delay_ms(20);        //消除抖动
  6.                 if(K1==0)
  7.                 {
  8.                         while(!K1);
  9.                         return 1;
  10.                 }
  11.         }
  12.         if(K2==0)                //检测按键K1是否按下
  13.         {
  14.                 delay_ms(20);        //消除抖动
  15.                 if(K2==0)
  16.                 {
  17.                         while(!K2);
  18.                         return 2;
  19.                 }
  20.         }        
  21.         return 0;
  22. }
复制代码



回复

举报

7#
ID:1141869 发表于 2024-12-29 15:42 | 只看该作者
中断操作按键
回复

举报

8#
ID:1109793 发表于 2024-12-29 18:44 | 只看该作者
lmn2005 发表于 2024-12-29 13:39
太复杂了,我一般是先用一个按键函数返回键值,然后再键值不同分别做处理

你这不是还是用了阻塞延时?还20MS
回复

举报

9#
ID:72649 发表于 2024-12-30 08:08 | 只看该作者
13872888583 发表于 2024-12-29 11:57
我喜欢用中断来操作按键,不然就会出现你的这种情况。

能不能帮我修改一下
回复

举报

10#
ID:72649 发表于 2024-12-30 08:09 | 只看该作者

给点思路
回复

举报

11#
ID:332444 发表于 2024-12-30 09:19 | 只看该作者

看我帖子
回复

举报

12#
ID:72649 发表于 2024-12-31 04:48 来自触屏版 | 只看该作者
xianfajushi 发表于 2024-12-30 09:19
看我帖子

在哪里可以看到你帖子?
回复

举报

13#
ID:641358 发表于 2024-12-31 09:56 | 只看该作者
太复杂了,按键可用中断,也可以用按键标记的办法来处理。
回复

举报

14#
ID:23640 发表于 2024-12-31 10:43 | 只看该作者
不要用那么多延时,不用中断可以开个定时器,使用状态机来做,不过首先楼主应该把按键和功能先分开来,这样的程序看着太费劲了
回复

举报

15#
ID:1132182 发表于 2024-12-31 11:41 | 只看该作者
太臃肿了
回复

举报

16#
ID:1132182 发表于 2024-12-31 11:42 | 只看该作者
code char smg_short[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,
                                                                                                 0x40,0xf9-0x80,0xa4-0x80,0xb0-0x80,0x99-0x80,0x92-0x80,0x82-0x80,0xf8-0x80,0x80-0x80,0x90-0x80,
                                                                                                0xc6,0x8c,0x88};
       
code char smg_post[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

char smg_cache[8] = {10,10,10,10,10,10,10,10};


void display_Init(void)
{
        P0 = 0xff;Y4;Y0;
        P0 = 0xff;Y5;Y0;
        P0 = 0xff;Y6;Y0;
        P0 = 0xff;Y7;Y0;
}

void smg_while(void)
{
        static char neo;
       
        P0 = 0xff;Y7;Y0;
        P0 = smg_post[neo];Y6;Y0;
        P0 = smg_short[smg_cache[neo]];Y7;Y0;
       
        neo++;
        neo%=8;
}

void smg_display(char t0,t1,t2,t3,t4,t5,t6,t7)
{
        smg_cache[0] = t0;
        smg_cache[1] = t1;
        smg_cache[2] = t2;
        smg_cache[3] = t3;
        smg_cache[4] = t4;              
        smg_cache[5] = t5;
        smg_cache[6] = t6;
        smg_cache[7] = t7;       
}数码管显示,
char Key_Open(void)
{
  unsigned char key;
        P3 &= 0xf0;
        P34=1;P35=1;P42=1;P44=1;
        if(!(P34&P35&P42&P44))
        {
                if(!(P34&P35&P42&P44))
                {
                        if(P34==0) key=1;
                        if(P35==0) key=2;
                        if(P42==0) key=3;
                        if(P44==0) key=4;
                        P3 |= 0x0f;
                        P34=0;P35=0;P42=0;P44=0;
                        if(P30==0) key=key;
                        if(P31==0) key=key+4;
                        if(P32==0) key=key+8;
                        if(P33==0) key=key+12;
                }
                while(P30 == 0 | P31 == 0 | P32  == 0 | P33 == 0);
        }
        return key;
}矩阵按键
回复

举报

17#
ID:1132182 发表于 2024-12-31 11:44 | 只看该作者
这不就是蓝桥杯类似的东西,看我帖子,应该可以有所收获
回复

举报

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

本版积分规则

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

Powered by 单片机教程网

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