一、STM32按键扫描
#include "key.h"
#include <rtthread.h>
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);
}
void
xkey_callbackRegister(key_callback pcallback,key_callback hcallback,key_callback rcallback)
{
pressCallback=pcallback;
holdCallback=hcallback;
releaseCallback=rcallback;
}
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 <rtthread.h>
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);
}
}
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;

三、小容量单片机按键扫描参考
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;
}
}
