【STM32学习笔记】按键输入

本文详细介绍了STM32F1单片机中使用GPIO进行按键输入的硬件原理、软件操作方法,包括GPIO配置、库函数调用、寄存器操作和位带操作。还提供了程序设计步骤,如时钟使能、IO口模式初始化和按键扫描功能实现。
摘要由CSDN通过智能技术生成

目录

硬件原理

软件原理

读取GPIO输入电平的方法

1.调用库函数

2.直接操作寄存器

3.位带操作

程序设计原理

1.使能对应IO口时钟

2.初始化IO口模式

3.扫描IO口电平

代码

1.Key.h

2.Key.c

3.main.c


硬件原理

        注意:KEY0 和 KEY1 是低电平有效的,而 KEY_UP 是高电平有效的,并且外部都没有上下拉电阻,所以,需要在 STM32F1 内部设置上下拉

        对于KEY0和KEY1,其连接为共阴接法,故IO口默认读取为高电平,故程序需设计为上拉输入模式;而对于KEY_UP,其连接为共阳接法,故IO口默认读取为低电平,故程序需设计为下拉输入模式

软件原理

读取GPIO输入电平的方法

1.调用库函数

        GPIO_ReadInputDataBit();

2.直接操作寄存器

        GPIOx_IDR:端口输入寄存器

3.位带操作

        PEin(n)        读取GPIOE.n口的电平

程序设计原理

1.使能对应IO口时钟

        RCC_APB2PeriphClockCmd();

2.初始化IO口模式

        GPIO_Init();        需初始化为上拉/下拉输入模式

3.扫描IO口电平

        详见读取GPIO输入电平的方法代码部分

代码

1.Key.h

#ifndef _Key_H_
#define _Key_H_

#include "sys.h" //为了引用PEin(n),PAin(n)

/* 库函数 */
#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)//读取按键 WK_UP

/* 位操作 */
//#define KEY0 PEin(4) //PE4
//#define KEY1 PEin(3) //PE3 
//#define WK_UP PAin(0) //PA0 WK_UP

#define KEY0_PRES 1 //KEY0 按下
#define KEY1_PRES 2 //KEY1 按下
#define WKUP_PRES 3 //WK_UP 按下

void Key_Init(void);
u8 Key_Scan(u8 Mode);

#endif

2.Key.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Key.h"

/**
  * @brief  按键初始化函数
  * @param  无
  * @retval 无
  */
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;//选择GPIOE端口
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
	GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化 GPIOE3,GPIOE4
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //选择GPIOA端口
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 设置成输入,下拉 
	GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.0
}

/**
  * @brief  按键扫描函数
  * @param  Mode 按键支持的模式,0为不支持连按,1为支持连按
  * @retval 0 没有按键按下
  * @retval 1 KEY0_PRES Key0按下
  * @retval 2 KEY1_PRES Key1按下
  * @retval 3 WKUP_PRES WakeUp按下
  */
u8 Key_Scan(u8 Mode)
{
	static u8 Key_ForeState = 1; //记录按键上一次按下的状况,0为按下,1为松手
	
	if(Mode == 1){Key_ForeState = 1;} //支持连按
	
	if(Key_ForeState && (KEY0==0||KEY1==0||WK_UP==1))
	{
		delay_ms(10); //消抖
		Key_ForeState = 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_ForeState = 1;
	}
	
	return 0;
}

3.main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Beep.h"
#include "Key.h"

u8 KeyNum; //存放返回键值

int main(void)
{
	delay_init();
	LED_Init();
	Beep_Init();
	Key_Init();
	
	LED0 = 0; //先点亮红灯
	while(1)
	{
		KeyNum = Key_Scan(0); //得到返回键值(不支持连按)
		
		if(KeyNum)
		{
			switch(KeyNum)
			{
				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); //不让其立即重新读键值
	}
}

此时main.c还需用到LED和蜂鸣器的代码,为了控制篇幅,相关代码详见 LED相关 蜂鸣器相关

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值