欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32学习笔记之按键输入实验

程序员文章站 2022-07-12 10:19:08
...

借助正点原子F103战舰V3开发板进行学习,采用库函数编程。
参考资料:正点原子教学视频,《STM32F1开发指南-库函数版本_V3.3》

**硬件连接:**KEY0连接到PE4,KEY1连接到PE3,KEY2连接到PE2,另一端接地,KEY_UP连接到PA0,另一端接高电平。
所以PE2、PE3、PE4低电平时表示按键按下,PA0高电平时表示WK_UP按下。
STM32学习笔记之按键输入实验
与前两个实验不同,LED和蜂鸣器实验均是GPIO输出,按键实验是输入,需要用库函数GPIO_ReadInputDataBit()读取GPIO口电平。
在key.h中定义好读取到的电平标志,按键按下标志并创建一个按键初始化函数和按键扫描函数,完整代码如下:

/**********  key.h **********/

#ifndef __KEY_H
#define __KEY_H
#include "sys.h"

#define KEY0 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4)       //电平标志
#define KEY1 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3)
#define KEY2 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2)
#define WK_UP GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)

#define KEY0_PRES   1		//KEY0按下
#define KEY1_PRES   2		//KEY1按下
#define KEY2_PRES	3		//KEY2按下
#define KEY_UP_PRES 4	    //KEY_UP按下(即WK_UP/KEY_UP)

void KEY_Init(void);	    //按键初始化函数
u8 KEY_Scan(u8);			//按键扫描函数

#endif

在key.c中写好前面定义好的按键初始化函数和按键扫描函数,GPIO初始化与LED实验和蜂鸣器实验有些不同,KEY0,KEY1,KEY2接地采用上拉输入,WK_UP接高电平采用下拉输入。按键初始化函数如下:

void KEY_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;		//KEY0,KEY1,KEY2一端接的地,需上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_3 | GPIO_Pin_2;	//初始化GPIOE2,3,4
	GPIO_Init(GPIOE, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;		//KEY_UP一端接的高电平,需下拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//初始化GPIOA0
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

按键扫描有两种模式,一种是支持连按、一种不支持连按,设置一个输入参数mode,mode=1时表示支持连按,mode=0时表示不支持连按;同时需要延时去抖,定义一个按键松开标志key_up,key_up=1时表示按键松开,按键扫描函数如下:

u8 KEY_Scan(u8 mode)		
{
	static u8 key_up = 1;		// 按键松开标志
	if(mode)
		key_up = 1;
	if(key_up&&(KEY0==0 || KEY1==0 || KEY2==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(KEY2==0)
			return KEY2_PRES;
		else if(WK_UP==1)
			return KEY_UP_PRES;
	}
	
	else if(KEY0==1 || KEY1==1 || KEY2==1 || WK_UP==0)		//按键松开
		key_up = 1;
	return 0;
}

用KEY0控制LED0翻转,KEY1控制LED1翻转,KEY2控制LED0和LED1同时翻转,用WK_UP控制LED0和LED1同时亮起并使蜂鸣器响起,主函数代码如下:

int main(void)
{
	vu8 key = 0;
	LED_Init();
	delay_init();
	BEEP_Init();
	KEY_Init();
	
	while(1)
	{
		key = KEY_Scan(0);	// 得到不支持连按的键值
		if(key)
		{
			switch(key)
			{
			case KEY0_PRES:		
				LED0 = !LED0;		//控制LED0翻转
			break;
			case KEY1_PRES:
				LED1 = !LED1;		//控制LED1翻转
			break;
			case KEY2_PRES:		
				LED0 = !LED0;
				LED1 = !LED1;		//控制LED0和LED1同时翻转
			break;
			case KEY_UP_PRES:
				BEEP = !BEEP;
				LED0 = 0;
				LED1 = 0;				//控制LED0和LED1亮起起蜂鸣器响起
			}
		}
		else delay_ms(10);
	}
}

编译无误后,用ST-Link将程序下载到开发板中,实验效果如预期。