找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

单片机多个独立按键控制不同功能的led灯,检测按键部分好像出了问题,求解

查看数: 2726 | 评论数: 5 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2020-10-4 17:00

正文摘要:

单片机源程序如下: #include<reg52.h> #define uchar unsigned char #define uint unsigned int void delayMS(uint x); void KeyProcess(uchar Key); uchar GetKey(); //延时函数 void delayMS(uint x) { &n ...

回复

ID:827243 发表于 2020-10-9 18:53
晕死, 按键高4位, 你判断低4位,错了。

switch (P1)

{

case 0xF7: k=1;break;

case 0xFB: k=2;break;

case 0xFD: k=3;break;

case 0xFE: k=4;break;

default: k=0;

}
ID:275826 发表于 2020-10-6 09:58
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define Kport  P3
#define Ledport  P1
uchar code table0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//LED从低位往高位移
unsigned char kscancnt;        //记录进入中断的次数,满一个周期清零

void timer0_init();                        //定时器0初始化
void delayMS(uint x);           //延时函数
void KeyProcess(uchar Key);         //按键处理函数
bit flag;
uchar knum;
uint F3cnt,F2cnt,Pwmcnt,T0cnt;
uchar temp=0xff,temp1;
uchar sh_cnt;
//延时函数
void delayMS(uint x)
{
    uchar i;

   while (x--)
      for(i=0;i<120; i++) ;
}
/***************************************************
*                                定时器0初始化子函数
*                        工作方式2,每1000us中断一次
****************************************************/
void timer0_init(void)
{
        TMOD = 0x01;                //采用定时器0,工作方式2,
        TH0 = (65536-1000)/256;                         //定时器设置,每隔20us发起一次中断。
        TL0 = (65536-1000)%256;         
        ET0 = 1;                        //开定时器0中断
        EA = 1;                                 //开总中断
        TR0 = 1;                        //打开定时器
}

//检测按键

uchar GetKey(uchar kscancnt)

{  
   uchar ktmp;
   if(kscancnt==0)
         {
          temp=(Kport&0xf0)>>4;
          ktmp=~temp &(temp1);
          if(ktmp)knum=ktmp;
          temp1=temp;
         }
   return knum;

}

//键盘按键处理

void KeyProcess(uchar Key)
  {
   
   switch (Key)
        {
           case 1:Ledport=0x00;                        
                       break;
               
           case 2:if(F2cnt==200){sh_cnt=++sh_cnt%8;F2cnt=0;}
                          Ledport=table0[sh_cnt];
                      break;
           case 4:if(T0cnt==300)
                    {F3cnt=F3cnt+10;T0cnt=0;}
                          if(F3cnt==130){F3cnt=0;flag=!flag;}
                  Pwmcnt=++Pwmcnt%100;

                          if(flag)
                            {if(Pwmcnt>F3cnt)Ledport=0x00;else Ledport=0xff;}
                          else
                            {if(Pwmcnt>F3cnt)Ledport=0xff;else Ledport=0x00;}
                  break;

           case 8:Ledport=0xff; //全部关闭
                          break;

        }

}

/***************************************************
*               中断服务子函数
*****************************************************/
void time0(void) interrupt 1
{
    TH0 = (65536-1000)/256;                         //定时器设置,每隔20us发起一次中断。
    TL0 = (65536-1000)%256;  
        kscancnt=++ kscancnt%10;
        if(knum==2)         {F2cnt++; }
    if(knum==4)         {T0cnt++; }
}


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

void main(void)

{  
        uchar Key;
        P0=P1=0xFF;
        timer0_init();
        while(1)
                   {
                 Key=GetKey(kscancnt);
                 KeyProcess(Key);
               
                }
}
ID:332444 发表于 2020-10-6 09:58
按键释放后主程序再次调用按键就被赋值0,因此,思路需重新考虑。
ID:275826 发表于 2020-10-6 09:56
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define Kport  P3
#define Ledport  P1
uchar code table0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//LED从低位往高位移
unsigned char kscancnt;        //记录进入中断的次数,满一个周期清零

void timer0_init();                        //定时器0初始化
void delayMS(uint x);           //延时函数
void KeyProcess(uchar Key);         //按键处理函数
bit flag;
uchar knum;
uint F3cnt,F2cnt,Pwmcnt,T0cnt;
uchar temp=0xff,temp1;
uchar sh_cnt;
//延时函数
void delayMS(uint x)
{
    uchar i;

   while (x--)
      for(i=0;i<120; i++) ;
}
/***************************************************
*                                定时器0初始化子函数
*                        工作方式2,每1000us中断一次
****************************************************/
void timer0_init(void)
{
        TMOD = 0x01;                //采用定时器0,工作方式2,
        TH0 = (65536-1000)/256;                         //定时器设置,每隔20us发起一次中断。
        TL0 = (65536-1000)%256;         
        ET0 = 1;                        //开定时器0中断
        EA = 1;                                 //开总中断
        TR0 = 1;                        //打开定时器
}

//检测按键

uchar GetKey(uchar kscancnt)

{  
   uchar ktmp;
   if(kscancnt==0)
         {
          temp=(Kport&0xf0)>>4;
          ktmp=~temp &(temp1);
          if(ktmp)knum=ktmp;
          temp1=temp;
         }
   return knum;

}

//键盘按键处理

void KeyProcess(uchar Key)
  {
   
   switch (Key)
        {
           case 1:Ledport=0x00;                        
                       break;
               
           case 2:if(F2cnt==200){sh_cnt=++sh_cnt%8;F2cnt=0;}
                          Ledport=table0[sh_cnt];
                      break;
           case 4:if(T0cnt==300)
                    {F3cnt=F3cnt+10;T0cnt=0;}
                          if(F3cnt==130){F3cnt=0;flag=!flag;}
                  Pwmcnt=++Pwmcnt%100;

                          if(flag)
                            {if(Pwmcnt>F3cnt)Ledport=0x00;else Ledport=0xff;}
                          else
                            {if(Pwmcnt>F3cnt)Ledport=0xff;else Ledport=0x00;}
                  break;

           case 8:Ledport=0xff; //全部关闭
                          break;

        }

}

/***************************************************
*               中断服务子函数
*****************************************************/
void time0(void) interrupt 1
{
    TH0 = (65536-1000)/256;                         //定时器设置,每隔20us发起一次中断。
    TL0 = (65536-1000)%256;  
        kscancnt=++ kscancnt%10;
        if(knum==2)         {F2cnt++; }
    if(knum==4)         {T0cnt++; }
}


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

void main(void)

{  
        uchar Key;
        P0=P1=0xFF;
        timer0_init();
        while(1)
                   {
                 Key=GetKey(kscancnt);
                 KeyProcess(Key);
               
                }
}
先把程序理解
ID:89515 发表于 2020-10-5 12:54
你的按键接的高四位吧?按键2,3的功能有逻辑问题。

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

Powered by 单片机教程网

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