1.C文件
#include "user_key.h"
#include "stm32f10x.h"
#include <stdio.h>
/*********************************如增减按键或者修改引脚,注意看下6项需要改动的地方****************************************/
/**************************************1按键的硬件定义,改动硬件需修改*********************************/
#define KEY1 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) //按键的状态函数,增加按键,可以去掉注释符
#define KEY2 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4)
/***************************************************************************************************/
typedef struct
{
volatile unsigned char key_lock_flag; //自锁标志,用于保证按键轮询是第一次进入计时,保证一次的准确计时
volatile unsigned int key_scan_count; //按键在定时器轮询计数变量,自加
volatile unsigned char key_short_press_flag; //按键短按标志位
volatile unsigned char key_long_press_flag; //按键长按标志位,目前这变量没用到,一般是多次单击会用到这个变量
volatile unsigned char key_num; //按键的键值
}KEY_InitTypeDef;
/**************************************2按键的硬件定义,改动硬件需修改*********************************/
KEY_InitTypeDef key_array[2] = //按键结构体数组,如增加按键,可以去掉注释符
{
{0,0,0,0,0,},
{0,0,0,0,0,}
};
/***************************************************************************************************/
/*****************************3按键的硬件定义,改动硬件需修改***************************/
void user_key_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStruct);
}
/*******************************************************************************************/
/*******************************4按键的硬件定义,改动硬件需修改*********************************/
void user_key_scan(void)
{
/***此函数放置在定时器的更新函数里***/
/***第一个参数 按键按下类型:1:短按 11:长按 111:短按和长按***/
/***第二个参数 按键电压:(if{1} else{0}是按键上拉,低电平触发按键有效)(if{0} else{1}是按键下拉,高电平触发按键有效)***/
/***第三个参数 按键的编号: key number 依次编号下去即可***/
if(KEY1){user_key_set_scan(111,1,1);}else{user_key_set_scan(111,0,1);}
if(KEY2){user_key_set_scan(111,1,2);}else{user_key_set_scan(111,0,2);}
// if(KEY3){user_key_set_scan(1,1,3);}else{user_key_set_scan(1,0,3);}
// if(KEY4){user_key_set_scan(1,1,4);}else{user_key_set_scan(1,0,4);}
// if(KEY5){user_key_set_scan(1,1,5);}else{user_key_set_scan(1,0,5);}
}
/*******************************************************************************************/
/*****************************5按键的硬件定义,改动硬件需修改***************************/
unsigned char key_get_num(unsigned char key_id)
{
unsigned char key_local_param;
switch(key_id)
{
case 1: key_local_param = key_array[0].key_num;break;
case 2: key_local_param = key_array[1].key_num;break;
// case 3: key_local_param = key_array[2].key_num;break;
// case 4: key_local_param = key_array[3].key_num;break;
// case 5: key_local_param = key_array[4].key_num;break;
}
return key_local_param;
}
/**********************************************************************************/
/*****************************6按键的硬件定义,改动硬件需修改***************************/
void key_clear_num(unsigned char key_id)
{
switch(key_id)
{
case 1: key_array[0].key_num = 0;break;
case 2: key_array[1].key_num = 0;break;
// case 3: key_array[2].key_num = 0;break;
// case 4: key_array[3].key_num = 0;break;
// case 5: key_array[4].key_num = 0;break;
}
}
/**********************************************************************************/
void user_key_set_scan(unsigned char key_press_type,unsigned char key_IOvaule, unsigned char key_id)
{
/***此函数不需要动,但可以修改key_scan_count判定值来调整按键灵敏度***/
if(key_press_type == 1) //短按判断
{ switch(key_IOvaule)
{
case 1:key_array[key_id - 1].key_scan_count = 0; //按键没按下,计数清零
key_array[key_id - 1].key_lock_flag = 0; //自锁标志清零
break;
case 0:if(key_array[key_id - 1].key_lock_flag == 0) //按键按下,并且标志位是0,判定是第一次进入计时
{
key_array[key_id - 1].key_scan_count++; //计时
if(key_array[key_id - 1].key_scan_count > 100) //短按一次持续的时间,可以调整数字调灵敏度
{
key_array[key_id - 1].key_scan_count = 0; //计时清零
key_array[key_id - 1].key_lock_flag = 1; //自锁置1,完成了一次短按判断,防止重复进入
key_array[key_id - 1].key_num = 1; //短按赋键值
}
}
default:break;
}
}
if(key_press_type == 11) //长按判断
{ switch(key_IOvaule)
{
case 1:key_array[key_id - 1].key_scan_count = 0;
key_array[key_id - 1].key_lock_flag = 0;
break;
case 0:if(key_array[key_id - 1].key_lock_flag == 0)
{
key_array[key_id - 1].key_scan_count++;
if(key_array[key_id - 1].key_scan_count > 5000) //长按一次持续的时间,可以调整数字调灵敏度
{
key_array[key_id - 1].key_scan_count = 0;
key_array[key_id - 1].key_lock_flag = 1;
key_array[key_id - 1].key_num = 11;
}
}
default:break;
}
}
if(key_press_type == 111) //短按和长按判断
{ switch(key_IOvaule)
{
case 1:key_array[key_id - 1].key_scan_count = 0; //按键没按下,计数清零
key_array[key_id - 1].key_lock_flag = 0; //自锁标志清零
if(key_array[key_id - 1].key_short_press_flag == 1) //按键松开会跳到这,可判定为短按
{
key_array[key_id - 1].key_short_press_flag = 0; //短按标志清零
key_array[key_id - 1].key_num = 1; //短按赋键值
}
break;
case 0:if(key_array[key_id - 1].key_lock_flag == 0) //按键按下,并且标志位是0,判定是第一次进入计时
{
key_array[key_id - 1].key_scan_count++; //计时
if(key_array[key_id - 1].key_scan_count > 100) //短按一次持续的时间,可以调整数字调灵敏度
{
key_array[key_id - 1].key_short_press_flag = 1; //给短按标志置1,等待接下来的转态,松手或者按键持续按着
}
}
if(key_array[key_id - 1].key_scan_count > 5000) //按键没有松手,一直按着
{
key_array[key_id - 1].key_scan_count = 0; //计时清零
key_array[key_id - 1].key_short_press_flag = 0; //短按标志清零
key_array[key_id - 1].key_lock_flag = 1; //自锁置1,完成了一次长按判断,防止重复进入
key_array[key_id - 1].key_num = 11; //长按赋键值
}
default:break;
}
}
}
2.头文件
#ifndef _user_key_h_
#define _user_key_h_
/*******************************************************************************************/
/***按键初始化函数,如脚位修改,函数需要修改***/
void user_key_init(void);
/***设置轮询按键***/
void user_key_set_scan(unsigned char key_press_type,unsigned char key_IOvaule, unsigned char key_id);
/***此函数放置在定时器的更新函数里***/
void user_key_scan(void);
/*******************************************************************************************/
/*******************************************************************************************/
/***主要使用这两个函数,获取按键的键值和清除按键的键值***/
/***获取按键的键值后必须清除按键的键值***/
/***注意获取和清除的编号一定要对应,不然容易出现按键一直处于长按或者短按***/
unsigned char key_get_num(unsigned char key_id);
void key_clear_num(unsigned char key_id);
/*******************************************************************************************/
#endif