stm32 按键 扫描 实验

按键扫描的两种模式:

  1. 支持连续按
         就是:一直按着也算有效
         例如:按键检测时间为1ms 按了1s的话等同于按了十次

    思路:

    u8 KEY_Scan(void){
        if(KEY按下){
            delay_ms(10);//延时10ms  进行软件消抖
            if(KEY确实按下){
                return KEY_Value;
            }
            return 无效值;
        }
    }
    
  2. 不支持连续按
         就是:一直按着也只算按了一次
         也即是上一次按键是松开的 这一次按下才有效
         例如:按键检测时间为1ms 按了1s的话等同于按了一次

不支持连续按的话就需要有一个变量来记录按键的上一次为开或关

思路:

u8 KEY_Scan(void){
    static u8 Key_up=1;
    if(key_up && KEY){fandou
        delay_ms(10);//延时,防抖
        Key_up=0;//标志这次已经按下
        if(Key确实按下){
            return KEY_Value;
        }
    }else if(KEY没有按下) Key_up=1;
    return 没有按下;
}
  1. 支持连续按&&不支持连续按的代码思路

    u8 KEY_Scan(u8 mode){
        static u8 Key_up=1;
        if(mode==1) Key_up=1;//支持连续按
        if(Key_up && KEY 按下){
            delay_ms(10);//延时,防抖
            Key_up=0;//标记这次已经按下
            if(KEY确实按下){
                return KEY_Value;
            }
        }else if(KEY没有按下) Key_up=1;
        return 没有按下;
    }
    

C语言static关键字

tatic关键字

普通局部变量是再熟悉不过的变量了,在任何一个函数内部定义的变量(不加static修饰符)都属于这个范畴。编译器一般不对普通局部变量进行初始化,也就是说它的值在初始时是不确定的,除非对其显式赋值。

普通局部变量存储于进程栈空间,使用完毕会立即释放。

静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。

变量在全局数据区分配内存空间;编译器自动对其初始化
其作用域为局部作用域,当定义它的函数结束时,其作用域随之结束

int getValue(void){
    int flag=0;
    flag++;
    return flag;
}
多次调用返回值为 11111111

int getValue(void){
    static int flag=0;
    flag++;
    return flag;
}
多次调用返回值为 1234567

上述两个函数中 唯一不同的就是 flag 是否使用了static关键字,没使用static关键字的函数每次执行flag都会被重新赋值,使用了static关键字的函数flag只会在第一次调用时赋值 之后都不会被赋值 可以用来保存上一次按键的状态值。

最终代码

//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下 
//4,KEY3按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>KEY3!!
u8 KEY_Scan(u8 mode)
{	 
	static u8 key_up=1;//按键按松开标志
	if(mode)key_up=1;  //支持连按		  
	if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
	{
		delay_ms(10);//去抖动 
		key_up=0;
		if(KEY0==0)return KEY0_PRES;
		else if(KEY1==0)return KEY1_PRES;
		else if(KEY2==0)return KEY2_PRES;
		else if(WK_UP==1)return WKUP_PRES;
	}else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1; 	    
 	return 0;// 无按键按下
}

猜你喜欢

转载自blog.csdn.net/qq_45816372/article/details/106714261