这里用到的是正点原子开发板
![在这里插入图片描述](https://img-blog.csdnimg.cn/80ea5bb435d345609f37f8321f336983.png)
可以看到键盘通过PE2、PE3、PE4、PA0来连接。如果你的开发板不是这个需要改到对应的接口啊。
另外可以看到WK_UP是高电平有效的,并且外部没有上下拉电阻,需要stm32内部设置上下拉。
首先写key.h文件,这里有两种方法库函数或者C51一样直接对io口进行操作。对比两中方法可以更好理解。
1、直接操作型
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY0 PEin(4)
#define KEY1 PEin(3)
#define KEY2 PEin(2)
#define KEY3 PAin(0)
#define KEY_UP 4
#define KEY_LEFT 3
#define KEY_DOWN 2
#define KEY_RIGHT 1
void KEY_Init(void);
u8 KEY_Scan(u8);
#endif
2、运用库函数型
#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 KEY3 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#define KEY_UP 4
#define KEY_LEFT 3
#define KEY_DOWN 2
#define KEY_RIGHT 1
void KEY_Init(void);
u8 KEY_Scan(u8);
#endif
其中#define KEY_UP 4//KEY_UP
是运用宏定义,当输入KEY_UP,会被当做4。
写key.c文件,同样包括2钟
1、直接操作型
#include "key.h"
#include "delay.h"
void KEY_Init(void)
{
RCC->APB2ENR|=1<<2;
RCC->APB2ENR|=1<<6;
GPIOA->CRL&=0XFFFFFFF0;
GPIOA->CRL|=0X00000008;
GPIOE->CRL&=0XFFF000FF;
GPIOE->CRL|=0X00088800;
GPIOE->ODR|=7<<2;
}
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;
if(mode)key_up=1;
if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3==1))
{
delay_ms(10);
key_up=0;
if(KEY0==0)return 1;
else if(KEY1==0)return 2;
else if(KEY2==0)return 3;
else if(KEY3==1)return 4;
}else if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==0)key_up=1;
return 0;
}
1、调用库函数型
#include "stm32f10x.h"
#include "key.h"
#include "sys.h"
#include "delay.h"
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOE,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;
if(mode)key_up=1;
if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3==1))
{
delay_ms(10);
key_up=0;
if(KEY0==0) return KEY_RIGHT;
else if (KEY1==0)return KEY_DOWN;
else if (KEY2==0)return KEY_LEFT;
else if (KEY3==1) return KEY_UP;
}
else if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==0)key_up=1;
return 0;
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/3f921a6ea33b4712913ccaabd4765adb.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6bih5rGk5p2l5Za9fg==,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/7b69a61667a7412c8b468fd1d82fa7ad.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6bih5rGk5p2l5Za9fg==,size_20,color_FFFFFF,t_70,g_se,x_16)
因为代码到这里会乱码,打汉字太麻烦,所以就是图片了。
其中
static u8 key_up=1;
static是修饰静态变量,可以避免每次调用函数重新赋值。
if(mode)key_up=1;
这里对应主函数的调用KEY_Scan(1);
你可以输入0/1
最后是主函数main.c
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "beep.h"
#include "key.h"
int main(void)
{
u8 t;
delay_init();
LED_Init();
BEEP_Init();
LED0=0;
while(1)
{
t=KEY_Scan(1);
if(t)
{
switch(t)
{
case KEY_UP: BEEP=£¡BEEP;
break;
case KEY_LEFT: LED0=!LED0;
break;
case KEY_DOWN: LED1=!LED1;
break;
case KEY_RIGHT: LED0=!LED0; LED1=!LED1;
break;
}
}else delay_ms(300);
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/a446af92787c4105a7e0d866662ef77b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6bih5rGk5p2l5Za9fg==,size_20,color_FFFFFF,t_70,g_se,x_16)
最后需要注意的是,库函数和直接写对应配套的h文件不同。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)