⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 key.c

📁 按键是比较复杂。可以用状态机表示。 每10mS执行一次键盘扫描任务 0、无键
💻 C
字号:
/**
 ******************************************************************************
 * @file key.c
 * @brief  用状态机编写的按键扫描
 * @author ifree64 - stm8 手持示波表开源项目组
 * @version V0.1.0
 * @date 03/25/2009
 ******************************************************************************
 *
 * free for use
 *
 ******************************************************************************
 */
#include "key.h"

enum KEY_ScanState{
	KSCAN_START = 0,        /* 无键按下, 键盘扫描初始状态 */
	KSCAN_PRESS,            /* 键按下,判断抖动, >0.1s */
	KSCAN_LONGPRESS,        /* 非抖动,判断是否长按键,>0.8s */
	KSCAN_PDLF,             /* 判断连发,得到一次长按键后1s 后开始连发 */
	KSCAN_LIANFA            /* 连发,每0.2s产生一次连发按键 */
};

struct KEY_StateFsm{
	enum KEY_ScanState KPressNext;       /* 键按下,下一个状态 */ 
	enum KEY_ScanState NoKeyNext;        /* 键抬起,下一个状态 */
	u8 KPressTime;	               /* 键按下需持续的时间, 10ms的倍数 */
	u8 KPressType;	     	       /* 键按下满足条件,输出按键类型 */	
};

/* 保证状态编号值与在数组中的位置相同  */
struct KEY_StateFsm const KEY_StateFsmTable[] = {
	/* kpress_next,     nokey_next,     time,   type   */
	{ KSCAN_PRESS,      KSCAN_START,    0,      KTYPE_NO},      /* KSCAN_START: 0 */
	{ KSCAN_LONGPRESS,  KSCAN_START,    5,      KTYPE_NORMAL},  /* KSCAN_PRESS: 1 */
	{ KSCAN_PDLF,       KSCAN_START,    80,     KTYPE_LONG},    /* KSCAN_LONGPRESS: 2 */
	{ KSCAN_LIANFA,     KSCAN_START,    100,    KTYPE_NO},      /* KSCAN_PDLF: 3 */
	{ KSCAN_LIANFA,     KSCAN_START,    20,     KTYPE_LIANFA}   /* KSCAN_LIANFA: 4*/
};

void KEY_Init(void)
{
	/* Initialize I/O in Input Mode with No Interrupt */
	GPIO_Init(KEY_PORT, KEY_PIN, GPIO_MODE_IN_FL_NO_IT); 

}

/* 
   功能描述:读取按键状态, 根据不同按键电路和编号方式修改本函数
   入口参数:无
   出口参数:按键编号
   */
static u8 KEY_Read(void)
{
    
    u8 KCode = 0;
/*	u8 KMask;
    // 读引脚状态,取反后1表示键按下
    KMask = GPIO_ReadInputData(KEY_PORT) ^ 0xFF;
	

	// KEY_PORT上接8个独立式按键,从低到高编号为1~8
	while(KMask != 0)
	{
		KMask >>= 1;
		KCode++;
	}
*/
    if( GPIO_ReadInputPin(KEY_PORT, KEY_PIN) == RESET )
        KCode = 1;
	return KCode;
}

/*
   使用说明:为了得到该函数提供的功能,必须每10ms调用1次
   功能描述:按键扫描,根据状态表的设置,返回当前按键状态
   入口参数:无
   出口参数:按键编号和按键种类,格式如下
   D7 D6 D5 D4 D3 D2 D1 D0
   M1 M0 K5 K4 K3 K2 K1 K0
M1:M0 表示按键类型, 01 普通  10 长按键  11 连发按键
K5:K0 按键编号 1~63, 总共可以支持2^6 - 1 = 63个按键    
*/
u8 KEY_Scan(void)
{
	static enum KEY_ScanState KScan_CurrState = KSCAN_START;
	static u8 OldKey;
	static u8 KTimeCounter = 0;

	u8 rKeyCode = 0;		// 0 for No key press
	u8 CurrKey = KEY_Read();

	if( (CurrKey != 0) && (CurrKey == OldKey) )
	{
		if(++KTimeCounter >= KEY_StateFsmTable[KScan_CurrState].KPressTime ) 
		{
			KTimeCounter = 0;
			rKeyCode = KEY_StateFsmTable[KScan_CurrState].KPressType | CurrKey;
			KScan_CurrState = KEY_StateFsmTable[KScan_CurrState].KPressNext;
		}
	}	
	else
	{
		//   抖动或新键
		KScan_CurrState = KEY_StateFsmTable[KScan_CurrState].NoKeyNext;
		OldKey = CurrKey;
	}
	return rKeyCode;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -