[51单片机]

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

[复制链接]
1057|6
手机看帖
扫描二维码
随时随地手机跟帖
daiya1981|  楼主 | 2020-7-5 20:17 | 显示全部楼层 |阅读模式
写了一个响应单按键多击的程序,按键弹起大于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,ClickFlag = 0,ClickFlagCount = 0,LongClickFlag = 0;
unsigned char i = 0,Click = 0;
unsigned char 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;
                ClickFlagCount = 0;
                return keynum;
                keynum = 0;
            }
            else
            {
                ClickFlag = 0;
                ClickFlagCount = 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)
    {
        if(i==1)
            LED0 = ~LED0;
        if(i==2)
            LED1 = ~LED1;
        if(i==3)
            LED2 = ~LED2;
    }     
}

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

使用特权

评论回复

相关帖子

LcwSwust| | 2020-7-5 20:44 | 显示全部楼层
这个逻辑有问题:
if(ClickFlagCount++ > 500)
{

}
else
{

       ClickFlagCount = 0;
}   

使用特权

评论回复
daiya1981|  楼主 | 2020-7-6 08:19 | 显示全部楼层
本帖最后由 daiya1981 于 2020-7-6 08:34 编辑

我改掉了,可是程序对于按键击发还是没反应

#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();
}

使用特权

评论回复
coody| | 2020-7-6 10:47 | 显示全部楼层
我觉得很简单的处理,每次按下都记录时刻,跟上一时刻比较即可。我的产品经常要一个键有多击和长按,比如播放器,长按3秒开机,长按3秒关机,短单击播放、暂停,双击进入设置。

使用特权

评论回复
daiya1981|  楼主 | 2020-7-6 11:25 | 显示全部楼层
我添加了注释,不知道可不可以看清楚逻辑了?

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;
}

使用特权

评论回复
ayb_ice| | 2020-7-7 10:29 | 显示全部楼层


#include <reg52.h>

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

sbit KEY1 = P3^2;

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


typedef struct{
        bit bBkpGpio;
        u08 ucPushNum;
        u16 usPopCnt;
        u08 ucScaleCnt;
       
        u08 ucNum;
       
}Key_Typedef;


Key_Typedef stKey;

bit keyscan(void)
{
        bit bThisGpio;
        bit bRtn = 0;

        if (++stKey.ucScaleCnt >= 10)
        {
                stKey.ucScaleCnt = 0;

                bThisGpio = KEY1;
                if (bThisGpio)
                {
                        if (++stKey.usPopCnt >= 500/10)
                        {
                                stKey.ucNum = stKey.ucPushNum;
                                stKey.ucPushNum = 0;
                                bRtn  = 1;
                        }
                }

                if (bThisGpio != stKey.bBkpGpio)
                {
                        if (!bThisGpio)
                        {
                                stKey.ucPushNum++;
                                stKey.usPopCnt = 0;
                        }
                        stKey.bBkpGpio = bThisGpio;
                }
        }

        return bRtn;
}

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

    while (1)
    {
        if(ucLedMode==1)
            LED0 = ~LED0;
        if(i==2)
            LED1 = ~LED1;
        if(ucLedMode==3)
            LED2 = ~LED2;
    }     
}

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

使用特权

评论回复
daiya1981|  楼主 | 2020-7-7 11:49 | 显示全部楼层
谢谢各位,愿好人一生平安!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

7

帖子

0

粉丝