STM32
直播中

李刚

7年用户 1320经验值
私信 关注
[问答]

使用系统滴答定时中断,基于按键的状态机怎么只能1个1个+,不能连+?

使用系统滴答定时中断,基于按键的状态机怎么只能1个1个+,不能连+
#define KEY1_USER                        GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)
unsigned char Key_Scan(void)
{      
  static unsigned int KeyStateTemp = 0, KeyTime=0;  //按键状态及按键时间
  static unsigned char num=0;            //  按键次数
   
switch(KeyStateTemp)
{
  case StateInit:      
   if(!KEY1_USER)   
    KeyStateTemp = StateAffirm;
   break;
  case StateAffirm:     
   if(!KEY1_USER)   
   {
    KeyTime = 0;
    KeyStateTemp = StateSingle;
   }
   else KeyStateTemp = StateInit;  
   break;
  case StateSingle:     
   if(KEY1_USER )   
   {
    KeyStateTemp = StateInit;   
    num++;      
    if(125== num)  num = 0;
   }
   else if(++KeyTime > 1000)  //按键时间1000*1MS
   {
    KeyStateTemp = StateRepeat;
     KeyTime = 0;
   }
   break;
  case StateRepeat:     
   if(KEY1_USER )
    KeyStateTemp = StateInit;
   else      
   {
    if(++KeyTime > 200)   //按键时间
    {
     KeyTime = 0;
     num++;                  
     if(125== num)  num = 0;
    }
    break;
   }
   break;
        default: KeyStateTemp = KeyStateTemp = StateInit; break;
}
  return num;
}

回帖(1)

hsdou月半

2024-5-16 17:48:11
要实现基于按键的状态机,使其能够连续加(连+),我们需要对按键扫描函数进行一些修改。首先,我们需要确保按键扫描函数能够识别按键的长按和短按,以便在短按时执行加操作,而在长按时执行其他操作(如连续加)。

以下是修改后的按键扫描函数,实现了连续加的功能:

```c
#define KEY1_USER GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13)
#define DEBOUNCE_TIME 50 // 去抖动时间,单位为ms
#define LONG_PRESS_TIME 500 // 长按时间阈值,单位为ms

unsigned char Key_Scan(void) {
    static unsigned int KeyStateTemp = 0, KeyTime = 0;
    static unsigned char num = 0;
    static unsigned char key_state = 0; // 新增按键状态变量
    unsigned int key_current_state = KEY1_USER; // 当前按键状态

    if (key_current_state != KeyStateTemp) {
        KeyTime = 0; // 重置按键时间
        KeyStateTemp = key_current_state;
    } else {
        KeyTime++; // 按键时间累加
    }

    switch (key_state) {
        case 0: // 检测按键是否按下
            if (KeyTime >= DEBOUNCE_TIME && key_current_state == Bit_SET) {
                key_state = 1;
            }
            break;
        case 1: // 检测按键是否长按
            if (KeyTime >= LONG_PRESS_TIME) {
                key_state = 2;
            } else {
                // 短按,执行加操作
                num++;
                key_state = 0; // 返回初始状态
            }
            break;
        case 2: // 长按,执行连续加操作
            if (KeyTime < LONG_PRESS_TIME) {
                num++; // 连续加
            } else {
                key_state = 0; // 返回初始状态
            }
            break;
        default:
            key_state = 0; // 重置状态
            break;
    }

    return num;
}
```

在这个修改后的函数中,我们添加了一个名为`key_state`的静态变量,用于跟踪按键的状态。我们使用了一个状态机,其中有三个状态:0(检测按键是否按下)、1(检测按键是否长按)和2(长按,执行连续加操作)。

当按键被短按时,状态机会执行加操作并将状态重置为0。当按键被长按时,状态机会进入连续加操作状态(状态2),并在长按期间持续执行加操作。

请注意,您需要根据您的硬件平台和需求调整`DEBOUNCE_TIME`和`LONG_PRESS_TIME`的值。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分