状态机的设计思想与单片机按键检测的实现方式

本文介绍了状态机的概念,以小区停车系统为例进行说明,并探讨了状态机在嵌入式编程、游戏开发和服务端开发中的应用。接着,文章重点阐述了如何使用状态机的思想来实现单片机按键扫描,提出了定时中断和while循环检测两种方式,并给出了代码示例,最后讨论了多按键同时按下的检测方法。
摘要由CSDN通过智能技术生成

一. 什么是状态机

我们以生活中的小区的停车系统为例:停车杆一般没车的是不动的(初态),有车来的时候需要抬杆(状态1),车通过需要放杆(状态2),如果在放杆的过程中突然有车,又需要抬杆(状态3)。。。就是说我们需要将不同的情况划分为不同的状态,每个状态对应相应的操作。

这只是状态机的一个很简单的举例。如果单个状态也是一个状态机的话,那么就会形成状态机套状态机,有点类似于C++里的父类和子类。其实在我们日常的程序设计中,处处都有状态机的影子,不管是我们嵌入式编程,游戏开发,服务端开发等等都要用到。

网上关于状态机的介绍很多,如果有想详细了解的可以去找找相关资料。

二. 用状态机的思想实现按键扫描

按键有按下和松开的状态,还有长按和短按的状态,以及单个按键和组合按键的状态等等。我们来看看如何用状态机的思想实现它,这里会有两种处理方式,第一种是利用一个定时器中断,每隔ms扫描一次;第二种是直接在while(1)循环里检测是否有按键按下。处理的思路都差不多,下面看看实现的代码。

/**********************************key.c*********************************/
//读取按键对应的管脚电平
static u16 GetKey(keysTypedef_t *keyS)
{
    uint8_t i = 0; 
    uint16_t readKey = 0;              
    
    //GPIO Cyclic scan
    for(i = 0; i < keys.keyTotolNum; i++)
    {
        if(!HAL_GPIO_ReadPin((GPIO_TypeDef*)keyS->singleKey[i].keyPort,keyS->singleKey[i].keyGpio))
        {
            G_SET_BIT(readKey, keyS->singleKey[i].keyNum); //读取到按键电平,设置对应的按键返回值为1
        }
    }
    
    return readKey;
}

// 判断按键是否按键按下,是长按还是短按
uint16_t readKeyValue(keysTypedef_t *keyS)
{
    static uint8_t keyCheck = 0;    //当前按键的值
    static uint8_t keyState = 0;
    stati
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值