key_scan(按键扫描)程序解读

本文是对“按键扫描”程序的解读。

硬件设置

“ KEY0 、KEY1、KEY2 ” 三个按键,按下时为低电平,不按时为高电平,且低电平(0)有效;

“ WK_UP ” 按键,按下时为高电平,不按时为低电平,且高电平(1)有效;

程序源码

uint8_t key_scan(uint8_t mode)
{
    static uint8_t key_up = 1;         
    uint8_t keyval = 0;

    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)  keyval = KEY0_PRES;
        
        if (KEY1 == 0)  keyval = KEY1_PRES;
        
        if (KEY2 == 0)  keyval = KEY2_PRES;
        
        if (WK_UP == 0)  keyval = WKUP_PRES;    
    }
    else if (KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && WK_UP == 0)
    {
        key_up = 1;
    }
    
    return keyval;

}
 

 源码解读

static uint8_t key_up = 1;       

 这行代码声明了一个名为 key_up 的静态变量,其类型为 uint8_t(无符号8位整数),并初始化为1。key_up 用于表示按键的状态,初始值1通常表示按键未被按下。

uint8_t keyval = 0;

这行代码声明了一个名为 keyval 的变量,其类型同样为 uint8_t,并初始化为0。 keyval 用于存储按键的值。

if (mode) key_up = 1;

这段代码是一条条件语句,用于根据变量mode的值来设置另一个变量key_up的值。如果mode为真(即非零),则key_up被设置为1。其中mode也是key_scan的形参,需要编程人员给定。

if (key_up && (KEY0 == 0 || KEY1 == 0 || KEY2 == 0 || WK_UP == 1));

这段代码是一个条件语句,用于检测按键的状态。同时,这段代码也和后边的“ else if ”共同构成判断语句。

“KEY0、KEY1、KEY2、WK_UP” 代表不同的按键。对于“KEY0、KEY1、KEY2”,0表示按键被按下,1表示按键未被按下;对于“WK_UP”,则正好相反,详见开篇的“硬件设置”。

“||”,逻辑或运算符,只要表达式中的任意一个条件为真,整个表达式就为真;

“&&”,逻辑与运算符,只有表达式中的所有条件都为真,整个表达式才为真;

整段代码的意思是,当变量 key_up为1(即按键未被按下),并且 KEY0KEY1KEY2中的任意一个为0(表示被按下)或者 WK_UP为1(表示按键被按下)时,执行花括号{}中的代码块

if 语句的基本格式是:

if (布尔表达式)

{

        /* 如果布尔表达式为真(即非零),将执行的语句 */

}

 因此,下边这两行代码,将在 if 后边的布尔表达式为真时执行,

   delay_ms(10);
   key_up = 0;

“ delay_ms(10);” 这行代码的意思是,为按键的读取添加10ms的延时,主要是为了消抖;

“ key_up = 0;” 这行代码的意思是,将变量 key_up置0,表示按键已被按下;

        if (KEY0 == 0)  keyval = KEY0_PRES;
        
        if (KEY1 == 0)  keyval = KEY1_PRES;
        
        if (KEY2 == 0)  keyval = KEY2_PRES;
        
        if (WK_UP == 0)  keyval = WKUP_PRES;

这几行代码也是 if 花括号{}中的代码,他们和上述的10ms延时以及key_up置0,都是在 if 后边的布尔表达式为真时执行,这四行代码是单独的 if 判断语句。

这几行代码的意思是,判断具体是哪个按键被按下,上述四条 if 语句从上到下依次执行。

第一条语句的意思是,如果 KEY0=0 (即按键 KEY0 被按下),则将 KEY0_PRES 的值赋给  keyval 。

第二条语句的意思是,如果 KEY1=0 (即按键 KEY1 被按下),则将 KEY1_PRES 的值赋给  keyval 。

第三条、第四条语句类似,不再叙述。

else if (KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && WK_UP == 0)

这行代码,与上文的 if 共同构成 “if···else if···” 判断语句,其基本格式如下,

if (布尔表达式1)

{

        /* 如果布尔表达式1为真(即非零),将执行的语句 */

}

else if (布尔表达式2)

{

        /* 如果布尔表达式2为真(即非零),将执行的语句 */

}

它的执行顺序是,当 if 语句的条件为真时,会执行 if 块内的代码,并且后续的 else if 语句将不会被执行。如果 if 条件为假,程序会继续检查后续的 else if 条件,直到找到为真的条件后,执行真条件块内的代码。

因此,

else if (KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && WK_UP == 0)
    {
        key_up = 1;
    }

这段代码的意思是,判断 KEY0、KEY1、KEY2、WK_UP 的键值,并将 key_up 的值置1。

当 KEY0、KEY1、KEY2 都为高电平(即没有被按下)且 WK_UP 为低电平(没有被按下)时,将 key_up 的值置1。

    return keyval;

这行代码的作用是结束程序的执行并将 keyval 的值返回给函数。

总结

key_scan(按键扫描)程序解读_第1张图片

你可能感兴趣的:(stm32,嵌入式硬件,单片机,笔记)