1.stm32定时器轮询按键

Posted Alkiatu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1.stm32定时器轮询按键相关的知识,希望对你有一定的参考价值。

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:短按和长按***/ /***第二个参数 按键电压:(if1 else0是按键上拉,低电平触发按键有效)(if0 else1是按键下拉,高电平触发按键有效)***/ /***第三个参数 按键的编号: key number 依次编号下去即可***/ if(KEY1)user_key_set_scan(111,1,1);elseuser_key_set_scan(111,0,1); if(KEY2)user_key_set_scan(111,1,2);elseuser_key_set_scan(111,0,2); // if(KEY3)user_key_set_scan(1,1,3);elseuser_key_set_scan(1,0,3); // if(KEY4)user_key_set_scan(1,1,4);elseuser_key_set_scan(1,0,4); // if(KEY5)user_key_set_scan(1,1,5);elseuser_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

 


 

以上是关于1.stm32定时器轮询按键的主要内容,如果未能解决你的问题,请参考以下文章

STM32CubeMX笔记--外部中断,使用按键KEY检测

STM32-通用定时器

STM32-定时器详解

07 STM32F4定时器中断

STM32F10X-定时器/计数器

STM32F407VG 定时器