木槿呀 2024-03-16 17:19 采纳率: 72.2%
浏览 4
已结题

蓝桥杯单片机第四届省赛,按键部分不加else就没反应,为什么?

今天在做蓝桥杯单片机第四届省赛的时候遇到了一个奇怪的问题,就是在main.c里的Change()函数里,按键判断里面,那些所有的else if如果任意一个不加else,那么按下S6,单片机就没有任何反应,只有当所有的都加上else 之后,按下S6才会切换界面,这是为什么啊?
1、这是main.c文件

#include <STC15F2K60S2.H>
#include"hardware.h"
#include "ds1302.h"
unsigned char Write_ds1302_addr[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char Read_ds1302_addr[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
unsigned char Timer[7]={0x00,0x30,0x08,0x16,0x03,0x07,0x24};// 24年周日3月16日8点30分
unsigned char stat=0;//0-自动,1-手动
unsigned char flag=0;
unsigned char cnt=50;
unsigned char sd=5;
//--------------------------------------------------
void DS1203_W()//写
{
  char i;
  Write_Ds1302_Byte(0x8e,0x00);//打开保护
  for(i=0;i<7;i++)
  {
    Write_Ds1302_Byte(Write_ds1302_addr[i],Timer[i]);
  }
  Write_Ds1302_Byte(0x8e,0x80);//关闭保护
}
//-------------------------------------------------------
void DS1302_R()//读
{
  char i;
  for(i=0;i<7;i++)
  {
     Timer[i]=Read_Ds1302_Byte(Read_ds1302_addr[i]);
  }
}
//------------------------------------------
void SMG_Display()
{ 

  if(stat==0 )
  {
     if(flag==0)
     {
       SMG_buf[0]=Timer[2]/16;
       SMG_buf[1]=Timer[2]%16;
       SMG_buf[2]=17;
       SMG_buf[3]=Timer[1]/16;
       SMG_buf[4]=Timer[1]%16;
       SMG_buf[5]=16;
       SMG_buf[6]=flag/10;
       SMG_buf[7]=flag%10;
      }
     else if(flag==1)
     {
        SMG_buf[0]=17;
        SMG_buf[1]=17;
        SMG_buf[2]=16;
        SMG_buf[3]=16;
        SMG_buf[4]=16;
        SMG_buf[5]=16;
        SMG_buf[6]=cnt/10;
        SMG_buf[7]=cnt%10;
     } 
  }

}
//------------------------------------------
void Change()
{
   if(timer10ms>=10)
   {
      timer10ms=0;
      Scankey();
      if(key_value==7 && key_stat==2)
      {
        switch(stat)
        {
           case 0:
             stat=1;
            break;
            case 1:
             stat=0;
            break;
        }
      }
    else if (key_value==6 && key_stat==2 && flag==0 && stat==0)//自动状态下S6
      {
        flag=1;
      }
     else  if(key_value==5 && key_stat==2 && flag==1 )//自然状态下调整湿度阈值
      {
        cnt++;
      }
      else if(key_value==4 && key_stat==2 && flag==1)//自然状态下调整湿度阈值
      {
        cnt--;
      }
      else if(key_value==6 && key_stat==2 && flag==1 )
      {
        flag=0;
      }
   }
}
//------------------------------------------


//--------------------------------------------

void main()
{
   led_output();
   ws_output();
   Timer1Init();
   DS1203_W();
   while(1)
   {
      DS1302_R();
      Change();
      SMG_Display();
   }
}

2、这是hardware.文件

#include <STC15F2K60S2.H>
#include"hardware.h"
/*************  本地常量声明    **************/
unsigned char code t_display[]={                       //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

unsigned char code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码
unsigned int timer10ms=0;
unsigned int timer100ms=0;
unsigned char led_buf=0xff;
unsigned char ws_buf=0x00;
unsigned char SMG_buf[]={0,8,17,3,0,16,0,0};
unsigned char key_stat=0;
unsigned char key_value=0;

//-----------------------------------------------
void SelectHC573(unsigned char channel)
{
   switch(channel)
   {
     case 4:
       P2=(P2 & 0x1f)|0x80;
     break;
     case 5:
       P2=(P2 & 0x1f)|0xa0;
     break;
     case 6:
       P2=(P2 & 0x1f)|0xc0;
     break;
     case 7:
       P2=(P2 & 0x1f)|0xe0;
     break;
     case 0:
       P2=(P2 & 0x1f)|0x00;
     break;
   }
}
//---------------------------------
void led_output()
{
  SelectHC573(4);
  P0=led_buf;
  SelectHC573(0);
}
//----------------------------------
void ws_output()
{
  SelectHC573(5);
  P0=ws_buf;
  SelectHC573(0);
}
//--------------------------------
void SMG_output()
{
   static unsigned char SMG_com=0;

   SelectHC573(6);
   P0=0x00;
   SelectHC573(0);

   SelectHC573(6);
   P0=T_COM[SMG_com];
   SelectHC573(0);

    SelectHC573(7);
   P0=~t_display[SMG_buf[SMG_com]];
   SelectHC573(0);
   
   if(++SMG_com>=8)
   {
     SMG_com=0;
   }
}
//------------------------------------------
void Timer1Init(void)        //1毫秒@12.000MHz
{
    AUXR |= 0x40;        //定时器时钟1T模式
    TMOD &= 0x0F;        //设置定时器模式
    TL1 = 0x20;        //设置定时初值
    TH1 = 0xD1;        //设置定时初值
    TF1 = 0;        //清除TF1标志
    TR1 = 1;        //定时器1开始计时
    ET1=1;
    EA=1;
}
//-----------------------------------------
void ServiceTimer () interrupt 3
{
  SMG_output();
  timer10ms++;
  timer100ms++;
}
//-------------------------------------------
void Scankey()
{
   P3|=0x0f;
   if(~P3&0x0f)
   {
      if(key_stat<255)
         key_stat++;
      if(P33==0)
         key_value=4;
      if(P32==0)
         key_value=5;
      if(P31==0)
         key_value=6;
      if(P30==0)
         key_value=7;
   }
   else 
   {
      key_stat=0;
      key_value=0;
   }
}

  • 写回答

13条回答 默认 最新

  • qzjhjxj 2024-03-16 22:34
    关注
    
    对每一次的按键被按下,确保做出唯一的一次反馈,需要唯一的选择条件。如果不加else,几条if语句是并列的,代码的执行是按顺序的,
    也就是每条if语句都会按先后顺序被执行判断一次。如::stat初值为0,flag初值为0,此时按下S6,那么就会进入
    if (key_value==6 && key_stat==2 && flag==0 && stat==0)//自动状态下S6
    {
    flag=1;
    }
    此时,后面的语句就是:
    if(key_value==5 && key_stat==2 && flag==1 )//自然状态下调整湿度阈值
    {
    cnt++;
    }
    。。。、// 因为代码是顺序执行的,它会每个if () 都判断一次
    当它判断到最后一个if 时:
    if(key_value==6 && key_stat==2 && flag==1 )
    {
    flag=0;
    }
    又把 flag 的值改回去了,s6按下去的作用失去了,所以也就没反应了。
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(12条)

报告相同问题?

问题事件

  • 系统已结题 3月24日
  • 已采纳回答 3月16日
  • 创建了问题 3月16日

悬赏问题

  • ¥15 AnolisOs7.9如何安装 Qt_5.14.2的运行库
  • ¥20 求:怎么实现qt与pcie通信
  • ¥50 前后端数据顺序不一致问题,如何解决?(相关搜索:数据结构)
  • ¥15 基于蒙特卡罗法的中介效应点估计代码
  • ¥15 罗技G293和UE5.3
  • ¥20 Tesla 特斯拉K80显卡 如果需要使用该设备,你需要禁用系统上的另一个设备。
  • ¥30 QT调用百度智能云千帆模型无法取得返回文本
  • ¥50 CCD工业视觉相机检测出现光边
  • ¥60 二次元手游日常任务自动化代肝(相关搜索:自动化)
  • ¥15 mysql将查询的结果作为动态列名怎么实现