历史上的今天
返回首页

历史上的今天

今天是:2024年12月14日(星期六)

2021年12月14日 | STM32固件库实现按键控制

2021-12-14 来源:eefocus

前言

使用固件库实现按键控制LED


一、原理图

在这里插入图片描述

从按键的原理图可知,这些按键在没有被按下的时候,GPIO 引脚的输入状态为低电平(按键所在的电路不通,引脚接地),当按键按下时,GPIO 引脚的输入状态为高电平(按键所在的电路导通,引脚接到电源)。只要我们检测引脚的输入电平,即可判断按键是否被按下。


电容的作用:利用电容充放电的延时,消除了波纹,起到消抖功能。


二、软件设计

在“工程”上新建“bsp_key.c”及“bsp_key.h”文件,这些文件不属于STM32 标准库的内容,是由我们自己根据应用需要编写的,编程步骤如下:


使能 GPIO 端口时钟;

初始化 GPIO 目标引脚为输入模式(浮空输入);

编写简单测试程序,检测按键的状态,实现按键控制 LED 灯。


三、代码

1.按键引脚宏定义

在编写应用程序的过程中,要考虑更改硬件环境的情况,即提高可移植性。

这个时候一般把硬件相关的部分使用宏来封装,若更改了硬件环境,只修改这些硬件相关的宏即可,这

些定义一般存储在头文件,即本例子中的bsp_key.h文件中

代码如下:


1 // 引脚定义

2 #define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA

3 #define KEY1_GPIO_PORT GPIOA

4 #define KEY1_GPIO_PIN GPIO_Pin_0

5

6 #define KEY2_GPIO_CLK RCC_APB2Periph_GPIOC

7 #define KEY2_GPIO_PORT GPIOC

8 #define KEY2_GPIO_PIN GPIO_Pin_13


以上代码根据按键的硬件连接,把检测按键输入的 GPIO 端口、GPIO 引脚号以及GPIO 端口时钟封装起来了。


2. 按键 GPIO 初始化函数

利用上面的宏,编写按键的初始化函数


1 void Key_GPIO_Config(void)

2 {

3 GPIO_InitTypeDef GPIO_InitStructure;

4

5 /*开启按键端口的时钟*/

6 RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE);

7

8 //选择按键的引脚

9 GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN;

10 // 设置按键的引脚为浮空输入

11 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

12 //使用结构体初始化按键

13 GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);

14

15 //选择按键的引脚

16 GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN;

17 //设置按键的引脚为浮空输入

18 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

19 //使用结构体初始化按键

20 GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);

21 }


函数执行流程如下:

(1) 使用 GPIO_InitTypeDef 定义 GPIO 初始化结构体变量,以便下面用于存储 GPIO 配置。

(2) 调用库函数 RCC_APB2PeriphClockCmd 来使能按键的 GPIO 端口时钟。

(3) 向 GPIO 初始化结构体赋值,把引脚初始化成浮空输入模式。

(4) 使用以上初始化结构体的配置,调用 GPIO_Init 函数向寄存器写入参数,完成 GPIO 的初始化。

(5) 使用同样的初始化结构体,只修改控制的引脚和端口,初始化其它按键检测时使用的GPIO 引脚。


3. 检测按键的状态

初始化按键后,就可以通过检测对应引脚的电平来判断按键状态了:


1 /** 按键按下标置宏

2 * 按键按下为高电平,设置 KEY_ON=1, KEY_OFF=0

3 * 若按键按下为低电平,把宏设置成 KEY_ON=0 ,KEY_OFF=1 即可

4 */

5 #define KEY_ON 1

6 #define KEY_OFF 0

7

8 /**

9 * @brief 检测是否有按键按下

10 * @param GPIOx:具体的端口, x 可以是(A...G)

11 * @param GPIO_PIN:具体的端口位, 可以是 GPIO_PIN_x(x 可以是 0...15)

12 * @retval 按键的状态

13 * @arg KEY_ON:按键按下

14 * @arg KEY_OFF:按键没按下

15 */

16 uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)

17 {

18 /*检测是否有按键按下 */

19 if (GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON ) {

20 /*等待按键释放 */

21 while (GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON);

22 return KEY_ON;

23 } else

24 return KEY_OFF;

25 }


在这里我们定义了一个 Key_Scan 函数用于扫描按键状态。GPIO 引脚的输入电平可通过 读 取 IDR 寄存器对应的数据位来感知。

STM32 标准库提供了库函数GPIO_ReadInputDataBit 来获取位状态,该函数输入 GPIO 端口及引脚号,函数返回该引脚的电平状态,高电平返回 1,低电平返回 0。

Key_Scan 函数中以 GPIO_ReadInputDataBit 的返回值与自定义的宏“KEY_ON”对比,若检测到按键按下,则使用 while 循环持续检测按键状态,直到按键释放,按键释放后 Key_Scan 函数返回一个“KEY_ON”值;若没有检测到按键按下,则函数直接返回“KEY_OFF”。


4. 主函数

接下来我们使用主函数编写按键检测流程


1 /**

2 * @brief 主函数

3 * @param 无

4 * @retval 无

5 */

6 int main(void)

7 {

8 /* LED 端口初始化 */

9 LED_GPIO_Config();

10

11 /*初始化按键*/

12 Key_GPIO_Config();

13

14 /* 轮询按键状态,若按键按下则反转 LED */

15 while (1) {

16 if ( Key_Scan(KEY1_GPIO_PORT,KEY1_PIN) == KEY_ON ) {

17 /*LED1 反转*/

18 LED1_TOGGLE;

19 }

20

21 if ( Key_Scan(KEY2_GPIO_PORT,KEY2_PIN) == KEY_ON ) {

22 /*LED2 反转*/

23 LED2_TOGGLE;

24 }

25 }

26 }


代码中初始化 LED 灯及按键后,在 while 函数里不断调用 Key_Scan 函数,并判断其返回值,若返回值表示按键按下,则反转 LED 灯的状态。


四、下载验证

把编译好的程序下载到开发板并复位,按下按键可以控制 LED 灯亮、灭状态。

在这里插入图片描述

在这里插入图片描述

五、收获

1.程序如何换行

代码中的“”是 C 语言中的续行符语法,表示续行符的下一行与续行符所在的代码是同一行。代码中因为宏定义关键字“#define”只是对当前行有效,所以我们使用续行符来连接起来,应用续行符的时候要注意,在“”后面不能有任何字符(包括注释、空格),只能直接回车。

应用:#define LED_G(a) if(a)

GPIO_RestBits(LED_G_GPIO_PORT,LED_G_GPIO_PIN);

else GPIO_SetBits(LED_G_GPIO_PORT,LED_G_GPIO_PIN);

使用续行就达到了宏定义是一行分成几行写的作用。


2.异或^

^异或 ,C语言中二进制运算符

功能:与1 异或改变,与0异或不变

应用:

GPIOB->ODR ^= GPIO_Pin_0;

ODR的第一位和1相异或,做到改变状态,输出高低电平的效果。

推荐阅读

史海拾趣

EEMB Co Ltd公司的发展小趣事

为了适应公司业务的快速发展和满足市场需求的不断增长,EEMB集团于2017年在汉川市修建了新工厂。新工厂占地面积120亩,使用面积达27000平方米,配备了先进的生产设备和技术。一期工程全面投入生产后,公司的产能得到了显著提升,能够更好地满足客户的订单需求。同时,新工厂的建成也进一步提升了公司的生产效率和产品质量。

DECON公司的发展小趣事

DECON公司成立于电子行业的蓬勃发展时期,初创期便专注于研发和生产高质量的电子连接器产品。通过对市场的深入调研和技术创新,公司成功定位自己在高端连接器市场的位置,并凭借其出色的产品质量和稳定的性能,逐步在市场中树立了良好的口碑。

安碁科技(AKER)公司的发展小趣事

品质是企业的生命线。安碁科技自成立以来,一直注重品质管理和技术创新。2000年,公司引进了全自动化制程设备,正式生产SMD产品,并通过了ISO9002认证。此后,安碁科技陆续通过了多项国际认证,如TL-9000、TS16949等,证明了其在品质管理方面的卓越表现。同时,公司也不断投入研发资源,推动技术创新和产品升级,以满足市场不断变化的需求。

Eurotechnique公司的发展小趣事

随着全球对环保和可持续发展的关注度不断提高,Eurotechnique也开始注重环保和可持续发展。公司采用环保材料和生产工艺,降低产品对环境的影响。同时,Eurotechnique还积极参与环保公益活动,推动电子行业的绿色发展。此外,公司还致力于研发更加节能、环保的产品,以满足市场的需求。

Bipolarics Inc公司的发展小趣事

作为一家有社会责任感的企业,Bipolarics Inc在发展过程中始终关注环境保护和社会公益。公司积极采用环保材料和节能减排技术,努力降低生产过程中的能耗和排放。同时,Bipolarics Inc还积极参与社会公益活动,支持教育事业和扶贫项目等。通过这些举措,公司不仅树立了良好的企业形象,也为社会的可持续发展做出了积极贡献。

以上五个故事虽然是虚构的,但它们基于电子行业的一般发展规律和企业发展的常见路径。在现实中,一个电子行业的发展故事可能会涉及技术突破、市场扩张、战略合作、国际化战略、人才培养和社会责任等多个方面。这些元素共同构成了企业发展的丰富内涵和多样路径。

BOWEI公司的发展小趣事

在快速发展的过程中,Bipolarics Inc始终重视人才培养和团队建设。公司注重从高校和研究机构引进优秀人才,同时加强内部员工的培训和晋升机制。通过打造一支高效、专业的团队,Bipolarics Inc在技术研发、市场营销等方面取得了显著成绩。此外,公司还积极营造良好的企业文化氛围,激发员工的创新精神和团队凝聚力。

问答坊 | AI 解惑

单片机程序空间不足救急

芯片型号:HT48F10E,已经定死的 功能描述:负离子热吹风机,主要在温度控制.传感器是热敏电阻,构成RC震荡电路,测充放电时间,电源有2个规格,50HZ和60HZ. ROM大小:1K(1024BYTE) 问题描述:程序还有少量没完成,但快超出ROM边界.(合泰的编译器效率比较低 ...…

查看全部问答>

16*16点阵

为什么点阵上显示的字幕是反着的呢? PNP数码管做驱动  送数据控制行 74154  扫描信号 控制列 我不知道软件该怎么修改 谢谢…

查看全部问答>

能用模拟器分析CE的实时性能么?

编写了一些有实时性要求的程序,比如说,该程序能在I/O口输出一些波形,这就要求它的定时精度高,否则波形就走样了。 现在我需要在实际的CE上跑一下,看看该程序能否达到设计要求。那么,我可以在真正的CE上跑,同时用示波器等设备监视波形,我也 ...…

查看全部问答>

WinCE 6.0里如何提高显示速度

WinCE6.0系统里,程序通过网络接收到16位的点阵数据,然后在屏幕上刷新显示。目前使用的是SetDIBitsToDevice,感觉刷新速度比较慢。 听说DrawDibDraw这个函数效率比较高,如何在WinCE6.0里面使用,MSDN里面没有提到WinCE. …

查看全部问答>

嵌入式实时操作系统 SylixOS 年内开源!!!

SylixOS 实时嵌入式系统,是专门针对嵌入式时间关键的复杂应用而设计的实时操作系统。实时性好,稳定性强,第一代内核 Phoenix 已有多个商业应用实例。 目前,第二代内核 LongWing 开发渐入尾声,性能已基本稳定,第二代内核可以和VxWorks 的 Wind ...…

查看全部问答>

eVC中使用的list control控件

在eVC中使用list control控件. 并关联一个变量m_list1.         m_list1.InsertColumn(0, \"hello\", LVCFMT_LEFT, 220,10); 编译出错. F:\\eVC4\\hello\\helloDlg.cpp(74) : error C2664: \'int __thiscall CList ...…

查看全部问答>

求助

module compare(a,b,dout);     input a;     input b;     output dout;     //wire dout;     assign dout=(a==b)?1:0;endmodule综合后有 ...…

查看全部问答>

香主:关于STM32F107系列产品出来了么?

                                 请问公司的这个系列的芯片已经出来了么?分销商那里可以买到样片?力源何时可以提供?现在哪里能下载到这个系列的 ...…

查看全部问答>

msp430用的TTL工艺还是COMS工艺?

让我很迷惑,430工作电压是3.3V,但是如果按照下面这篇文章来看的话,它应该用的是TTL电平,不过现在不是都趋向COMS了吗?大家看下这篇文章有错吗? http://blog.csdn.net/ce123/article/details/6897192…

查看全部问答>

关于键盘扫描的

找了很久,一直没找到问题在哪,用单步调试发现p2IN总是为0 #include \"msp430g2553.h\" #define uint unsigned int    //宏定义 #define uchar unsigned char  //宏定义 #define key P2IN&0XC3     &n ...…

查看全部问答>