按键扫描

一、STM32按键扫描

#include "key.h"
#include    //rt_thread 头文件


static key_callback pressCallback = 0;
static key_callback holdCallback = 0;
static key_callback releaseCallback = 0;

void 
KEY_Init(void) 
{ 
 	GPIO_InitTypeDef GPIO_InitStructure;
 
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);

	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_4|GPIO_Pin_3;
	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);

}
/*
**********************************************************
*	Key callback function registration
*	@param pcallback   the key press function
*	@param hcallback	 the key longpress function
*	@param rcallback   the key realease function
* @return            NO return
***********************************************************
*/
void 
xkey_callbackRegister(key_callback pcallback,key_callback hcallback,key_callback rcallback)
{
		pressCallback=pcallback;
		holdCallback=hcallback;
		releaseCallback=rcallback;
}

/*
**********************************************************
*	Key scan function    
*	@param 							
* @return
* @note   This function needs to be called periodically(20ms)
***********************************************************
*/
void 
xkey_scan(void)
{
	static enum x_keystates key_state=KEY_NORMAL;
	static uint8_t last_key= NO_KEY;
	uint8_t cur_key	= 0;
	
	
	cur_key=xget_Keyvalue1();
	
	switch(key_state)
	{
		case KEY_NORMAL:
			if(cur_key!=last_key){
				key_state=KEY_PRESS;
			}	
			else 
				key_state=KEY_NORMAL;
			last_key=cur_key;
		break;
		
		case KEY_PRESS:
			if(cur_key==last_key)
			{
				rt_kprintf("key press\r\n");
				key_state=KEY_HOLD;
				pressCallback(&cur_key);
			}
			else
				key_state=KEY_NORMAL;   
			last_key=cur_key;
		break;
		
		case KEY_HOLD:
			if(cur_key==last_key)
			{
				rt_kprintf("key hold\r\n"); 
				key_state=KEY_HOLD;
				holdCallback(&cur_key);
			}
			else
			{
				rt_kprintf("key release\r\n"); 
				key_state=KEY_RELEASE;
				releaseCallback(&last_key);
			}
			last_key=cur_key;
		break;
		
		case KEY_RELEASE:
				if(last_key==NO_KEY)
					key_state=KEY_NORMAL;
			break;
		default:key_state=KEY_NORMAL;break;
	}	
}
#ifndef KEY_H
#define KEY_H

#include "stm32f10x.h"

enum x_keystates
{
	KEY_NORMAL,
	KEY_PRESS,
	KEY_HOLD,
	KEY_RELEASE,
	KEY_MAX,
};


typedef void (*key_callback)(void *parameter);


#define KStatusLBIT0   (!(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)&0x01))
#define KStatusLBIT1   (!(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)&0x01))
#define KStatusLBIT2   0
#define KStatusLBIT3   0
#define KStatusLBIT4   0
#define KStatusLBIT5   0
#define KStatusLBIT6   0
#define KStatusLBIT7   0

#define xget_Keyvalue1() (KStatusLBIT0|(KStatusLBIT1<<1)|(KStatusLBIT2<<2)|(KStatusLBIT3<<3)\
						|(KStatusLBIT4<<4)|(KStatusLBIT5<<5)|(KStatusLBIT6<<6)|(KStatusLBIT7<<7))	

#define NO_KEY 0x00

void KEY_Init(void);
void xkey_scan(void);
void xkey_callbackRegister(key_callback pcallback,key_callback hcallback,key_callback rcallback);

#endif

二、Demo

#include "key.h"
#include    //rt_thread 头文件

void keycallback1(void* parameter)
{
	uint8_t key_value=*(uint8_t *)parameter;
	switch(key_value)
	{
		case 0x01:rt_kprintf("按键1按下\r\n");break;
		case 0x02:rt_kprintf("按键2按下\r\n");break;
	}
}

void keycallback2(void* parameter)
{
	rt_kprintf("按键持续按下回调函数\r\n");
}

void keycallback3(void* parameter)
{
	uint8_t key_value=*(uint8_t *)parameter;
	switch(key_value)
	{
		case 0x01:rt_kprintf("按键1弹起\r\n");break;
		case 0x02:rt_kprintf("按键2弹起\r\n");break;
	}
}



static void key_thread_entry(void *parameter)
{
	//注册按键回调函数
	xkey_callbackRegister(keycallback1,keycallback2,keycallback3);
	while(1)
	{
		xkey_scan();
		rt_thread_delay(20);
	}
}

//以下是main中的线程初始化
//动态创建一个线程
key_thread=rt_thread_create("key",
								  key_thread_entry,
								  RT_NULL,
								  512,
								  2,
								  20);
	 
if(key_thread!=RT_NULL)
 rt_thread_startup(key_thread);
else
 return -1;

按键扫描_第1张图片

三、小容量单片机按键扫描参考

static void key_scan(void)
{

	
	static uint16_t Up=0;
	static uint16_t Cont=0;
	static uint16_t Trg=0;
	static uint16_t longPress_cnt=0;
	static uint8_t  longPress_state=0;
	uint16_t ReadLevel=GPIOE->IDR;
	ReadLevel|=0xFFE7; 	
	ReadLevel^=0xFFFF;
	
	Up=Cont&(Cont^ReadLevel);          //上升沿触发
	Trg=ReadLevel&(Cont^ReadLevel);   //下降沿触发
	Cont=ReadLevel;                   //长按
	
	
	if(Up==0x0008)
	{
		if(!longPress_state)
		{
			rt_kprintf("按键1弹起\r\n");
		}
		else
		{
			longPress_state=0;
		}
	}
	
	switch(Trg)
	{
		case 0x0008:rt_kprintf("按键1按下\r\n");
			break;
		case 0x0010:
			break;
		default:break;
	}
	
	if(Cont==0x0008)
	{
		if(++longPress_cnt>=100)
		{
			longPress_cnt=100;
			longPress_state=1; 	//长按弹起功能不会触发
			rt_kprintf("按键1长按2秒\r\n");
		}
	}
	else
	{
		longPress_cnt=0;
	}
}

按键扫描_第2张图片

你可能感兴趣的:(库函数)