找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2317|回复: 5
收起左侧

按键状态机配置运用 STM32源程序

  [复制链接]
ID:815787 发表于 2020-8-29 17:08 | 显示全部楼层 |阅读模式
#include "key.h"
/**********************************************************************
    *函数名:KEY_init
    *功  能:按键初始化
    *参  数:无
    *返  回:无
    *备  注:
        KEY  ----  PA0
**********************************************************************/
void KEY_Init(void)
{

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    //使能PA时钟
        GPIO_InitTypeDef GPIO_InitStructure;                                    //定义结构体变量
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //浮空输入模式
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

}

/****************************************************************
    驱动层
    1.完成按键的消抖,松手检测
    2.把过程细分为一个个状态
    3.实现长按与单击功能
   
    按键初始态                  0
    按键消抖与确认态          1
    按键的单击和长按状态      2
    等待按键释放状态            3

*****************************************************************/
u8 key_driver()
{
    static unsigned char state = 0, time = 0;           //静态变量具有记忆性,不会再读取这里的赋值
    unsigned char key_return = N_key;                   //不用静态,避免按键释放的时候回不到无键状态

    switch (state)
    {
      case 0:                                         // 按键初始态  
        if (!KEY) state = 1;                        // 键被按下是0,非0即真,状态转换到按键消抖和确认状态  1
        break;
      
      case 1:                                          // 按键消抖与确认态
        if (!KEY)                                     // 再次确认按键是否按下
        {
             time = 0;                              // 按键按下,开始计时
             state = 2;                             // 按键仍然处于按下,消抖完成,状态转换到按下键时间的计时状态,但返回的还是无键事件
        }         
        else
             state = 0;                           // 按键已抬起,转换到按键初始态。此处完成和实现软件消抖,其实按键的按下和释放都在此消抖的。
        break;
      
      case 2:
        if(KEY)                                 //前面确认按键按下后,此时按键释放为1
        {
             key_return = S_key;                // 此时按键释放,说明是产生一次短操作,返回S_key
             state = 0;                           // 转换到按键初始态
        }
        else if (++time >= 100)                 // 继续按下,
        {
             key_return = L_key;                //  
             state = 3;                          // 转换到等待按键释放状态
        }
        break;

      case 3:                                     // 等待按键释放状态,此状态只返回无按键事件
        if (KEY) state = 0;                       // 按键已释放,转换到按键初始态
        break;
    }
    return key_return;
}   
u8 key_read(void)  
{  
    static u8 key_m=key_state_0, key_time_1=0;  
    u8 key_return=0,key_temp;  
      
    key_temp=key_driver();  
      
    switch(key_m)  
    {  
        case key_state_0:  
            if(key_temp==S_key)  
            {  
                 key_time_1=0;               // 第1次单击,不返回,到下个状态判断后面是否出现双击  
                 key_m=key_state_1;  
            }  
            else  
                 key_return=key_temp;        // 对于无键、长键,返回原事件  
            break;  
            case key_state_1:  
            if(key_temp==S_key)             // 又一次单击(间隔肯定<500ms)  
            {  
                 key_return=D_key;          // 返回双击键事件,回初始状态  
                 key_m=key_state_0;  
            }  
            else                                 
            {                                // 这里500ms内肯定读到的都是无键事件,因为长键>1000ms,在1s前低层返回的都是无键  
                 if(++key_time_1>=50)  
                 {  
                      key_return=S_key;      // 500ms内没有再次出现单键事件,返回上一次的单键事件  
                      key_m=key_state_0;     // 返回初始状态  
                 }  
             }  
             break;  
    }
    return key_return;  
}      

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:815094 发表于 2020-8-29 17:12 | 显示全部楼层
学到了 谢谢贴主
回复

使用道具 举报

ID:291265 发表于 2020-9-15 20:40 | 显示全部楼层
++time >= 100  这个时间,好像不能固定使用100  如果是1秒  ....函数多了,100估计就等于N秒..
如果有  10个按键扫描函数  ,这个时间好像就会变长(长按按键)
回复

使用道具 举报

ID:890367 发表于 2022-8-19 14:37 | 显示全部楼层
你好楼主,key.h这里面是什么???
回复

使用道具 举报

ID:1040201 发表于 2022-9-2 15:48 | 显示全部楼层
我还需要细细咀嚼一下。非常感谢
回复

使用道具 举报

ID:165291 发表于 2022-12-3 21:59 | 显示全部楼层
没做完整程序吗?看不懂啊!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表