STM32标准库_02 | 从按键开始认识状态机编程
本篇文章主要介绍如何利用状态机来编写按键检测实验,希望能给人以收获。
1.开发环境
软件环境
使用MDK5.25版本,芯片包为STM32F4系列。
硬件环境
开发板:一块多按键的开发板,本实验采用有三个按键的stm32F407VGT6开发板,是一款大容量芯片,最高能跑168MHz,比F103的72M快了一倍多。
烧录器:STlink或者Jlink。
2.工程创建
和STM32标准库_01 | 搭建自己的程序框架,思路是一样的,具体可以看我的截图,从正点原子的资料中拷贝相关源文件。
因为我的开发板用的是25M的外部晶振,所以要修改两个地方,达到利用外部晶振倍频到168M作为系统时钟。
1.修改的地方之一:stm32f4xx.h里面的HSE_VALUE,系统默认采用外部8M晶振,所 以 #define HSE_VALUE ((uint32_t)8000000) ,现把它修改 为 #define HSE_VALUE ((uint32_t)25000000)
2.修改的地方之二:系统通过PLL倍频到168M,所以在配置PLL的时候,也需要作相应的修改。在system_stm32f4xx.c里,需要 把PLL_M修改为25,不然会超频使STM32不能正常工作,常见表现为掉进HardFault_Handler()中。
滴答定时器的初始化是和F103一样的,但是GPIO的初始化有些区别,F407挂载到高速时钟总线AHB1上,翻转速度最高能够达到100M,意味着可以更高速的进行一些协议的通信,还有就是把设置IO的输出输出模式和上下拉模式分离了出来,多了GPIO_OType和GPIO_PuPd需要配置。
测试一下
3.代码编写
1.状态机编程思想
其实很多项目里面多多少少都有状态机的影子,状态机又称有限状态机,任何事物只要拥有有限个状态,就能使用状态机的方式实现代码。例如门有两种状态,即开和关,还例如我们今天要写的按键轮询检测实验中,按键的状态可以分为四种,按键弹起的状态、按键按下抖动状态、按键按下状态和按键弹起抖动状态。
2.按键基础代码编写
下面我们来编写代码,首先是按键的GPIO初始化,因为我们检测的是低电平,所以设置为上拉输入。
编写引脚电平获取函数。
关于按键编号,是声明在头文件的枚举
除了按键编号与按键状态的枚举外,还有一个键值的枚举,让我们保留按键是按下,长按还是松开等等。
声明了这些枚举后,我们得用实体去接收啊,如果是C++,就是创建对象了,当然了,C语言没有对象,所以我们创建一个结构体去接收。
3.按键轮询状态机代码编写
先定义触发长按的时间为1s。
开始编写三个按键一起轮询的按键检测函数,利用状态机编程。
在按键弹起状态时,如果检测到引脚为低电平,则跳转到按键按键抖动状态。
在按键按键抖动状态里,如果检测到引脚为按下时的低电平,则跳转到按键按下状态,否则则返回按键弹起状态。
在按键按下状态里,会执行长按计数,如果小于触发长按的时间里,按键松开了,则进入按键弹起抖动状态,并且保留(按键按下的键值);如果达到触发长按的时间,就会保存(按键长按的键值,并赋值长按状态,就能一直去等待按键松开),如果按键松开就跳转到按键弹起抖动状态。
在按键弹起抖动状态下,检测按键是不是按键弹起状态,如果是则跳转到按键弹起状态。异常状态时按键切回按键弹起状态。
4.按键轮询状态机测试
1.测试流程
按键1按下,把LED1,2,3点亮;按键2按下,把LED1,2,3熄灭;按键3长按,翻转LED1,2,3。
2.代码烧录
3.实验现象
代码已全部上传到gitee,希望各位小伙伴们在下载的同时不忘点击Star,地址:https://gitee.com/Notmi/stm32-standard-peripheral-libraries。