新手入门
- 积分
- 20
- 金钱
- 20
- 注册时间
- 2016-8-3
- 在线时间
- 2 小时
|
发表于 2016-9-5 23:00:01
|
显示全部楼层
本帖最后由 ghw318 于 2016-9-5 23:03 编辑
本人初学者,在学到此处时也大为头疼,现把自己的一点心得写下,希望不对的地方多多指教,有益的地方作参考。
理解该问题最主要的点是对static的理解:静态可理解为:被该关键字修饰的变量的值存储在静态存储区域,只初始化一次,在函数执行过程中他的值可以被改变,但当再次参与到函数运算时,他的值是上次运行结束后的值(即第二次调用时的值=第一次调用结束时的值)
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;//按键按松开标志 //当该值位1时,才可以判断键值(因为被static修饰,
//所以只在第一次调用该函数时初始化,以后调用时的值是上次调用结束时的值)
if(mode)key_up=1; //mode为1时支持连按//也就是说每次调用该按键扫描函数时,先赋值key_up=1 ,直接进行按键扫描,所以实现了连按,
if(key_up&&(KEY0==0||KEY1==0||WK_UP==1)) /如果key_up不为1时 不进入该if语句
{
delay_ms(10);//去抖动
key_up=0;
if(KEY0==0)return KEY0_PRES;
else if(KEY1==0)return KEY1_PRES;
else if(WK_UP==1)return WKUP_PRES;
}
else
if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1;
return 0;// 无按键按下
}
该函数最关键点在前2句。
当mode=0时,当函数第一次调用,初始化static u8 key_up=1 后,key_up=1,下面进入if判断语句进行判断,不成立,直接跳到下面,进入if判断按键扫描语句进行判断,比如检测到KEY1按下,则延时10ms去抖动,赋值key_up=0(按键没有松开),并返回KEY1的返回值;第二次调用时:因为mode=0,则直接执行 if(key_up&&(KEY0==0||KEY1==0||WK_UP==1)) 这一句,由于第一次调用结束时key_up=0,所以不论按键是否按下,该语句均判断不成立,则执行else语句 if(KEY0==1&&KEY1==1&&WK_UP==0)进行判断,由于此时按键还是按下的,该条件不成立,则不执行key_up=1; 直接return 0;相当于没有按键按下,则实现了不支持连按。下次按键松开时,再执行 if(KEY0==1&&KEY1==1&&WK_UP==0)成立,赋值key_up=1,又可以进行正常的按键扫描。
当mode=1时,当函数第一次调用,初始化static u8 key_up=1 后,key_up=1,下面进入if判断语句进行判断,由于mode=1;所以每次进入该函数都会执行这一句,都会成立,都会赋值key_up=1,都会进入if判断按键扫描语句进行判断,所以每次进入都会返回键值,所以只要按着不动,按键就会一直被扫描到,就是所谓的连按。
note:static u8 key_up=1;只初始化一次,该变量相当于“只能在该函数内使用的全局变量” |
|