搜索
bottom↓
回复: 11

51单片机单按键多击程序遇到问题

[复制链接]

出0入44汤圆

发表于 2020-7-5 21:16:22 | 显示全部楼层 |阅读模式
本帖最后由 daiya1981 于 2020-7-6 08:31 编辑

写了一个响应单按键多击的程序,按键弹起大于0.5S后返回键值,有问题,无法运行。可是我才疏学浅,找不到问题出在哪里。请各位高人帮忙看看问题出在哪?

#include <reg52.h>

sbit LED0 = P1^0;
sbit LED1 = P1^1;
sbit LED2 = P1^2;

sbit KEY1 = P3^2;

unsigned int count = 0,ClickFlagCount = 0;
unsigned char i = 0,ClickFlag = 0,keynum = 0;

unsigned char keyscan(void)
{
        if(KEY1)
        {                                                
            if(count > 30 && count < 3000)
            {        
                ClickFlag = 1;
                 keynum++;
            }
            count = 0;
           if(ClickFlag == 1)
           {               
                if(ClickFlagCount++ > 500)
                {
                    ClickFlag = 0;
                    return keynum;
                    keynum = 0;
                }
                else
                {
                    ClickFlag = 0;
                }        
            }
            else
            {
                ClickFlagCount = 0;
            }
        }   
        else   
        {
                count++;
                if(count > 3000)
                        count = 3001;   
        }
        return 0;
}

void main()
{
     EA = 1;       //使能总中断
    TMOD = 0x01;  //设置T0为模式1
    TH0  = 0xFC;  //为T0赋初值0xFC67,定时1ms
    TL0  = 0x67;
    ET0  = 1;     //使能T0中断
    TR0  = 1;     //启动T0

    while (1)
    {
        switch (i)
        {
            case 1:        
                LED0 = ~LED0;
                break;
            case 2:
                LED1 = ~LED1;
                break;
            case 3:
                LED2 = ~LED2;
                break;                  
            default:
                break;
        }         
}

/* 定时器0中断服务函数 */
void InterruptTimer0() interrupt 1
{
    TH0 = 0xFC;  //重新加载初值
    TL0 = 0x67;
        i = keyscan();
}

出0入0汤圆

发表于 2020-7-5 23:55:39 | 显示全部楼层
有什么问题不说清楚一点,看下定时器中断函数能进去不。

出0入44汤圆

 楼主| 发表于 2020-7-6 08:26:25 | 显示全部楼层
本帖最后由 daiya1981 于 2020-7-6 08:28 编辑

定时器中断函数肯定进得去,我测试过了。这个程序是响应单按键多击,只要在按键抬起0,5秒之内按下均有效,可以响应1~N击,是个通用程序,可是由于我水平限制,里面肯定有错误,自己找不出来,请大家帮忙

出0入44汤圆

 楼主| 发表于 2020-7-6 11:26:01 | 显示全部楼层
我添加了注释,不知道可不可以看清楚逻辑了?

unsigned char keyscan(void)
{
    if(KEY1)
    {                                                
        if(count > 30 && count < 3000)    //如果按下时间30ms~3s,认为是单击
        {        
                ClickFlag = 1;    //按键抬起标志置1
                keynum++;    //键号加1
        }
        count = 0;    // 键按下时间计数器清0
        if(ClickFlag == 1)    //如果按键抬起标志为1
        {               
            if(ClickFlagCount++ > 500)    //按键抬起时间大于0.5s
            {
                ClickFlag = 0;    //按键抬起标志清0
                return keynum;    //返回键号
                keynum = 0;    //键号清0
            }
            else    //按键抬起时间小于0.5s
            {
                ClickFlag = 0;
            }        
        }
        else    //如果按键抬起标志为0
        {
            ClickFlagCount = 0;    //清0按键抬起时间计数器
        }
    }   
    else   
    {
        count++;    //按键按下时间计数器加1
        if(count > 3000)    //防止数据溢出
            count = 3001;   
    }
    return 0;
}

出16170入6148汤圆

发表于 2020-7-6 12:04:42 来自手机 | 显示全部楼层
打赏!

庆祝论坛“打赏”功能实施, 现在开始发技术主题,可以获得打赏
https://www.amobbs.com/thread-5735948-1-1.html

出0入20汤圆

发表于 2020-7-6 19:54:02 | 显示全部楼层
我们一般将键盘设计成一个独立模块,产生单击、延时击、延时后的快击,几种状态码,然后到相应的任务模块里调看键值,简单可靠。尽量不用定时器去延时,只用主程序执行的周期做计时,对于按键的去抖延时20-40毫秒,均无防。这样可以减少定时器的支出。
给你一段代码:
#include "Use.h"
#include "Ver.H"


#define Timer20ms        (80/TK_MAIN)                 //ÑÓʱʱ¼ä20mS
#define Timer3S                (1500/TK_MAIN)                 //ÑÓʱʱ¼ä2S
#define Timer100ms        (200/TK_MAIN)                //ÑÓʱʱ¼ä100mS
//**********************************************************
KEY                                KeyDat;                //¶¨ÒåÊý¾Ý½á¹¹
//**********************************************************
sbit KeyIn=P1^6;
sbit Clk_Key595=P2^7;
sbit Rck_Key595=P0^2;
sbit Dat_Key595=P0^3; //
//*********************************************
void SenDat_Key595(unsigned char Dat){
        unsigned char j=8;

        Rck_Key595=0;
        for (j=0;j<8;j++){
                Clk_Key595=0;
                Dat_Key595=(bit)(Dat & 0x80);
                Clk_Key595=1;       
                Dat<<=1;                          //×óÒÆÊäÈë
        }
        Rck_Key595=1;
}
//*********************************************
unsigned char ReadKey(void){
        unsigned char i,j=0;
       
        j =~HMLCtrl;
        j &=0x0f;
        j<<=1;
        if (fBZ==0) j |=0x01;
        //*****************************************

        i =0x60 | j;        // 0111,1111=7f 2005-3-22

        KeyIn=1;
        SenDat_Key595(i);
        if (!KeyIn) return 1; //Ka

        i=0xa0 | j;        //1011,1111 =bf
        SenDat_Key595(i);
        if (!KeyIn) return 2; //kb

        i=0xc0 | j;        //1101,1111=df
        SenDat_Key595(i);
        if (!KeyIn) return 3; //kc
        //***************************** KFo KFs
        return 0;
}

/************************************
ÅбðÊÇ·ñÓмü
*************************************/
void GetKey (void){
        if (ReadKey()!=0)        {
                KeyDat.KeyDog=Timer20ms;
                KeyDat.KeyPower++;
        }
}       
/**************************************
ÑÓʱȥ¶¶¶¯
***************************************/
void KeyDog(void){
        if (--KeyDat.KeyDog== 0){
                KeyDat.KeyData=ReadKey();        //¶Á¼üÅÌ               
                if (KeyDat.KeyData!=0){
                         KeyDat.KeyPower++;
                        KeyDat.KeyDog=Timer3S;
                }else{
                        KeyDat.KeyPower=0;
                        KeyDat.KeyData=0;                //·µ»Ø
                   }
        }
}
/*********************************
ÅбðÊÇ·ñËÉ¿ª
**********************************/
void KeyOff1(void){
        unsigned char i;
        i=ReadKey();
        if (i==0){                                                        //ËÉ¿ª°´¼ü
                KeyDat.KeyPower=0;
                KeyDat.KeyData |=HaveKey;        //¶¨Òå±êÖ¾               
//*****************************************                                               
                Beep_Start(0);                                        //·äÃùÆ÷¶ÌÃù
//******************************************
        }else{
                if (--KeyDat.KeyDog == 0){                 //3ÃëÑÓʱµ½
        //*****************************************                                               
                        Beep_Start(0);//·äÃùÆ÷¶ÌÃù
        //******************************************
                        KeyDat.KeyData |=HaveKey | DubClick;        //3SºóËÉ¿ªµÃµ½³¤ÑÓʱ¼ä¶¨Òå±êÖ¾               
                        KeyDat.KeyDog=3*Timer100ms;
                        KeyDat.KeyPower++;
                }
        }
}
/**********************************
Á¬»÷ÊÇ·ñËÉ¿ª
**********************************/
void KeyOff2(void){
        unsigned char i;
        i=ReadKey();
        if (i!=0){
                if (--KeyDat.KeyDog == 0){
                        KeyDat.KeyData =i | HaveKey | AddClick;        //¼ÓËÙ»÷±êÖ¾
                        KeyDat.KeyDog=Timer100ms;
//*****************************************                                               
                        Beep_Start(0);//·äÃùÆ÷¶ÌÃù
//******************************************
                }
        }else{
                KeyDat.KeyData =0;       
                KeyDat.KeyPower =0;
        }
}
/**********************************
º¯ÊýÖ¸Õ붨Òå
***********************************/
code void (code *SubKey[])()={
        GetKey,KeyDog,KeyOff1,KeyOff2       
};
/*****************************
¼ü´¦Àí³ÌÐò
******************************/
void KeyBord(void){
        (*SubKey[KeyDat.KeyPower])();

}
/**************************************
¼ü´¦ÀíºóÇå³ý¼üÖµ
***************************************/
unsigned char JB_KeyData(void){
        unsigned char i=0;

        if (KeyDat.KeyData > DubClick){
                i=KeyDat.KeyData;
                KeyDat.KeyData=0;
        }
        return i;
}       

出0入20汤圆

发表于 2020-7-6 19:54:32 | 显示全部楼层
奇怪了中文变成乱码。

出0入20汤圆

发表于 2020-7-6 19:56:40 | 显示全部楼层
/*****************************************************
¼üÅ̵ļüÖµ¶¨Òå
******************************************************/
#define AddClick                0x20                                //Á¬»÷
#define DubClick                0x40                                //µ¥»÷
#define HaveKey                        0x80                                //Óмü

#define        Ka                (0x01|HaveKey)
#define        Kb                (0x02|HaveKey)
#define        Kc                (0x03|HaveKey)
#define        Ko                (0x04|HaveKey)
#define        Ks                (0x05|HaveKey)
#define        Kos                (0x06|HaveKey)


#define Ka_Dub        (Ka  | DubClick | HaveKey)        //Ë«»÷       
#define Kb_Dub        (Kb  | DubClick | HaveKey)
#define Kc_Dub        (Kc  | DubClick | HaveKey)
#define        Ko_Dub        (Ko         | DubClick | HaveKey)
#define        Ks_Dub        (Ks  | DubClick | HaveKey)
#define        Kos_Dub        (Kos | DubClick | HaveKey)

#define Ka_Add         (Ka  | HaveKey | AddClick)        // ¼ÓËÙ       
#define Kb_Add         (Kb  | HaveKey | AddClick)
#define Kc_Add         (Kc  | HaveKey | AddClick)
#define        Ko_Add         (Ko         | HaveKey | AddClick)
#define        Ks_Add         (Ks  | HaveKey | AddClick)
#define        Kos_Add (Kos | HaveKey | AddClick)

//*******************************************************************
//ºìÍâ¼üÅ̶¨Òå
//*******************************************************************
#define K0_IR        0
#define K1_IR        1
#define K2_IR        2
#define K3_IR        3
#define K4_IR        4
#define K5_IR        5
#define K6_IR        6
#define K7_IR        7
#define K8_IR        8
#define K9_IR        9
//*********************************************************************
#define Ka_IR        1
#define Kb_IR        1
#define Kc_IR        1
#define Kd_IR        1
#define Ke_IR        1
#define Kf_IR        1
//*********************************************************************
#define K_up_IR                1
#define K_down_IR        1
#define K_left_IR        1
#define K_right_IR        1
#define K_ok_IR                1
#define K_esc_IR        1

出0入20汤圆

发表于 2020-7-6 19:57:23 | 显示全部楼层


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入20汤圆

发表于 2020-7-6 19:58:25 | 显示全部楼层
//---------------------------------------
typedef struct{
        unsigned char KeyPower;        //ÃüÁî×Ö
        unsigned int  KeyDog;        //ÑÓʱ
        unsigned char KeyData;        //¼üÖµ
}KEY;

出0入20汤圆

发表于 2020-7-6 19:59:19 | 显示全部楼层
采用状态机,将键译程序分解成几个工作状态。

出0入0汤圆

发表于 2020-7-8 17:26:05 | 显示全部楼层
学习了,谢谢
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 07:56

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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