再发一种基于stm32的4X4矩阵键盘定时器扫描消抖法,彻底告别delay函数! .

        本人今天又换种思路写了个关于stm32的4X4矩阵键盘定时器扫描消抖法的算法程序,同样是采用的效率较高的翻转法,已通过测试,希望大家喜欢!大概思路为:将端口的第N次扫描值和第(N-1)次的扫描值进行比较,若相等则某个变量自增1次,否则将其清0,当此变量自增的值达到某个值时,则认为按键确实是被按下了,然后再进行后续的行和列的查找工作,最终确定是哪个按键被按下了!注:本程序的定时器中断扫描周期为10ms,同上次本矩阵键盘是采用的PB口的低8位。这个程序只是表达了思路,写得很粗糙,大家可以自行改进。代码如下:

s8 scan_MatrixKey(void)
{
    #define PORT GPIOB->IDR
    u8 column;
    u8 row;
    u8 tmp;
    static u8 j;
    static u8 x;
    static u8 i;
    s8 MatrixKey_value = 20; 
   
    //低8位为推挽输出
    GPIOB->CRL &= 0X00000000;
    GPIOB->CRL |= 0X33333333;
    //初值:低4位为低,次低4位为高
    GPIOB->ODR &= 0XFF00;
    GPIOB->ODR |= 0X00F0;
    //次低4位为上拉输入
    GPIOB->CRL &= 0X0000FFFF;
    GPIOB->CRL |= 0X88880000;

    tmp = PORT;//必须要

    if (tmp != 0XF0)//说明有键按下
    {          
        i++;//记录中断扫描的次数
        if (i == 1)//第一次扫描
        {
            //把tmp的值(即PORT的值)存起来
            //以便和后续扫描所得的PORT的值进行比较
            x = tmp;
        }
        else if (i == 2)//第二次扫描
        {
            if (x == tmp)//把第二次扫描PORT的值和前一次比较
            {
                j++;//j=1
            }
            else//2次扫描PORT的值不等说明有抖动
            {
                j = 0;//将j清0
                x = tmp;//将最新的tmp的值(即PORT的值)再存起来
            }
        }
        else if (i == 3)//第三次扫描
        {
            if (x == tmp)
            {
                j++;//j=2
            }
            else
            {
                j = 0;
                x = tmp;
            }
        }
        else if (i == 4)//第四次扫描
        {
            if (x == tmp)
            {
                j++;//j=3
            }
            else
            {
                j = 0;
                x = tmp;
            }
        }
        //经历2个中断扫描周期后确定按下
        if (j == 2)//此处数值可以由定时器中断扫描的周期而改动
        {                              
            column = tmp & 0X00F0;//获取列号
            //低8位为推挽输出
            GPIOB->CRL &= 0X00000000;
            GPIOB->CRL |= 0X33333333;
            //翻转:低4位为高,次低4位为低
            GPIOB->ODR &= 0XFF00;
            GPIOB->ODR |= 0X000F;
            //低4位为上拉输入
            GPIOB->CRL &= 0XFFFF0000;
            GPIOB->CRL |= 0X00008888;                    
            row = PORT & 0X000F;//获取行号

            switch (column | row)//column|row为按键被按下对应端口的编码
            {  
                //按键对应的码表(可以根据需求调整欲返回的键值) 
                case 0XEE: MatrixKey_value = 12; break; 
                case 0XDE: MatrixKey_value = 10; break;
                case 0XBE: MatrixKey_value = 11; break;               
                case 0X7E: MatrixKey_value = 0; break;                                              
                case 0XED: MatrixKey_value = 13; break;
                case 0XDD: MatrixKey_value = 3; break;
                case 0XBD: MatrixKey_value = 2; break;
                case 0X7D: MatrixKey_value = 1; break;                                  
                case 0XEB: MatrixKey_value = 14; break;
                case 0XDB: MatrixKey_value = 6; break;
                case 0XBB: MatrixKey_value = 5; break;
                case 0X7B: MatrixKey_value = 4; break;                                    
                case 0XE7: MatrixKey_value = 15; break;
                case 0XD7: MatrixKey_value = 9; break;
                case 0XB7: MatrixKey_value = 8; break;
                case 0X77: MatrixKey_value = 7; break;
                default:   break;    
            }
        }      
    }
    //没有按键被按下时对计数变量清0
    if ((PORT & 0X00FF) == 0x00F0)
    {
        i = 0;
        j = 0;
    }

    return MatrixKey_value;
}

        上一篇stm32矩阵键盘扫描定时器消抖代码链接为:

http://blog.csdn.net/dcx1205/article/details/8859509

 

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页