stm32---按键
2019-04-27 本文已影响0人
飞向深空
key.c
#include "key.h"
#include "SysTick.h"
/**********************************************************************
* 函 数 名 : KEY_Init
* 函数功能 : 按键初始化
* 输 入 : 无
* 输 出 : 无
************************************************************************/
void KEY_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //GPIO初始化要配置的结构体定义
RCC_APB2PeriphClockCmd(KEY_PORT_RCC,ENABLE); //开启APB2总线的时钟
GPIO_InitStructure.GPIO_Pin = KEY_UP_PIN; //选择要操作的引脚
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //工作频率,可以可无,按键是输入输出才要配置速率
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉模式,默认是低电平,这个按键结论个3.3V所以配置下拉才能检测出按下
GPIO_Init(KEY_UP_PORT,&GPIO_InitStructure); //初始化端口
GPIO_InitStructure.GPIO_Pin = KEY_DOWN_PIN|KEY_LEFT_PIN|KEY_RIGHT_PIN; //选择要操作的引脚
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //工作频率,可以可无,按键是输入输出才要配置速率
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //下拉模式,默认是低电平,这个按键结论个3.3V所以配置下拉才能检测出按下
GPIO_Init(KEY_PORT,&GPIO_InitStructure); //初始化端口
}
/*******************************************************************************
* 函 数 名 : KEY_Scan
* 函数功能 : 按键扫描检测
* 输 入 : mode=0:单次按下按键
mode=1:连续按下按键
* 输 出 : 0:未有按键按下
KEY_UP:K_UP键按下
KEY_DOWN:K_DOWN键按下
KEY_LEFT:K_LEFT键按下
KEY_RIGHT:K_RIGHT键按下
*********************************************************************************/
u8 KEY_Scan(u8 mode)
{
static u8 key=1;
if(key==1&&(K_UP==1||K_DOWN==0||K_LEFT==0||K_RIGHT==0)) //任意一个按键按下
{
delay_ms(10); //消抖
key = 0;
//按键内容部分
if(K_UP==1)
{
return KEY_UP;
}
else if(K_DOWN==0)
{
return KEY_DOWN;
}
else if(K_LEFT==0)
{
return KEY_LEFT;
}
else
{
return KEY_RIGHT;
}
//按键内容部分
}
else if(K_UP==0&&K_DOWN==1&&K_LEFT==1&&K_RIGHT==1) //没有一个按键按下
{
key=1;
}
if(mode==1) //连续按键按下
{
key=1;
}
return 0;
}
/*
mode=0是普通模式 ,mode=1是连续模式
当任意按键按下,key=1,消抖后变0。普通模式下,只有在松开按键时key=1,下一次按键内容部分按才能实现。
连续模式下,下面判断mode==1,每次判断完key=1,实现按键内容部分一直运行
*/
key.h
#ifndef _key_h
#define _key_h
#include "system.h"
//按键所用时钟定义
#define KEY_PORT_RCC RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE //按键要的开启的时钟
//按键所在引脚定义
#define KEY_UP_PIN GPIO_Pin_0
#define KEY_DOWN_PIN GPIO_Pin_3
#define KEY_LEFT_PIN GPIO_Pin_2
#define KEY_RIGHT_PIN GPIO_Pin_4
//按键所在端口定义
#define KEY_PORT GPIOE
#define KEY_UP_PORT GPIOA
//使用位操作定义
#define K_UP PAin(0)
#define K_DOWN PEin(3)
#define K_LEFT PEin(2)
#define K_RIGHT PEin(4)
//使用读取管脚状态库函数定义
//#define K_UP GPIO_ReadInputDataBit(KEY_UP_Port,KEY_UP_Pin)
//#define K_DOWN GPIO_ReadInputDataBit(KEY_Port,KEY_DOWN_Pin)
//#define K_LEFT GPIO_ReadInputDataBit(KEY_Port,KEY_LEFT_Pin)
//#define K_RIGHT GPIO_ReadInputDataBit(KEY_Port,KEY_RIGHT_Pin)
//定义各个按键值
#define KEY_UP 1
#define KEY_DOWN 2
#define KEY_LEFT 3
#define KEY_RIGHT 4
void KEY_INIT(void);
u8 KEY_Scan(u8 mode);
#endif
main.c
#include "systick.h"
#include "led.h"
#include "system.h"
#include "key.h"
int main()
{
u8 key,i;
SysTick_Init(72); //系统时钟初始
KEY_INIT(); //初始化KEY
LED_INIT(); //初始化LED
while(1)
{
key = KEY_Scan(0); //按键扫描
switch(key)
{
case KEY_UP: led2=0;break; //按下K_UP按键 点亮D2指示灯
case KEY_DOWN: led2=1;break; //按下K_DOWN按键 熄灭D2指示灯
case KEY_LEFT: led3=1;break; //按下K_LEFT按键 点亮D3指示灯
case KEY_RIGHT: led3=0;break; //按下K_RIGHT按键 熄灭D3指示灯
}
i++; //每加20就变led状态,每次延时10ms,200ms变换一次
if(i%20==0)
{
led1=!led1;
}
delay_ms(10);
}
}