STM32 Cubemax(十二) ——利用状态机实现按键的长短按和双击

发布者:ZenMaster123最新更新时间:2022-08-24 来源: csdn关键字:STM32  状态机  按键 手机看文章 扫描二维码
随时随地手机看文章

前言

状态机是一种根据当前状态来执行相应动作,根据输入去改变状态的方法,出处应该在数字电路中。


我们利用状态机的思想来实现按键的消抖和一些其他功能的实现


一、状态图

在这里插入图片描述

我们的按键实验,就是以此状态图为基础,然后做延申,实现长短按和双击。


二、Cubemax配置

1、IO口配置

这个配置很简单,看自己的板子上按键的IO口是哪个,我这里以KEY0做演示

在这里插入图片描述

配置PH3为输出IO,而且由电路图可知,应该设置为上拉。

在这里插入图片描述

2、定时器配置

我们需要配置一个10ms的定时器,以10ms去检测按键的状态

在这里插入图片描述
在这里插入图片描述

三、代码

1、编写有关按键的结构体和定义相关参数

#define IOSTATE HAL_GPIO_ReadPin(GPIOH, GPIO_PIN_3) //读取PH3的IO信息


typedef struct

{

uint8_t flag; //双击标志

uint8_t mode; //按键模式,0为短按,1为长按,2为双击

uint8_t press_state; //表示按键按下时,IO口为高电平还是低电平

}Key;


2、结构体初始化


void Key_Init()

{

key.mode = 2;

key.press_state = 0;

key.flag = 0;

HAL_TIM_Base_Start_IT(&htim2);

}


3、状态机编写

我这里用一个变量a去观察结果


//此函数在定时器中每10ms调用一次

void Key_Check()

{

static uint8_t state = 0, key_time = 0, twice_time = 0;

if(key.flag == 1)

{

twice_time++;

if(twice_time == 100) //双击的间隔时间

{

twice_time = 0;

key.flag = 0;

}

}

switch(state)

{

case 0:

if(IOSTATE == key.press_state) state = 1;

break;

case 1:

if(IOSTATE == key.press_state)

{

if(key.mode == 0) a++; //单击模式

else if(key.mode == 2) //双击模式

{

key.flag++;

if(key.flag == 2)

{

a++;

key.flag = 0;

twice_time = 0;

}

}

state = 2;

}

else state = 0;

break;

case 2:

if(IOSTATE != key.press_state)

{

state = 0;

key_time = 0;

}

else if(key.mode == 1) //长按模式

{

key_time++;

if(key_time == 50) //长按时间

{

a++;

}

}

break;

}

}


4、10ms定时器中反复检测按键状态

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

if(htim->Instance == htim2.Instance)

{

Key_Check();

}

}


总结

状态机的思想,适用于状态多变的场所,不仅是按键中。

关键字:STM32  状态机  按键 引用地址:STM32 Cubemax(十二) ——利用状态机实现按键的长短按和双击

上一篇:STM32 Cubemax(十三) ——SPI时序读写RFID-RC522
下一篇:STM32 Cubemax(十一) ——JY901陀螺仪数据的读取与简单数据处理

推荐阅读最新更新时间:2024-11-12 10:55

stm32 mmc卡扫描指定文件夹下的所有文件 串口输出(文件名长度有限制)
硬件环境:神州一号开发板 软件环境:mdk 1、sd卡初始化 2、f_mount 3、扫描函数如下: #define _USE_LFN 0 FRESULT scan_files (char* path) { FRESULT res; FILINFO fno; DIR dir; int i; char *fn; #if _USE_LFN static char lfn ; fno.lfname = lfn; fno.lfsize = sizeof(lfn); #endif res = f_opendir(&dir, path); if (res == FR_OK) { i = strl
[单片机]
实体按键消亡背后,是一段人机交互的发展史
    为什么这块屏幕按了没反应?   不到10岁的小女儿拿着Game Boy Color(GBC)问Chris Cohoon,GBC是1998年任天堂出品的彩屏掌上游戏机,著名的《精灵宝可梦:金/银》就是GBC上的游戏。   尽管GBC是一代经典,但对10后来说,游戏机没有触屏是件匪夷所思的事情。从小玩iPhone、iPad长大的她,对GBC屏幕下方的按键熟视无睹。   Chris Cohoon把这段视频传到了YouTube上,不到一周时间就吸引了超过260万次的点击。有网友在视频下面评论道: 现在的小孩连按键是什么都不知道了,这世界到底怎么了?   事实上,这只是半个世纪以来计算机交互形式变迁的一个缩影,也是一段实体按键
[手机便携]
STM32 USB SD卡读卡器和NAND FLASH模拟U盘
本次工程是要同时实现SD卡读卡器和NAND Flash模拟U盘的功能。结合之前的两个工程,稍稍修改下就可以了。 既然要实现两个盘,当然在usb_prop.c中的Max_Lun变量赋值为1,在USB_User组中同时添加fsmc_nand.c和sdio_sdcard.c这两个文件,在外设库中挺尸添加stm32f10x_sdio.c和stm32f10x_fsmc.c两个文件。 添加完之后,可能会有些许的错误,解决完后,我们就要修改下mass_mal.c文件了,这个文件本次要同时实现SD卡和NAND Flash的相关驱动代码的挂接,代码如下: uint32_t Mass_Memory_Size ; uint32_t Mass_Block
[单片机]
<font color='red'>STM32</font> USB SD卡读卡器和NAND FLASH模拟U盘
STM32入门笔记1
STM32入门笔记:STM32+ST-Link ST-link仿真器跟一块最小系统的STM32开发板都买回来好久了,到最近终于有空开始动手学习。 --|||在ST-Link配的光盘里有个J-Link的介绍文档跟驱动程序,结果我就看完把驱动一装,连上开发板按着教程开始想烧录个程序进去试试。结果一直无法识别到J-Link设备…我居然还上旺旺找买仿真器的那个卖家问为什么我发现不了设备,我的仿真器上面的灯不亮?卖家问了下情况后很纳闷:你买的是ST-Link当然用J-Link的驱动程序连接不到设备啦…当时自己也被自己这个乌龙给雷到了。 好吧,又接着问了一下,原来ST-Link不用装驱动,但是用ST-Link无法像使用J-Link
[单片机]
STM32 GPIO操作流程
GPIO初始化步骤 1、打开GPIO外设时钟. 设置RCC- APB2ENR RCC- APB2ENR|=1 2;//使能PORTA时钟 2、设置端口模式和速度. GPIOA- CRH(8-15位) 或者GPIOA- CRL(0-7位) 端口模式: 模拟输入模式/ 浮空输入模式/ 上拉/下拉输入模式/ 通用推挽输出模式/ 通用开漏输出模式/ 复用功能推挽输出模式/ 复用功能开漏输出模式 速度: 2M 5M 10M 3、设置端口输入GPIOA- IDR/输出GPIOA- ODR GPIOA- ODR|=1 8; //PA8 输出高
[单片机]
Ubuntu下安装Stm32的Eclipse的开发环境(1)
在最起初的时候,我刚刚接触linux上单片机的开发,最喜欢的就是 eclipse + arm-plug-in + arm-none-eabi 的开发环境,因为这是在Linux上最接近于windows下keil、IAR等IDE的开发方式,然而那是由于对eclipse亦或是makefile等编译过程中的工具的不甚了解,很多时候会遇到一些莫名的错误,也导致了那是觉得这样的环境很鬼畜,现在看来多是一些很浅显的问题,直到最近我再一次的尝试了eclipse开发环境的搭建和使用,我才很顺利的完成了程序的配置。现在也把这个方法推荐给大家,不过在使用这个方式前,还是建议大家先把之前的文章内容看懂了,否则很多时候遇到问题都会不知道怎么解决。 安装
[单片机]
STM32 普通IO口 模拟串口
这两天一直在调试用普通IO口来承担串口的角色,再次做个笔记。当然广泛参考广大网友的代码在此感谢网友 首先串口的最最最基本的数据格式是由10位数据组成,注意是最最最基本的当然要有些带各种校验的那些暂时不考虑毕竟要先会走才能飞嘛,首先,第一位开始位,其次是八个数据位,然后一个停止位,数据位的时间长度由你的波特率决定的,我模拟的串口最实现了115200波特率当然偶尔有错位,这个就是接下来校验的工作了。 个人定义的数据格式 首先是发送部分,发送相对来说比较简单,直接就是基本的延时由于,stm32有比较方便的滴答定时器所以做出的延时还是相当精准的。 发送代码如下: SendingDelay 需要延时的时间长度由波特率决定 void IO
[单片机]
<font color='red'>STM32</font> 普通IO口 模拟串口
解决Stm32开发板每次下程序必须重新上电问题
Stm32的启动模式由 BOOT0和BOOT1进行配置,在下载模式下我们需要讲BOOT0配置成0电平,但往往忽略了BOOT1。 一般开发板厂家都会把BOOT0和BOOT0都做成可配置的。 我遇到的问题就是在下载程序的时候只在BOOT0上接了跳线帽讲其接地,但是BOOT1确由其悬空着,因此每次下载都必须重新上电才能被下载器认可,后来将BOOT1用跳线帽接到高电平后,问题成功解决,每次下载前只需要按下复位按键就可以了。
[单片机]
解决<font color='red'>Stm32</font>开发板每次下程序必须重新上电问题
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved