4*4键盘扫描程序--去抖加长按

前阵子做的是一个叫精密电压源的项目,使用了4*4的键盘,使用了8个GPIO,是比较简单的做法了,之前在网上看到一个老外已经能用3个GPIO实现多达25个按键的控制了,对应的接线图如下

使用的是新塘某Cortex-M0单片机,(讲真,单片机这部分虽然我水平不行但是我是写腻了),从网上找了些按键扫描程序又结合当前的项目写了一个按键扫描的程序,不用延迟来去抖,也可以添加长按功能,废话不多说,直接上代码

uint8_t b_key_scan;uint8_t b_key_debounce;uint8_t b_key_release;unsigned char key_scan_1()
{
    unsigned char pb;
    unsigned char n,m;
    if(b_key_scan==0) return 0;//Timer 定时将b_key_scan置1,为了去抖
    b_key_scan = 0;
    P20 = P21 = P22 = P23 = 0;
    P24 = P25 = P26 = P27 = 1;
    pb = P27 << 7 | P26 << 6 | P25 << 5 | P24 << 4;
    n = pb & 0xf0;
    P20 = P21 = P22 = P23 = 1;
    P24 = P25 = P26 = P27 = 0;
    pb = P23 << 3 | P22 << 2 | P21 << 1 | P20;
    m = pb & 0x0f;

    if((m!=0x0f)||(n!=0xf0))
    {
        x=n|m;
        if(b_key_release == 1)
        {
            b_key_debounce = 0;
            count_time++;
            if(count_time % 30 == 0)
            {
//                printf("continue_press=%x\n",x);//长按功能检测
                count_time = 1;
                key_continue = 1;
                return x;
            }
            return 0;
        }
        if(b_key_debounce == 0)
        {
            r_key_pre = x;
            b_key_debounce = 1;
            return 0;
        }
        b_key_debounce = 0;
    //compare twice key value
        if(r_key_pre != x)
            return 0;

        b_key_release = 1;//set key not release
        return x;
    }
    b_key_release = 0;
    key_continue = 0;
    return 0;

}
unsigned char key_scan(void)
{
    unsigned char num = 0xff;
    unsigned char key_value;

    key_value = key_scan_1();
    if(key_value)
    {
        Beep();
    //    printf("key_in = %x\n",key_value);
            switch(key_value)
            {
            case 0xee:num=‘0‘;break;
            case 0xed:num=‘1‘;break;
            case 0xeb:num=‘4‘;break;
            case 0xe7:num=‘7‘;break;
            case 0xde:num=‘.‘;break;
            case 0xdd:num=‘2‘;break;
            case 0xdb:num=‘5‘;break;
            case 0xd7:num=‘8‘;break;
            case 0xbe:num=‘+‘;break;
            case 0xbd:num=‘3‘;break;
            case 0xbb:num=‘6‘;break;
            case 0xb7:num=‘9‘;break;
            case 0x7e:num=‘-‘;break;
            case 0x7d:num=‘c‘;break;//confirm
            case 0x7b:num=‘s‘;break;//setup
            case 0x77:num=‘o‘;break;//output
            default:break;
            }
        }
        return num;
}

代码实现也很简单,按键扫描这一部分首先是先将GPIO 设为准双向模式,然后横坐标GPIO置0,纵坐标全部置1,,按键按下的时候,横坐标的GPIO 值会变0,就获取到横坐标的值,随后再将横坐标置1,纵坐标置0,按键按下的时候获取到纵坐标,有了横坐标和纵坐标就能确定是哪个按键被按下了。另外起一个定时器,每20ms或者30ms去执行一下扫描程序。人手按按键一般停留时间至少为100ms,所以扫描和去抖都没问题。简单记录一下,有不对的请告知

原文地址:https://www.cnblogs.com/yinseyingji/p/8143896.html

时间: 2024-09-29 01:52:02

4*4键盘扫描程序--去抖加长按的相关文章

4X4矩阵键盘扫描程序

4X4矩阵键盘扫描: 1. 4根行线的GIO均设为Output,根列线的GIO均设为Input: 2. 4根行线的GIO分别置为0111.1011.1101.1110,读逐一读取列线GIO的值,可确定是哪一个按键: 电路图如下: 注意: 1. 图中用作输入的GIO,一定要有一个上拉电阻. 2. 芯片中的每一个引脚是否用作了GPIO口来用,需配置芯片的寄存器,使引脚当作GPIO口来使用,才会有效. 测试代码如下: #define KEY_GIO_ROW_1 37 #define KEY_GIO_R

4x4矩阵键盘 扫描程序

一:不排除第四位异常处理 uchar JuzhenkeyScan() { // P3=0xfe; // temp=P3; // while(temp!=0xfe) // { // temp=P3; // switch(temp) // { // case 0xee:num=10; // break; // case 0xde:num=3; // break; // case 0xbe:num=2; // break; // case 0x7e:num=1; // break; // } // d

关于按键扫描程序的终极讨论

一.思路 基于STM8,按键处理,思路是这样的: 每20ms左右一次去扫描按键,用一个key_now记录当前值,用key_last记录上次的值,如果key_now和key_last同时有效,则开始进行cnt++. 我设定两个阈值,LONG_PRESS为100(100*20ms=2s),SHORT_PRESS为4(4*20ms=80ms,去抖). cnt大于LONG_PRESS,表示是长按,反之再判断cnt是不是大于SHORT_PRESS,表示是短按,否则把cnt清零. 另外一种情况,我们在设置参

4x4矩阵键盘扫描

4x4矩阵键盘扫描 Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一章我们讲了 Win10 IoT 如何对本地 IoT 设备内嵌 SQLite 数据库进行 CURD 操作 ,这章我们来学习如何使用 GPIO Pin 扫描4x4矩阵键盘按键状态.如果对安装部署过程还不熟悉可以参考前几篇文章,Raspberry安装 IoT系统及搭建开发环境(http:/

基于FPGA的按键扫描程序

最近在学习FPGA,就试着写了个按键扫描的程序.虽说有过基于单片机的按键扫描处理经验,对于按键的处理还是有一些概念.但是单片机程序的编写通常都采用C写,也有用汇编,而FPGA却是采用VHDL或者Verilog这种硬件描述语言来编写.初次利用VHDL编写控制程序,最开始就有点反应不过来了.采用VHDL语言编写程序与用C语言编写,在思维上会有很大的不一样,因为C程序时顺序执行的,而VHDL语言各个进程之间是并行执行的,这就会要考虑到时序方面的问题,这正也合乎了硬件工作实际过程,毕竟各个功能模块之间既

最好的按键扫描和消抖方法,适用于复合、长按、按下或抬起响应按键

刚参加工作的时候,看了一些同事采用的按键扫描和消抖方法,对比学校里和网上查到的按键处理,发现觉得不尽善尽美,有以下几点: 1. 消抖复杂,效率低.有人直接在电平判断后使用delay()函数,进行消抖,耽误时间:有人在按键电平中断中进行消抖和处理,导致其他的服务反应慢,不适合做实时系统: 2. 许多功能在不同界面下是不同的,把按键处理在中断进行,导致分支很多,业务流不清晰. 3. 特殊功能按键的处理麻烦.在需要长按作为特殊按键.复合按键响应.复合按键长按响应的时候,需要增加很多的标志位,反复使用i

编译原理学习:TINY语言词法扫描程序实现

最近对解释型程序(类似python或者是linux里的bc计算器)非常感兴趣,就开始学习一下编译原理.今天自己实现了TINY语言的词法扫描程序.大部分参考<编译原理及实践>一书.但是我做了一些小小的改进. 先说一下TINY语言: 1.注释:放在一对大括号内.书上的注释不能嵌套,我做了一点改进,允许嵌套. 2.关键字:read write if end repeat until else 3.类型:只支持整型和布尔型. 4.计算:+ - * / ( ) < = :=,其中:=为赋值运算,=

矩阵键盘扫描算法

函数的主体 unsigned char GetKey() { unsigned char i,j,k; static unsigned char backup[4][4]={ {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1} }; EA=1; TMOD=0x01;//设置T0为模式1 TH0=0xF8; TL0=0xCD; ET0=1;//使能T0中断 TR0=1;//启动T0 while(1) { for(i=0;i<4;i++)//循环检测4×4的矩阵按键 {

MiS603开发板 第五章 按钮去抖实验

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第五章 按钮去抖实验 按键的消抖,是指按键在闭合或松开的瞬间伴随着一连串的抖动,这样的抖动将直接影响设计系统的稳定性