STM32 使用外部中断实现按键模块化

举报
yd_274589494 发表于 2023/07/27 17:39:18 2023/07/27
【摘要】 @TOC 前言前一篇按键模块的文章我们封装了按键的功能函数等,现在为什么又需要改进呢?因为在前面我们使用的是延时函数进行的消抖,延时函数在项目开发中最好就是少使用。延时函数的大量使用会造成系统的卡顿,所以这里我们使用外部中断改进按键的代码。外部中断的介绍:外部中断按键模块化:按键模块化下面我们直接上代码,原理部分请大家看之前的文章。 一、代码部分driver_key.h#ifndef __D...

@TOC


前言

前一篇按键模块的文章我们封装了按键的功能函数等,现在为什么又需要改进呢?因为在前面我们使用的是延时函数进行的消抖,延时函数在项目开发中最好就是少使用。延时函数的大量使用会造成系统的卡顿,所以这里我们使用外部中断改进按键的代码。
外部中断的介绍:外部中断
按键模块化:按键模块化
下面我们直接上代码,原理部分请大家看之前的文章。

一、代码部分

driver_key.h

#ifndef __DRIVER_KEY_H
#define __DRIVER_KEY_H

#include "main.h"

#define Key1_Pin 										GPIO_PIN_4
#define Key1_GPIO_Port 							GPIOE
#define Key2_Pin 										GPIO_PIN_3
#define Key2_GPIO_Port 							GPIOE
#define KEY1_GPIO_CLK_EN()          __HAL_RCC_GPIOE_CLK_ENABLE()
#define KEY2_GPIO_CLK_EN()          __HAL_RCC_GPIOE_CLK_ENABLE()

#define Key1()      HAL_GPIO_ReadPin(Key1_GPIO_Port, Key1_Pin)
#define Key2()      HAL_GPIO_ReadPin(Key2_GPIO_Port, Key2_Pin)

uint8_t Getkey1val(void);
uint8_t Getkey2val(void);

void key_init(void);

#endif

driver_key.c
这里我们把按键设置为了外部中断,而且是双边沿触发,当按键按下或者松开时都会触发外部中断,在外部中断中我们进行按键值的读取,并编写一个函数返回按键值,供应用程序调用。

#include "driver_key.h"

uint8_t key1_val = 0;
uint8_t key2_val = 0;

void key_init(void)
{
    // 定义GPIO的结构体变量
	GPIO_InitTypeDef GPIO_InitStruct = {0};

	// 使能按键的GPIO对应的时钟
	KEY1_GPIO_CLK_EN();
	KEY2_GPIO_CLK_EN();

	GPIO_InitStruct.Pin = Key1_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;  // 设置为双边沿触发外部中断
	GPIO_InitStruct.Pull = GPIO_PULLUP;                 // 默认上拉
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;       // 引脚反转速度设置为快

	// 初始化引脚配置
	HAL_GPIO_Init(Key1_GPIO_Port, &GPIO_InitStruct);


	GPIO_InitStruct.Pin = Key2_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;  // 设置为双边沿触发外部中断
	GPIO_InitStruct.Pull = GPIO_PULLUP;                 // 默认上拉
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;       // 引脚反转速度设置为快

	// 初始化引脚配置
	HAL_GPIO_Init(Key2_GPIO_Port, &GPIO_InitStruct);
	
	
	HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);// 设置外部中断优先级
	HAL_NVIC_EnableIRQ(EXTI3_IRQn);// 使能外部中断
	
	HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);// 设置外部中断优先级
	HAL_NVIC_EnableIRQ(EXTI4_IRQn);// 使能外部中断
}

//外部中断3中断处理函数
void EXTI3_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(Key2_Pin);
}

//外部中断4中断处理函数
void EXTI4_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(Key1_Pin);
}

//外部中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == Key1_Pin)
	{
		key1_val = Key1();
	}
	else if(GPIO_Pin == Key2_Pin)
	{
		key2_val = Key2();
	}
	
}

//返回key1按键值
uint8_t Getkey1val(void)
{
	return key1_val;
}

//返回key2按键值
uint8_t Getkey2val(void)
{
	return key2_val;
}

maic.c

if(Getkey1val() == 0)
{
	LED0(ON);
}
else if(Getkey1val() == 1)
{
	LED0(OFF);
}

总结

使用外部可以减少延时函数的使用,而且还能使得按键更加灵敏。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。