当前位置: 首页 > news >正文

STM32_07_按键

按键介绍


硬件设计

  • KEY_UP:
    3.3V --- KEY_UP --- PA0 | CPU  
    KEY0:
    GND  --- KEY0   --- PE4 | CPU 
    KEY1:
    GND  --- KEY1   --- PE3 | CPU 
    KEY2:
    GND  --- KEY2   --- PE2 | CPU 
  • 默认:断开状态        按下:导通状态
  • 按下按键,完成某种功能
  • 如何检测某个按键按下?
    KEY_UP: 配置为下拉输入即可(接的是3.3V电源,因此按键按下默认高电平)
    按键松开 - PA0 - 低电平 
    按键按下 - PA0 - 高电平 
    按键松开 - PA0 - 低电平 
    循环检测, 只要检测到高电平, 认为KEY_UP按下

    KEY_0: 配置为上拉输入(接地,PE4->低电平,因此按键按下默认低电平)
    按键松开 - PE4 - 高电平
    按键按下 - PE4 - 低电平 
    按键松开 - PE4 - 高电平 
    后续只要检测到PE4低电平, 认为KEY0按下 

实战演练-掌控需求

软件实现

代码示例:

key.h:

// key.h
#ifndef __KEY_H__
#define __KEY_H__#include "stm32f10x.h"
#include "system.h"// 位带操作// KEY0 - PE4
#define KEY0_PIN   GPIO_Pin_4
#define KEY0_PORT  GPIOE
#define KEY0			 PEin(4) // 判断GPIOE4引脚的高低电平
#define KEY0_PRESS 1	// key0的键值extern void KEY_Init(void);
//
// 扫描是否有按键扫描
//
extern u8   KEY_Scan(void);
#endif

key.c:

// key.c
#include "key.h"
#include "systick.h" // 定时器
//
// 初始化函数
// GPIOE4:上拉输入(高电平 - 低电平 - 高电平)
//
void KEY_Init(void){// 1.打开GPIOE控制器的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);// 2.配置GPIOE4为上拉输入// 当我们把引脚配置成输入时,不用配置速率,寄存器里面是没有速率的GPIO_InitTypeDef GPIO_Config;GPIO_Config.GPIO_Pin = GPIO_Pin_4;GPIO_Config.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入GPIO_Init(KEY0_PORT, &GPIO_Config);}
//
// 扫描是否有按键按下 - 循环调用
// 如果按键按下,返回按键键值
// KEY0 - 1
// 否则返回0
//
u8   KEY_Scan(void){// key0 - 已经按下 - 不能再按了// = 0,没有按键被按下,可以按键了;=1, 按键已经被按下了,不能再按了static u8 ispressed = 0;if((ispressed == 0) && (KEY0 == 0)){delay_ms(10); // 加了这句代码就不会接触不良了// 如果if中的两个条件满足,此次确实按下了KEY0按键ispressed = 1;if(KEY0 == 0)// 如果是多个按键,你就不知道是哪个按键按下了,因此这里还要判断一次return KEY0_PRESS; // 返回KEY0键值}else if(KEY0 == 1){ // 没有按键按下ispressed = 0; // 标识这个按键松开了}return 0; // 没有按键按下
}

main.c:

// main.c 
#include "stm32f10x.h"
#include "led.h"
#include "beep.h"
#include "system.h"
#include "systick.h"
#include "key.h"int main(void)
{// LED初始化 LED_Init();// BEEP初始化 BEEP_Init();// systick初始化 Systick_Init();// KEY初始化KEY_Init();// 定义变量获取扫描按键的返回值u8 key_value;while(1){key_value = KEY_Scan();switch(key_value){case KEY0_PRESS : LED0 = !LED0; break;}}
}

实验现象

按键抖动

delay_ms(10);

软件去抖

代码示例:

key.h

// key.h
#ifndef __KEY_H__
#define __KEY_H__#include "stm32f10x.h"
#include "system.h"// 位带操作// KEY0 - PE4
#define KEY0_PIN   GPIO_Pin_4
#define KEY0_PORT  GPIOE
#define KEY0			 PEin(4) // 判断GPIOE4引脚的高低电平
#define KEY0_PRESS 1	// key0的键值// KEY_UP - PA0 (低电平 - 高电平 - 低电平)
#define  KEY_UP_PIN GPIO_Pin_0
#define KEY_UP_PORT GPIOA
#define KEY_UP			PAin(0) // 判断PA0引脚的高低电平
#define KEY_UP_PRESS 2	// key0的键值// KEY1 - PE3
#define KEY1_PIN   GPIO_Pin_3
#define KEY1_PORT  GPIOE
#define KEY1			 PEin(3) // 判断GPIOE4引脚的高低电平
#define KEY1_PRESS 3	// key0的键值// KEY2 - PE2
#define KEY2_PIN   GPIO_Pin_2
#define KEY2_PORT  GPIOE
#define KEY2			 PEin(2) // 判断GPIOE4引脚的高低电平
#define KEY2_PRESS 4	// key0的键值extern void KEY_Init(void);
//
// 扫描是否有按键扫描
//
extern u8   KEY_Scan(void);
#endif

key.c:

// key.c
#include "key.h"
#include "systick.h" // 定时器
//
// 初始化函数
// GPIOE4:上拉输入(高电平 - 低电平 - 高电平)
// GPIOA0:下拉输入(低电平 - 高电平 - 低电平)
//
void KEY_Init(void){// 1.打开GPIOE控制器的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);// 1.2打开GPIOA控制器的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 2.配置GPIOE4为上拉输入// 当我们把引脚配置成输入时,不用配置速率,寄存器里面是没有速率的GPIO_InitTypeDef GPIO_Config;GPIO_Config.GPIO_Pin = GPIO_Pin_4;GPIO_Config.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入GPIO_Init(KEY0_PORT, &GPIO_Config);	// 2.2配置GPIOA0为下拉输入GPIO_Config.GPIO_Pin = GPIO_Pin_0;GPIO_Config.GPIO_Mode = GPIO_Mode_IPD; // 下拉输入GPIO_Init(KEY_UP_PORT, &GPIO_Config);// 2.3配置GPIOE3为上拉输入GPIO_Config.GPIO_Pin = GPIO_Pin_3;GPIO_Config.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入GPIO_Init(KEY1_PORT, &GPIO_Config);	}
//
// 扫描是否有按键按下 - 循环调用
// 如果按键按下,返回按键键值
// KEY0 - 1
// KEY_UP - 2
// KEY1 - 3
// 否则返回0
//
u8   KEY_Scan(void){// key0 - 已经按下 - 不能再按了// = 0,没有按键被按下,可以按键了;=1, 按键已经被按下了,不能再按了static u8 ispressed = 0;if((ispressed == 0) && ((KEY0 == 0) || (KEY_UP == 1) || (KEY1 == 0) || (KEY2 == 0))){delay_ms(10); // 加了这句代码就不会接触不良了// 如果if中的两个条件满足,此次确实按下了KEY0按键ispressed = 1;if(KEY0 == 0)// 如果是多个按键,你就不知道是哪个按键按下了,因此这里还要判断一次return KEY0_PRESS; // 返回KEY0键值else if(KEY_UP == 1)return KEY_UP_PRESS; // 返回KEY_UP键值else if(KEY1 == 0)return KEY1_PRESS;else if(KEY2 == 0)return KEY2_PRESS;}else if((KEY0 == 1) && (KEY_UP == 0) && (KEY1 == 1) && (KEY2 == 1)){ // 没有按键按下ispressed = 0; // 标识这个按键松开了}return 0; // 没有按键按下
}

main.c:

// main.c 
#include "stm32f10x.h"
#include "led.h"
#include "beep.h"
#include "system.h"
#include "systick.h"
#include "key.h"int main(void)
{// LED初始化 LED_Init();// BEEP初始化 BEEP_Init();// systick初始化 Systick_Init();// KEY初始化KEY_Init();// 定义变量获取扫描按键的返回值u8 key_value;while(1){key_value = KEY_Scan();switch(key_value){case KEY0_PRESS : LED0 = !LED0; break;case KEY_UP_PRESS : BEEP = !BEEP; break;case KEY1_PRESS : LED1 = 0; break;case KEY2_PRESS : LED1 = 1; break;}}
}

http://www.dtcms.com/a/394347.html

相关文章:

  • 基于迁移学习和SqueezeNet的滚动轴承故障诊断(MATLAB)
  • 实战项目(十二:《AI画质增强与LED驱动控制:一场关于‘创造’与‘还原’的对话》):从LED冬奥会、奥运会及春晚等大屏,到手机小屏,快来挖一挖里面都有什么
  • 开发避坑指南(52):IDEA 2025.1.3 顶部显示类完整路径的设置方法
  • 安装Qt新之后出现两本帮助手册
  • Rust_2025:阶段1:day7.2unsafe , 链接相关
  • 【论文速递】2025年第15周(Apr-06-12)(Robotics/Embodied AI/LLM)
  • 设计模式简单说明:责任链与规则树
  • 自动备份脚本 mysql_hourly_backup.sh
  • SuperGLUE:自然语言理解的挑战与进步
  • 线程安全的单例模式、自旋锁,以及读者写者问题
  • U盘长期插在电脑上的影响
  • Windows 系统部署 PaddleOCR —— 基于 EPGF 架构
  • 数据一致性指的是什么?如何实现数据一致性?
  • 初识消息队列的世界
  • Python快速入门专业版(三十八):Python字典:键值对结构的增删改查与进阶用法
  • SpringCloudOAuth2+JWT:微服务统⼀认证方案
  • LeetCode 分类刷题:2517. 礼盒的最大甜蜜度
  • 深度学习优化器进阶:从SGD到AdamW,不同优化器的适用场景
  • C++ 之 【C++的IO流】
  • truffle学习笔记
  • 现代循环神经网络
  • vlc播放NV12原始视频数据
  • ThinkPHP8学习篇(七):数据库(三)
  • 链家租房数据爬虫与可视化项目 Python Scrapy+Django+Vue 租房数据分析可视化 机器学习 预测算法 聚类算法✅
  • MQTT协议知识点总结
  • C++ 类和对象·其一
  • TypeScript里的类型声明文件
  • 【LeetCode - 每日1题】设计电影租借系统
  • Java进阶教程,全面剖析Java多线程编程,线程安全,笔记12
  • DCC-GARCH模型与代码实现