基于stm32F7单片机的按键程序详解(两种方案)

于小鱼的第一篇文章-----stm32f7(HAL库)按键操作

开发板: stm32F7核心板
开发平台: keilMDK5

文章内容:通过KEY0,KEY1,KEY2,WK_UP四个按键来控制两个LED灯的熄灭,将会从两种方案进行剖析:①按键后就触发相对应按键的功能。②按键后松开后才触发相应按键的功能。

所用原理图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码初始化讲解:

LED灯我们只用LED0和LED1,由于在不受控制的时候是接的上拉电阻,触发方式为PB1 和 PB1送低电平点亮LED,所以在初始化端口的时候不要浮空,设置一个推挽输出上拉电阻是最合适不过了。这里两IO口设置为推挽输出模式,LED初始化代码如下:
void Led_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE(); //使能时钟
__HAL_RCC_GPIOB_CLK_ENABLE(); //使能时钟

/*Configure GPIO pins : PB0 PB1 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1; //PB0和PB1
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出模式
GPIO_InitStruct.Pull = GPIO_PULLUP; //设置上拉电阻
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //高速模式
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); //IO口初始化

/*Configure GPIO pin Output Level */

//这一句就是IO口输出模式电平选择了,GPIO_PIN_SET 为高电平, GPIO_PIN_RESET为低电平。这里初始化用的高电平输出,LED灯熄灭。
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_SET);
}

在这里,我要说一个重要的事情,并且我要说三遍:
在调用端口的时候,
一定要记得使能对应端口时钟!!!
一定要记得使能对应端口时钟!!!
一定要记得使能对应端口时钟!!!

按键我们用了四个,分别是KEY0 KEY1 KEY2 WK_UP
通过原理图我们可以看出KEY0 KEY1 KEY2接的是地,那么在键按下的话,IO口会接到低电平以至触发开关,所以在初始化的时候一定要上拉它所对应的IO口,并设为输入模式,而只有WK_UP外接的是上拉电阻,所以在初始化的时候一定要下拉它所对应的IO口。初始化代码如下:
void Key_Init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();

/*Configure GPIO pin : PH2 PH3  KEY0 KEY1*/
GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;   //上拉
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
/*Configure GPIO pin: PC13  KEY2*/
GPIO_InitStruct.Pin = GPIO_PIN_13;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/Configure GPIO pin : PA0 WK_UP/
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN; //下拉
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

按键代码:
①按键后就触发相对应按键的功能
当在要写稍微要动一点脑子的代码时候,需要头脑绝对清醒,确实想不出来,就别再想,也许在某一刻放松的时候想到这件事情,突然灵感就迸发了出来。

建立松开标志位是关键,先看代码:
int Key_Scan(void)
{
static u8 a = 1; //松开标志
if(a && ((Key0_Check == 0) || (Key1_Check == 0) || (Key2_Check == 0) || (WK_UP == 1)))
{
a = 0;
if(Key0_Check == 0) return Key0_ON;
else if(Key1_Check == 0) return Key1_ON;
else if(Key2_Check == 0) return Key2_ON;
else if(WK_UP == 1) return WK_UP_ON;
}
else if((Key0_Check == 1) && (Key1_Check == 1) && (Key2_Check == 1) && (WK_UP == 0))
{
a = 1;
}
return 0;
}
松开标志只能用静态变量,因为是局部函数,为了不提前释放变量值,定义了静态变量。

代码已经提供,可以直接复制使用,

②按键松开后触发,在上面的基础上在设立一个标志位
代码如下:

int Key_Scan(void)
{ static u8 flag = 0;
static u8 a = 1; //松开标志
if(a && ((Key0_Check == 0) || (Key1_Check == 0) || (Key2_Check == 0) || (WK_UP == 1)))
{
a = 0;
if(Key0_Check == 0) flag = 1;
else if(Key1_Check == 0) flag = 2;
else if(Key2_Check == 0) flag = 3;
else if(WK_UP == 1) flag = 4;
}
else if((Key0_Check == 1) && (Key1_Check == 1) && (Key2_Check == 1) && (WK_UP == 0))
{
a = 1;
}

/*松开触发*/
if(flag == 1 && Key0_Check == 1)
{
	flag = 0;
	return Key0_ON;
}
else if(flag == 2 && Key1_Check == 1)
{
	flag = 0;
	return Key1_ON;
}
else if(flag == 3 && Key2_Check == 1)
{
	flag = 0;
	return Key2_ON;
}
else if(flag == 4 && WK_UP == 0)
{
	flag = 0;
	return WK_UP_ON;
}
return 0;

}

主函数内容:
#include “stm32f7xx_hal.h”
#include “uart.h”
#include “systemclock.h”
#include “led.h”
#include “yu.h”
#include “iwdg.h”
#include “key.h”

int main(void)
{
u8 len = 0;
u16 times=0;
HAL_Init();
SystemClock_Config();

Led_Init();
Key_Init();


while(1)
{

		len = Key_Scan();
		if(len == Key0_ON) 				{LED0_ON;LED1_OFF;}
		else if(len == Key1_ON)		    {LED0_OFF;LED1_ON;}
		else if(len == Key2_ON)         {LED0_ON;LED1_ON;}
		else if(len == WK_UP_ON)     {LED0_OFF;LED1_OFF;}
}

对第二种按键进行一次详解:
做程序就一定要用微观的思想去想,由于触发之间都是在微秒的时间段发生的。

进入主循环连续扫描按键,就KEY0触发为例子,当按键按下的时候,Key0_Check == 0 判断为真,进入条件语句,flag = 1,a = 0。在这里如果长期按着不松,将不会进入任何条件语句。当一松开,Key0_Check == 1判断为真的时候 a = 1,并且执行:
if(flag == 1 && Key0_Check == 1)
{
flag = 0;
return Key0_ON;
}
里面的语句,重复上面动作,就可以实现松开触发按键。

宏定义目录:
#define LED0_ON HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET)
#define LED1_ON HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET)
#define LED0_OFF HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET)
#define LED1_OFF HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET)
#define LED0(n) (n?HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET))
#define LED0_Toggle (HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1))
#define LED1(n) (n?HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET))
#define LED1_Toggle (HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0))
#define Key0_Check HAL_GPIO_ReadPin(GPIOH, GPIO_PIN_2)
#define Key1_Check HAL_GPIO_ReadPin(GPIOH, GPIO_PIN_3)
#define Key2_Check HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)
#define WK_UP HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)
#define Key0_ON 1 //KEY0按下
#define Key1_ON 2 //KEY1按下
#define Key2_ON 3 //KEY2按下
#define WK_UP_ON 4 //WK_UP按下

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于STM32F7xx单片机按键控制LED灯亮灭的代码: 首先,需要在CubeMX中配置GPIO引脚。我们将LED连接到PA5引脚,按键连接到PA0引脚。在“Pinout & Configuration”选项卡中,将PA5设置为GPIO输出模式,将PA0设置为GPIO输入模式。然后,生成代码并打开工程。 在main.c文件中,我们需要在GPIO初始化函数中初始化PA0和PA5引脚: ``` void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin : PA0 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pin : PA5 */ GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` 然后,我们需要在main函数中编写代码来检测按键的状态并控制LED灯的亮灭。以下是完整的main函数代码: ``` int main(void) { /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); /* Infinite loop */ while (1) { /* Check if button is pressed */ if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) { /* Turn on LED */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); } else { /* Turn off LED */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); } } } ``` 在无限循环中,我们检测PA0引脚的状态。如果按键被按下,PA0引脚将被拉低,我们将PA5引脚设置为高电平以点亮LED。否则,我们将PA5引脚设置为低电平以关闭LED。 最后,我们需要编译和下载代码到STM32F7xx单片机中。启动单片机后,按下按键可以看到LED灯亮起,松开按键可以看到LED灯熄灭。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值