打印

用于4ms Timer中断的键盘扫描 实例(源代码)

[复制链接]
1063|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kingkits|  楼主 | 2019-12-16 13:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 kingkits 于 2019-12-19 15:49 编辑

看到很多朋友都困惑如何扫描键盘,这里给出一个简单单排(非矩阵式键盘)扫描的程序,希望能给大家帮助

static  unsigned char key;
static  unsigned char new_key_pushed_flag;
static  unsigned char key_pushed_flag;
static  uint16_t key_pushed_time;
static unsigned char key_current;
static unsigned char key_old;
static unsigned char key_cnt;

void init_key_data(void)
{
    key = 0;
    key_pushed_flag = 0;
    key_pushed_time = 0;
    key_current = 0;
    key_old = 0;
    key_cnt = 0;
}

// note: one pushed key only one time
uint8_t get_key(void)
{
    uint8_t key_tmp;
    if(new_key_pushed_flag)
    {
        new_key_pushed_flag = 0;
        key_tmp = key;
        key = 0;
        return key_tmp;
    }
    return 0;
}

// 这里读取按键按下时间,单位是4ms (因为我用4ms中断调用的,你的可能不太一样),可以用于判断长时间按下,最长大概有1秒,如果你需要更长,需要改改
uint16_t get_key_pushed_time(void)
{
    return key_pushed_time;
}

// 这里判断是否有按键按下

uint8_t is_key_pushed(void)
{
    return key_pushed_flag;
}

// 我用4ms中断调用这个函数,这个函数已经做了去抖动了。正常的按键都能识别。
void check_key(void)
{
    uint32_t key_data;
    // 这一部分要替换成你的代码
    // --->
    key_data = GPIOK->IDR;
    key_data >>= 4;
    key_data = (uint8_t)(key_data & 0xf);
    key_data ^= 0xf;
    // <----

    // 我这里用0 表示没有按键按下,你的可能不一样
    if(key_data == 0)
    {
        key_pushed_flag = 0;
        key_pushed_time = 0;
    }
    else
    {
        key_pushed_flag = 1;
    }
    key_current = key_data & (key_data ^ key_cnt);
    key_cnt = key_data;
    if(key_current == 0)
    {
        key_old = 0;
        key_pushed_time = 0;
        return;
    }
    if(key_current == key_old)
    {
        // 防止溢出
        if(key_pushed_time < 0xfe)
        {
            key_pushed_time ++;
        }
    }
    else
    {
        new_key_pushed_flag = 1;
        key_old = key_current;
        key = key_current;
    }
}

使用特权

评论回复
评论
dirtwillfly 2019-12-16 13:42 回复TA
感谢分享 

相关帖子

沙发
kingkits|  楼主 | 2019-12-17 08:58 | 只看该作者
不会用么?
先把check_key()中关于按键的IO操作改好
在4ms中断处理函数中调用check_key()

使用时可以这样

...//你的其他代码

// 判断按键,并处理
if(is_key_pushed())
{
     key=get_key();
     switch(key)
     {
           case xxx:
               ....
           default:
                ....
     }
}
....//你的其他代码

使用特权

评论回复
板凳
asdsfgwsafd| | 2019-12-20 08:53 | 只看该作者
为什么是用定时中断,感觉要求不高就在主循环里扫描,要求高的就用外部中断做了

使用特权

评论回复
地板
kingkits|  楼主 | 2019-12-20 09:40 | 只看该作者
asdsfgwsafd 发表于 2019-12-20 08:53
为什么是用定时中断,感觉要求不高就在主循环里扫描,要求高的就用外部中断做了 ...

这里有个判断按键时间长短的地方,用4ms比较容易计算,在主循环里,就很难把握时间了

使用特权

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

本版积分规则

2

主题

646

帖子

1

粉丝