本章节资料下载链接:
我用夸克网盘分享了「第7章 独立按键扫描」,点击链接即可保存。打开「夸克APP」,无需下载在线播放视频,畅享原画5倍速,支持电视投屏。
链接:https://pan.quark.cn/s/c2182510a54e
第 七 章
1、独立按键
1.1 按键介绍
按键是一种电子开关,使用时轻轻按开关按钮就可使开关接通,当松开手时, 开关断开。按键内部简易图如下图所示:

按键管脚两端距离长的表示默认是导通状态,距离短的默认是断开状态, 如果按键按下,初始导通状态变为断开,初始断开状态变为导通。通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,电压信号如下图所示。

由于机械点的弹性作用,按键开关在闭合时不会马上稳定的接通,在断开时也不会一下子断开,因而在闭合和断开的瞬间均伴随着一连串的抖动。一般在代码需要添加消抖操作保证按键识别正确。
单片机常用的软件去抖动方法:
1,先设置 IO 口为高电平,外部上拉10K或者设置上拉输出模式。
2,读取 IO 口电平确认是否有按键按下。
3,如有 IO 电平为低电平后,延时几个毫秒。
4,再读取该 IO 电平,如果仍然为低电平,说明按键按下。
5,执行按键控制程序。
独立按键电路构成是由各个按键的一个管脚连接在一起接地,按键其他引脚分别接到单片机 IO 口。
1.2 硬件设计
PA0和PA1接到LED灯,按键外接上拉电阻分别接到PA12-PA15,分别取别名为KEY4-KEY1。LED灯控制脚设置为推挽输出,按键控制脚设置为上拉输入。4 个独立按键的控制管脚连接到单片机的PA12-PA15脚上且接外部上拉电阻。其中 K1 连接在PA15上,K2 连接在PA14上,K3 连接在PA13上,K4 连接在PA14上。4 个按键另一端全部连接在 GND,当按键按下后,对应 IO 口即为低电平。

1.3 工程代码配置
复制第9章工程文件,修改为Jsmcu_P02_KEY,添加key.c和key.h到工程路径下Public下,新增方法如9.3所示,此处不在赘述。
按键配置为上拉输入,分别自定义KEY1-KEY4,LED灯配置为推挽输出,分别自定义名称为LED0和LED1。点击生成代码。


打开工程文件,key.c代码:
#include "key.h"
#include "system.h"
/*******************************************************************************
* 函 数 名 : KEY_Scan
* 函数功能 : 按键扫描检测
* 输 入 : mode=0:单次按下按键
mode=1:连续按下按键
* 输 出 : 0:未有按键按下
KEY1_PRESS:KEY1键按下
KEY2_PRESS:KEY2键按下
KEY3_PRESS:KEY3键按下
KEY4_PRESS:KEY4键按下
*******************************************************************************/
u8 KEY_Scan(u8 mode)
{
static u8 key=1;
if(mode==1) //连续按键按下
key=1;
if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0)) //任意一个按键按下
{
HAL_Delay(10); //消抖
key=0;
if(KEY1==0)
return KEY1_PRESS;
else if(KEY2==0)
return KEY2_PRESS;
else if(KEY3==0)
return KEY3_PRESS;
else if(KEY4==0)
return KEY4_PRESS;
}
else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1) //无按键按下
key=1;
return 0;
}
key.h代码:
#ifndef _key_H
#define _key_H
#include "system.h"
//使用位操作定义
#define KEY1 PAin(15)
#define KEY2 PAin(14)
#define KEY3 PAin(13)
#define KEY4 PAin(12)
#define LED1 PAout(0)
#define LED2 PAout(1)
//定义各个按键值
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
u8 KEY_Scan(u8 mode);
#endif
main.c添加代码段
USER CODE BEGIN Includes和USER CODE END Includes之间添加:
/* USER CODE BEGIN Includes */
#include "System.h"
#include "key.h"
/* USER CODE END Includes */
while函数部分修改为:
/* USER CODE BEGIN Includes */
#include "System.h"
#include "key.h"
/* USER CODE END Includes */
while函数部分修改为:
/* USER CODE BEGIN WHILE */
u8 key=0;
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
key=KEY_Scan(0); //扫描按键
switch(key)
{
case KEY1_PRESS: LED1=0;break; //点亮D1指示灯
case KEY2_PRESS: LED1=1;break; //熄灭D1指示灯
case KEY3_PRESS: LED2=0;break; //点亮D2指示灯
case KEY4_PRESS: LED2=1;break; //熄灭D2指示灯
}
}
/* USER CODE END 3 */
}
实验现象:KEY4控制LED1熄灭,KEY3控制LED1点亮
KEY2控制LED0熄灭,KEY1控制LED0点亮
