当前位置:网站首页>基于STM32F103ZET6库函数按键输入实验
基于STM32F103ZET6库函数按键输入实验
2022-06-27 16:55:00 【是北豼不太皮吖】
基于STM32F103ZET6库函数按键输入实验
我们将通过 ALIENTEK 精英 STM32F103 上载有的 3 个按钮(KEY_UP、KEY0 和 KEY1),来控制板上的 2 个 LED(DS0和 DS1)和蜂鸣器。
其中 KEY_UP 控制蜂鸣器,按 一次叫,再按一次停;
KEY1 控制 PB5,按一次亮,再按一次灭;
KEY0 则同时控制 PB5 和 PE5, 按一次,他们的状态就翻转一次。
GPIO_ReadInputDataBit函数
STM32F1 的 IO 口做输入使用的时候,是通过调用函数 GPIO_ReadInputDataBit()来读取 IO 口的状态
硬件设计
KEY0 和 KEY1 是低电平有效的,而 KEY_UP 是高电平有效的,并且 外部都没有上下拉电阻,所以,需要在 STM32F1 内部设置上下拉。
上拉无按键输入时是1,有按键输入时是0
下拉无按键输入时是0,有按键输入时是1
软件设计
key.c
#include "stm32f10x.h"
#include "key.h"
#include "sys.h"
#include "delay.h"
//按键初始化函数
//IO 初始化
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOE,ENABLE); //使能 GPIOA,GPIOE 时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4; //KEY0-KEY1-->GPIOE.3,4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //PE3,4 设置成上拉输入
GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化 GPIOE.3,4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //WK_UP-->GPIOA.0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 设置成下拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.0
}
key.c
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,KEY0 按下
//2,KEY1 按下
//3,KEY3 按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY_UP!!
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1; //按键按松开标志
if(mode)
{
key_up=1; //支持连按
}
/*支持连按,而且按键有响应优先级*/
if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
{
delay_ms(10); //去抖动
key_up=0;
if(KEY0==0)
{
return KEY0_PRES;
}
else if(KEY1==0)
{
return KEY1_PRES;
}
else if(WK_UP==1)
{
return WKUP_PRES;
}
}
else if(KEY0==1&&KEY1==1&&WK_UP==0)
{
key_up=1;
}
return 0; // 无按键按下
}
知识点:
1.当 mode 为 0 的时候,KEY_Scan()函数将不支持连续按,扫描某个按键,该按键按下之后 必须要松开,才能第二次触发,否则不会再响应这个按键,这样的好处就是可以防止按一次多 次触发,而坏处就是在需要长按的时候比较不合适。
当 mode 为 1 的时候,KEY_Scan()函数将支持连续按,如果某个按键一直按下,则会一直 返回这个按键的键值,这样可以方便的实现长按检测。
2.因为该函数里面有 static 变量,所以该函数不是一个可重入函数
3.该函数的按键扫描是有优先级的,最优先的是 KEY0, 第二优先的是 KEY1,最后是 WK_UP 按键。
4.该函数有返回值,如果有按键按下,则返回非 0 值,如果没有或者按键不正确,则返回 0。
key.h
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) //读取按键0
#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) //读取按键1
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) //读取按键3(WK_UP)
#define KEY0_PRES 1 //KEY0按下
#define KEY1_PRES 2 //KEY1按下
#define WKUP_PRES 3 //KEY_UP按下(即WK_UP/KEY_UP)
void KEY_Init(void); //IO初始化
u8 KEY_Scan(u8); //按键扫描函数
#endif
知识点:
1.宏定义,采取的是库函数的读取 IO 口的值。
2.也同样可以通过位带操作来简单的实现
#define KEY0 PEin(4) //PE4
#define KEY1 PEin(3) //PE3
#define WK_UP PAin(0) //PA0 WK_UP
用库函数实现的好处是在各个 STM32 芯片上面的移植性非常好,不需要修改任何代码。 用位带操作的好处是简洁
3.定义了 KEY0_PRES/KEY1_PRES /WKUP_PRES 等 3 个宏定义,分别 对应开发板(KEY0/KEY1/WKUP)按键按下时 KEY_Scan()返回的值。
beep.c
#include "beep.h"
//初始化PB8为输出口,并使能这个口的时钟
//蜂鸣器初始化
void BEEP_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //BEEP-->PB.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据参数初始化GPIOB.8
GPIO_ResetBits(GPIOB,GPIO_Pin_8); //输出0,关闭蜂鸣器输出
}
beep.h
#ifndef __BEEP_H
#define __BEEP_H
#include "sys.h"
//蜂鸣器端口定义
#define BEEP PBout(8) // BEEP,蜂鸣器接口
void BEEP_Init(void); //初始化
#endif
main.c
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "beep.h"
int main(void)
{
vu8 key=0;
delay_init(); //延时函数初始化
LED_Init(); //初始化与LED连接的硬件接口
BEEP_Init(); //初始化蜂鸣器端口
KEY_Init(); //初始化与按键连接的硬件接口
LED0=0; //先点亮红灯
while(1)
{
key=KEY_Scan(0); //得到键值
if(key)
{
switch(key)
{
case WKUP_PRES: //控制蜂鸣器
BEEP=!BEEP;
break;
case KEY1_PRES: //控制LED1翻转
LED1=!LED1;
break;
case KEY0_PRES: //同时控制LED0,LED1翻转
LED0=!LED0;
LED1=!LED1;
break;
}
}
else
{
delay_ms(10);
}
}
}
边栏推荐
- Comprehensively analyze the zero knowledge proof: resolve the expansion problem and redefine "privacy security"
- [elt.zip] openharmony paper Club - witness file compression system erofs
- Cucumber自动化测试框架使用
- 工作流自动化 低代码是关键
- 别焦虑了,这才是中国各行业的工资真相
- 实施MES管理系统前,要对哪些问题进行评估
- PostgreSQL database Wal - resource manager rmgr
- Keras deep learning practice (12) -- facial feature point detection
- Market status and development prospect forecast of global 3-Chloro-1,2-Propanediol industry in 2022
- Explain in detail the differences between opentsdb and tdengine in system functions
猜你喜欢

VS code 运行yarn run dev 报yarn : 无法加载文件XXX的问题

推荐几个开源的物联网平台

Mise à jour SQL mise à jour par lots

2022年信创行业空间测算

Comprehensively analyze the zero knowledge proof: resolve the expansion problem and redefine "privacy security"

Hi,你有一份Code Review攻略待查收!

阿里巴巴的使命、愿景、核心价值观

原创 | 2025实现“5个1”奋斗目标!解放动力全系自主非道路国四产品正式发布

PostgreSQL database Wal - resource manager rmgr

深度学习和神经网络的介绍
随机推荐
VS code 运行yarn run dev 报yarn : 无法加载文件XXX的问题
使用logrotate对宝塔的网站日志进行自动切割
[cloud based co creation] the "solution" of Digital Travel construction in Colleges and Universities
Market status and development prospect forecast of the global infusion needle less connector industry in 2022
Gartner聚焦中国低代码发展 UniPro如何践行“差异化”
如何实现IM即时通讯“消息”列表卡顿优化
通过 G1 GC Log 重新认识 G1 垃圾回收器
全面解析零知识证明:消解扩容难题 重新定义「隐私安全」
CDGA|交通行业做好数字化转型的核心是什么?
Stored procedures of PostgreSQL
PostgreSQL之存储过程篇
Rxjs mergeMap 的使用场合
Contest3182 - the 39th individual training match for 2021 freshmen_ E: ringring
Win10 LTSC 2021 wsappx CPU usage high
Market status and development prospect forecast of phenethyl resorcinol for skin care industry in the world in 2022
脉脉热帖:为啥大厂都热衷于造轮子?
银河麒麟V10系统激活
New Zhongda chongci scientific and Technological Innovation Board: annual revenue of 284million and proposed fund-raising of 557million
Market status and development prospect forecast of global aircraft hose industry in 2022
xctf攻防世界 MISC薪手进阶区