找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机按键程序运行不正常,帮忙看一下

[复制链接]
跳转到指定楼层
#
K 是 开关机键。
k1,k2,k3,k4 是开机后,是操作键。键不能正常操作。


#include"stc8h.h"

sbit LEDR = P1^0;

sbit LEDB  = P1^4;
sbit LEDR0 = P1^5;
sbit LEDG0 = P1^6;
sbit LEDB0 = P1^7;


sbit KEY  = P3^7;
sbit KEY1 = P3^6;
sbit KEY2 = P3^5;
sbit KEY3 = P3^4;
sbit KEY4 = P3^3;

unsigned char keyshort; //短按键标志
unsigned char keylong;  //长按键标志

unsigned char keyshort1; //短按键标志
unsigned char keylong1;  //长按键标志

unsigned char keyshort2; //短按键标志
unsigned char keylong2;  //长按键标志

unsigned char keyshort3; //短按键标志
unsigned char keylong3;  //长按键标志

unsigned char keyshort4; //短按键标志
unsigned char keylong4;  //长按键标志

unsigned char LEDON;    //开灯状态
unsigned char flag1ms;  //1ms标志
unsigned char flag1ms1;  //1ms标志
unsigned char flag1ms2;  //1ms标志
unsigned char flag1ms3;  //1ms标志
unsigned char flag1ms4;  //1ms标志

void key_Proc(); //按键处理
void led_Proc();  //灯处理

void key_Proc1(); //按键处理
void led_Proc1();  //灯处理

void key_Proc2(); //按键处理
void led_Proc2();  //灯处理

void key_Proc3(); //按键处理
void led_Proc3();  //灯处理

void key_Proc4(); //按键处理
void led_Proc4();  //灯处理

void Timer0Init(); //中断初始化

void main()
{
    P0 = 0;
    P1 = 0;
    P2 = 0;

    Timer0Init();  //中断初始化

    while(1)
    {
    key_Proc();   //按键处理
    led_Proc();  //灯处理
            
        key_Proc1();   //按键处理
    led_Proc1();  //灯处理
    key_Proc2();   //按键处理
    led_Proc2();  //灯处理
    key_Proc3();   //按键处理
    led_Proc3();  //灯处理            
    key_Proc4();   //按键处理
    led_Proc4();  //灯处理        
        }
}

void key_Proc()    //按键处理
{
      unsigned int keyTim; //按键时间
    if(flag1ms)  //1ms时间标志
    {
        flag1ms = 0;
        if(KEY)
        {
        if((keyTim>10)&&(keyTim<1000))  //按键时间大于10ms小于50ms,是短按键
        {
        keyshort = 1;   //短按键标志
        }
        keyTim = 0;        //按键时间清零
        }
        else
        {
        if(keyTim<5000)    //按键时间小于10S
        keyTim++;           //按键时间加
        if(keyTim==1500)    //按键时间为1S
        {
        keylong = 1;    //长按键标志
        }
        }      
    }
}

void led_Proc()   //灯处理
{
    if((LEDON==0)&&(keyshort==1))  //关灯状态同时长按键按下就开灯
    {   
        keyshort = 0;  //长按键松开
        LEDON = 1;    //关灯时就开灯
        LEDR = 1;     //RGB灯亮白光
    }        
    if((LEDON==1)&&(keylong==1)) //开灯状态同时长按键按下就关灯
    {   
        keylong = 0;  //长按键松开
        LEDON = 0;    //开灯时就关灯
        LEDR = 0;     //RGB灯灭
    }
}

void key_Proc1()    //按键处理
{
      unsigned int keyTim; //按键时间
    if(flag1ms1)  //1ms时间标志
    {
        flag1ms1 = 0;
        if(KEY1)
        {
        if((keyTim>10)&&(keyTim<1000))  //按键时间大于10ms小于50ms,是短按键
        {
        keyshort1 = 1;   //短按键标志
        }
        keyTim = 0;        //按键时间清零
        }
        else
        {
         if(keyTim<5000)    //按键时间小于10S
         keyTim++;           //按键时间加
         if(keyTim==1500)    //按键时间为1S
         {
         keylong1 = 1;    //长按键标志
         }
        }      
    }
}

void led_Proc1()   //灯处理
{
    if((LEDON==1)&&(keyshort1==1))  //关灯状态同时长按键按下就开灯
    {   
        keyshort1 = 0;  //长按键松开
        LEDON = 1;    //关灯时就开灯
        LEDR0 = 1;     //RGB灯亮白光
        LEDG0 = 0;
        LEDB0 = 0;
    }        
    if((LEDON==1)&&(keylong1==1)) //开灯状态同时长按键按下就关灯
    {   
        keylong1 = 0;  //长按键松开
        LEDON = 1;    //开灯时就关灯
        LEDR0 = 0;     //RGB灯灭
        LEDG0 = 0;
        LEDB0 = 0;
    }
}

void key_Proc2()    //按键处理
{
    if(flag1ms2)  //1ms时间标志
    {
                unsigned int keyTim; //按键时间
        flag1ms2 = 0;
        if(KEY2)
        {
        if((keyTim>10)&&(keyTim<1000))  //按键时间大于10ms小于50ms,是短按键
         {
         keyshort2 = 1;   //短按键标志
         }
         keyTim = 0;        //按键时间清零
        }
        else
        {
         if(keyTim<5000)    //按键时间小于10S
         keyTim++;           //按键时间加
         if(keyTim==1500)    //按键时间为1S
          {
          keylong2 = 1;    //长按键标志
          }
        }      
    }
}

void led_Proc2()   //灯处理
{
    if((LEDON==1)&&(keyshort2==1))  //关灯状态同时长按键按下就开灯
    {   
        keyshort2 = 0;  //长按键松开
        LEDON = 1;    //关灯时就开灯
        LEDR0 = 0;     //RGB灯亮白光
        LEDG0 = 1;
        LEDB0 = 0;
    }        
    if((LEDON==1)&&(keylong2==1)) //开灯状态同时长按键按下就关灯
    {   
        keylong2 = 0;  //长按键松开
        LEDON = 1;    //开灯时就关灯
        LEDR0 = 0;     //RGB灯灭
        LEDG0 = 0;
        LEDB0 = 0;
    }
}

void key_Proc3()    //按键处理
{
        unsigned int keyTim; //按键时间
    if(flag1ms3)  //1ms时间标志
    {
        flag1ms3 = 0;
        if(KEY3)
        {
        if((keyTim>10)&&(keyTim<1000))  //按键时间大于10ms小于50ms,是短按键
         {
         keyshort3 = 1;   //短按键标志
         }
         keyTim = 0;        //按键时间清零
        }
        else
        {
         if(keyTim<5000)    //按键时间小于10S
         keyTim++;           //按键时间加
         if(keyTim==1500)    //按键时间为1S
          {
          keylong3 = 1;    //长按键标志
          }
        }      
    }
}

void led_Proc3()   //灯处理
{
    if((LEDON==1)&&(keyshort3==1))  //关灯状态同时长按键按下就开灯
    {   
        keyshort3 = 0;  //长按键松开
        LEDON = 1;    //关灯时就开灯
        LEDR0 = 0;     //RGB灯亮白光
        LEDG0 = 0;
        LEDB0 = 1;
    }        
    if((LEDON==1)&&(keylong3==1)) //开灯状态同时长按键按下就关灯
    {   
        keylong3 = 0;  //长按键松开
        LEDON = 1;    //开灯时就关灯
        LEDR0 = 0;     //RGB灯灭
        LEDG0 = 0;
        LEDB0 = 0;
    }
    }
void key_Proc4()    //按键处理
{
        unsigned int keyTim; //按键时间
    if(flag1ms4)  //1ms时间标志
    {
        flag1ms4 = 0;
        if(KEY4)
        {
        if((keyTim>10)&&(keyTim<1000))  //按键时间大于10ms小于50ms,是短按键
         {
         keyshort4 = 1;   //短按键标志
         }
         keyTim = 0;        //按键时间清零
        }
        else
        {
         if(keyTim<5000)    //按键时间小于10S
         keyTim++;           //按键时间加
         if(keyTim==1500)    //按键时间为1S
          {
          keylong4 = 1;    //长按键标志
          }
        }      
    }
}

void led_Proc4()   //灯处理
{
    if((LEDON==1)&&(keyshort4==1))  //关灯状态同时长按键按下就开灯
    {   
        keyshort4 = 0;  //长按键松开
        LEDON = 1;    //关灯时就开灯
        LEDR0 = 0;     //RGB灯亮白光
        LEDG0 = 0;
        LEDB = 1;
    }        
    if((LEDON==1)&&(keylong4==1)) //开灯状态同时长按键按下就关灯
    {   
        keylong4 = 0;  //长按键松开
        LEDON = 0;    //开灯时就关灯
        LEDR0 = 0;     //RGB灯灭
        LEDG0 = 0;
        LEDB  = 0;
    }
    }

void Timer0Init()   //中断初始化
{
    TMOD &= 0XF0; //中断0模式1
    TMOD |= 0X01;
    TH0 = 0XFC;   //初值1ms
    TL0 = 0X66;
    ET0 = 1;     //允许T0中断
    TR0 = 1;    //定时器0开始计时
    EA = 1;       //开中断
    }

void interruptTimer0() interrupt 1
{
    TH0 = 0XFC;
    TL0 = 0X66;
    flag1ms = 1; //1ms标志
    flag1ms1 = 1; //1ms标志
      flag1ms2 = 1; //1ms标志
      flag1ms3 = 1; //1ms标志
      flag1ms4 = 1; //1ms标志
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

15#
ID:97678 发表于 2023-5-9 13:27 | 只看该作者
终于修改成功。运行正常了。
回复

使用道具 举报

14#
ID:161164 发表于 2023-5-8 20:58 | 只看该作者
jovew 发表于 2023-5-8 13:29
可以把代码给我看看吗?


回复

使用道具 举报

13#
ID:97678 发表于 2023-5-8 19:20 来自手机 | 只看该作者
xianfajushi 发表于 2023-5-8 15:30
还以为是这样的矩阵,按键时间弄那么长达几秒有什么意义?像图片这样的矩阵可以演化为一组IO能实现16*4的矩 ...

在机器上,发生故障,有的是短时间,有的是长时间的。必须逐个判断。分别处理故障。而且需要可靠。所以,一个点,就要一个键。
回复

使用道具 举报

12#
ID:332444 发表于 2023-5-8 15:30 | 只看该作者
还以为是这样的矩阵,按键时间弄那么长达几秒有什么意义?像图片这样的矩阵可以演化为一组IO能实现16*4的矩阵。


回复

使用道具 举报

11#
ID:97678 发表于 2023-5-8 13:57 | 只看该作者
wulin 发表于 2023-5-8 09:43
给你把按键扫描部分改了,灯处理按自己意图补充完善。

我想知道这个程序有什么问题,为什么不能工作?
回复

使用道具 举报

10#
ID:97678 发表于 2023-5-8 13:29 | 只看该作者
lkc8210 发表于 2023-5-8 10:04
除了led_Proc4()有一点问题(已修正)其他都正常

可以把代码给我看看吗?
回复

使用道具 举报

9#
ID:97678 发表于 2023-5-8 13:28 | 只看该作者
wulin 发表于 2023-5-8 09:43
给你把按键扫描部分改了,灯处理按自己意图补充完善。

谢谢!运行正常的!
我想知道我写的这个程序,哪里有问题?
回复

使用道具 举报

8#
ID:161164 发表于 2023-5-8 10:04 | 只看该作者
jovew 发表于 2023-5-8 08:15
还是不行! 我的程序,一个按键就可以工作。增加到5个按键,就不行了。

除了led_Proc4()有一点问题(已修正)其他都正常



回复

使用道具 举报

7#
ID:213173 发表于 2023-5-8 09:43 | 只看该作者
jovew 发表于 2023-5-7 18:47
还是不对!
还是部分操作正确,部分不正确。

给你把按键扫描部分改了,灯处理按自己意图补充完善。
  1. //K 是 开关机键。
  2. //k1,k2,k3,k4 是开机后,是操作键。键不能正常操作。
  3. #include"stc8h.h"
  4. /*
  5. sbit KEY  = P3^7;
  6. sbit KEY1 = P3^6;
  7. sbit KEY2 = P3^5;
  8. sbit KEY3 = P3^4;
  9. sbit KEY4 = P3^3;
  10. */
  11. unsigned char Key_value;//键值
  12. unsigned int keyTim; //按键时长
  13. bit flag1ms;//1ms中断标志

  14. void Timer0Init();  //T0初始化       
  15. void key_scan();    //按键扫描
  16. void led_Proc();   //灯处理

  17. void main()
  18. {
  19.         P0M0 = 0x00;
  20.         P0M1 = 0x00;
  21.         P1M0 = 0x00;
  22.         P1M1 = 0x00;
  23.         P2M0 = 0x00;
  24.         P2M1 = 0x00;
  25.         P3M0 = 0x00;
  26.         P3M1 = 0x00;
  27.         P4M0 = 0x00;
  28.         P4M1 = 0x00;
  29.         P5M0 = 0x00;
  30.         P5M1 = 0x00;
  31.         P6M0 = 0x00;
  32.         P6M1 = 0x00;
  33.         P7M0 = 0x00;
  34.         P7M1 = 0x00;       
  35.         P1=0x00;//P1用于演示键值
  36.         Timer0Init();  //T0初始化
  37.         while(1)
  38.         {
  39.                 key_scan();
  40.                 led_Proc();
  41.         }
  42. }

  43. void interruptTimer0() interrupt 1
  44. {
  45.         flag1ms = 1;    //1ms标志
  46. }

  47. void Timer0Init(void)//1毫秒@11.0592MHz
  48. {
  49.         AUXR |= 0x80;                //定时器时钟1T模式
  50.         TMOD &= 0xF0;                //设置定时器自动重载模式
  51.         TL0 = 0xCD;                        //设置定时初始值
  52.         TH0 = 0xD4;                        //设置定时初始值
  53.         TF0 = 0;                                //清除TF0标志
  54.         TR0 = 1;                                //定时器0开始计时
  55.         ET0 = 1;                                //允许T0中断
  56.         EA = 1;                                //开总中断
  57. }

  58. void key_scan()    //按键扫描
  59. {
  60.         unsigned char temp;//临时变量
  61.         if(flag1ms)  //1ms时间标志
  62.         {
  63.                 flag1ms = 0;//1ms时间标志清0
  64.                 temp=P3&0xf8;//5个独立按键P3.3~3.7
  65.                 if(temp!=0xf8)
  66.                 {
  67.                         if(++keyTim>1000)keyTim=1001;//防止溢出

  68.                         if(keyTim==10) //大于10ms小于1s算短按
  69.                         {
  70.                                 switch(temp)
  71.                                 {
  72.                                         case 0xf0: Key_value=0x01; break;
  73.                                         case 0xe8: Key_value=0x02; break;
  74.                                         case 0xd8: Key_value=0x03; break;
  75.                                         case 0xb8: Key_value=0x04; break;
  76.                                         case 0x78: Key_value=0x05; break;
  77.                                 }
  78.                         }
  79.                         if(keyTim==1000) //达到1s算长按
  80.                         {
  81.                                 Key_value|=0x10;
  82.                         }
  83.                 }
  84.                 else keyTim=0;        //按键松手keyTim清0
  85.         }
  86. }

  87. void led_Proc()   //灯处理
  88. {//短按等松手响应,长按达1s不论是否松手即响应
  89.         if((keyTim==0||keyTim==1000) && Key_value!=0x00)
  90.         {
  91.                 switch(Key_value)
  92.                 {
  93.                         case 0x01: P1=0x01; break;//短按1任务
  94.                         case 0x02: P1=0x02; break;//短按2任务
  95.                         case 0x03: P1=0x03; break;//短按3任务
  96.                         case 0x04: P1=0x04; break;//短按4任务
  97.                         case 0x05: P1=0x05; break;//短按5任务
  98.                         case 0x11: P1=0x11; break;//长按1任务
  99.                         case 0x12: P1=0x12; break;//长按2任务
  100.                         case 0x13: P1=0x13; break;//长按3任务
  101.                         case 0x14: P1=0x14; break;//长按4任务
  102.                         case 0x15: P1=0x15; break;//长按5任务
  103.                 }
  104.                 Key_value=0x00;//任务完成后键值清0
  105.         }
  106. }

复制代码
回复

使用道具 举报

6#
ID:97678 发表于 2023-5-8 08:15 | 只看该作者
lkc8210 发表于 2023-5-7 22:16
static unsigned int keyTim; //按键时间

还是不行! 我的程序,一个按键就可以工作。增加到5个按键,就不行了。
回复

使用道具 举报

5#
ID:97678 发表于 2023-5-8 06:26 来自手机 | 只看该作者
wulin 发表于 2023-5-7 19:16
你的按键代码问题严重,一二十行代码的事情你洋洋洒洒写了这么多?

我需要帮助。请您指出我的问题在哪里行吗?。
回复

使用道具 举报

地板
ID:161164 发表于 2023-5-7 22:16 | 只看该作者
static unsigned int keyTim; //按键时间
回复

使用道具 举报

板凳
ID:213173 发表于 2023-5-7 19:16 | 只看该作者
jovew 发表于 2023-5-7 18:47
还是不对!
还是部分操作正确,部分不正确。

你的按键代码问题严重,一二十行代码的事情你洋洋洒洒写了这么多?
回复

使用道具 举报

沙发
ID:97678 发表于 2023-5-7 18:47 | 只看该作者
wulin 发表于 2023-5-7 18:16
关于 I/O 的注意事项:
1、 P3.0 和 P3.1 口上电后的状态为弱上拉/准双向口模式
2、 除 P3.0 和 P3.1 外 ...

还是不对!
还是部分操作正确,部分不正确。
回复

使用道具 举报

楼主
ID:213173 发表于 2023-5-7 18:16 | 只看该作者
关于 I/O 的注意事项:
1、 P3.0 和 P3.1 口上电后的状态为弱上拉/准双向口模式
2、 除 P3.0 和 P3.1 外,其余所有 IO 口上电后的状态均为高阻输入状态,用户在使用 IO 口
前必须先设置 IO 口模式
3、 芯片上电时如果不需要使用 USB 进行 ISP 下载,P3.0/P3.1/P3.2 这 3 个 I/O 口不能同时
为低电平,否则会进入 USB 下载模式而无法运行用户代码
4、 芯片上电时,若 P3.0 和 P3.1 同时为低电平,P3.2 口会短时间由高阻输入状态切换到双
向口模式,用以读取 P3.2 口外部状态来判断是否需要进入 USB 下载模式
5、 当使用 P5.4 当作复位脚时,这个端口内部的 4K 上拉电阻会一直打开;但 P5.4 做普通
I/O 口时,基于这个 I/O 口与复位脚共享管脚的特殊考量,端口内部的 4K 上拉电阻依
然会打开大约 6.5 毫秒时间,再自动关闭(当用户的电路设计需要使用 P5.4 口驱动外
部电路时,请务必考虑上电瞬间会有 6.5 毫秒时间的高电平的问题)

void main()
{
//所有端口初始化为准双向口
        P0M0 = 0x00;
        P0M1 = 0x00;
        P1M0 = 0x00;
        P1M1 = 0x00;
        P2M0 = 0x00;
        P2M1 = 0x00;
        P3M0 = 0x00;
        P3M1 = 0x00;
        P4M0 = 0x00;
        P4M1 = 0x00;
        P5M0 = 0x00;
        P5M1 = 0x00;
        P6M0 = 0x00;
        P6M1 = 0x00;
        P7M0 = 0x00;
        P7M1 = 0x00;


        P0 = 0;
        P1 = 0;
        P2 = 0;       
        Timer0Init();  //中断初始化       
        while(1)
        {

评分

参与人数 1黑币 +15 收起 理由
ldc2000 + 15 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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