关于蓝桥杯按键长按短按-按位与的应用

#学习

首先介绍一下按位与是:

按位与运算是一种二进制运算,它用来对两个二进制数的每个对应位进行逻辑与操作。按位与运算的规则如下:

对于每一个位的操作:

- 如果两个对应的位都是1,则结果位为1。

- 如果其中一个或两个对应的位是0,则结果位为0。

下面是按位与运算的示例:

```

  10101011 (173 in decimal)

& 11001100 (204 in decimal)

-----------

  10001000 (136 in decimal)

```

在上面的例子中,我们对二进制数10101011和11001100进行按位与运算。对于每个位的操作如下:

- 第1位:1 & 1 = 1

- 第2位:0 & 1 = 0

- 第3位:1 & 0 = 0

- 第4位:0 & 0 = 0

- 第5位:1 & 1 = 1

- 第6位:0 & 1 = 0

- 第7位:1 & 0 = 0

- 第8位:1 & 0 = 0

结果为10001000,对应的十进制数是136。

在实际编程中,按位与运算通常用于对某些位进行屏蔽或提取操作。例如,通过与一个掩码进行按位与运算,可以将某些位设置为0,保留其他位不变。

#define SHORT_PRESS_THRESHOLD 200 // Short press

#define LONG_PRESS_THRESHOLD 1000 // Long press

 

uint8_t Key_Scan(void)

{

    static uint8_t previousState[4] = {1, 1, 1, 1}; // Record the previous key states, defaulting to not pressed

    static uint32_t lastScanTime = 0; // Last key scan time

    uint8_t currentState[4]; // Current key states

 

    // Get the current time

    uint32_t currentTime = HAL_GetTick();

 

    // Check if it meets the cooldown time (assuming the cooldown time is 200ms)

    if (currentTime - lastScanTime < 200)

    {

        return 0; // If still within the cooldown time, return 0, indicating no key press

    }

 

    currentState[0] = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);

    currentState[1] = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);

    currentState[2] = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2);

    currentState[3] = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);

 

    // Detect key state changes and return the corresponding key number

    for (uint8_t i = 0; i < 4; i++)

    {

        if (currentState[i] == 0 && previousState[i] == 1) // When the key changes from not pressed to pressed

        {

            previousState[i] = currentState[i]; // Update the previous key state

            lastScanTime = currentTime; // Record the current time

            return i + 1; // 返回密钥编号(从 1 开始)

        }

        else if (currentState[i] == 0 && previousState[i] == 0) // When the key is being held down

        {

            if (currentTime - lastScanTime >= LONG_PRESS_THRESHOLD) // Long press detected

            {

                lastScanTime = currentTime; // Update the last scan time to avoid triggering multiple times

                return (i + 1) | 0x80; // 返回键号,MSB 设置为 1 表示长按

       

            }

        }

        else // When the key is released or not pressed

        {

            previousState[i] = currentState[i]; // Update the previous key state

        }

    }

 

    return 0; // No key press detected, return 0

}

 

长按短按检测:

78f0d9859f914b01bdabdc1b78cd5037.jpg

 在这个例子中,`flag & 0x80` 的结果是 `10000000`,也就是 `0x80`。这是因为只有最高位为1的位在两个数中同时为1,其它位都为0。

 

在 C/C++ 中,非零值被视为真,而零被视为假。因此,当 `flag & 0x80` 的结果为非零值时,条件为真,意味着最高位为1,表示长按。当结果为零时,条件为假,表示不是长按。这样就可以通过 `if (flag & 0x80)` 来判断是否为长按。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值