#include "key.h"
/*********************************************************************************
*************************MCU啟明 STM32F103MINI開(kāi)發(fā)板******************************
**********************************************************************************
* 文件名稱: key.c *
* 文件簡(jiǎn)述:按鍵掃描程序 *
* 創(chuàng)建日期:2019.08.08 *
* 版 本:V1.0 *
* 作 者:Reny Ren *
* 說(shuō) 明:該按鍵掃描,包涵各種按鍵模式的掃描 *
**********************************************************************************
*********************************************************************************/
/**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~按鍵模式剖析~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
一、按鍵返回值,即按鍵掃描結(jié)果值,分為以下幾種情況
1、按鍵按下未抬起時(shí)的返回值,對(duì)應(yīng)代碼中 keydown_data 變量的值
2、按鍵按下抬起后才返回的值,對(duì)應(yīng)代碼中 keyup_data 變量的值
3、按任意鍵有效,只需在程序中判斷key_time>某個(gè)值,該值取決于執(zhí)行一次掃描函數(shù)的
時(shí)間長(zhǎng)短,掃描函數(shù)時(shí)間長(zhǎng),相應(yīng)這該值就小,反之亦然。
4、需要長(zhǎng)按一個(gè)鍵一段時(shí)間才執(zhí)行相應(yīng)的程序,就需要該鍵鍵值key_tem與key_time
配合使用,即實(shí)現(xiàn)某個(gè)按鍵(key_tem)長(zhǎng)按多久(key_time)后執(zhí)行相應(yīng)的程序
二、按鍵使用模式
1、單按:按鍵按下(一直按著)只返回一次有效按鍵值
2、連按:按鍵一直按著每執(zhí)行一次按鍵掃描函數(shù)就返回一次按鍵值
3、void key_scan(u8 mode) 中 mode 0:?jiǎn)伟?nbsp; 1:連按
三、按鍵使用注意事項(xiàng);
1、當(dāng)使用抬起返回值keyup_data時(shí),按鍵的連按模式無(wú)效,因?yàn)殒I抬起才返回按鍵值,你
按再久都沒(méi)用,所以在使用keyup_data時(shí),模式mode必須設(shè)置為0
2、如果需要keydown_data與key_time配合構(gòu)成長(zhǎng)按,模式mode需設(shè)置為1,才可用
3、如果需要keyup_data與key_time配合構(gòu)成長(zhǎng)按,就要對(duì)程序作出相應(yīng)的改動(dòng),在函數(shù)的
末尾,將 key_time=0; 改為 key_tem=0;就可以使用長(zhǎng)按一個(gè)按鍵一段時(shí)間,等時(shí)間到
并且按鍵抬起才執(zhí)行相應(yīng)的代碼。不過(guò)這樣改動(dòng),按任意鍵就失效了,因?yàn)榘存I抬起沒(méi)
把key_time清零,key_time一直有值;蛘哂脩暨是需要任意鍵有效就要自己在相應(yīng)的
代碼中把key_time清零。這種長(zhǎng)按配合使用在實(shí)際是很少用到的。
**/
u8 keydown_data=0x00; //按鍵按下后就返回的值
u8 keyup_data=0x00; //按鍵抬起返回值
u16 key_time=0x00; //按鍵按下之后的時(shí)間計(jì)數(shù),該值乘以掃描一次按鍵函數(shù)的時(shí)間就等于按鍵按下的時(shí)間
u8 key_tem=0x00; //長(zhǎng)按的按鍵值與按鍵掃描程序過(guò)渡變量
u8 key_bak=0x00; //按鍵掃描程序過(guò)渡變量
//按鍵IO口初始化函數(shù)
void KEY_Init(void)
{
//初始化GPIOF6,7,8,9
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE); //使能GPIOF時(shí)鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;//KEY0 KEY1 KEY2 對(duì)應(yīng)引腳
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //設(shè)置成上拉輸入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
GPIO_Init(GPIOF, &GPIO_InitStructure); //初始化GPIOF2,3,4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; // KEY3對(duì)應(yīng)引腳
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0設(shè)置成輸入,默認(rèn)下拉
GPIO_Init(GPIOF, &GPIO_InitStructure); //初始化GPIOF.5
}
/****************************************************************************
* 名 稱: void key_scan(u8 mode)
* 功 能:按鍵掃描函數(shù)
* 入口參數(shù):mode:0:?jiǎn)伟?br />
1: 連按
* 返回參數(shù):無(wú)
* 說(shuō) 明:響應(yīng)優(yōu)先級(jí),KEY0>KEY1>KEY2>KEY3
****************************************************************************/
void key_scan(u8 mode)
{
keyup_data=0; //鍵抬起后按鍵值一次有效
if(KEY0==0||KEY1==0||KEY2==0||KEY3==1) //有鍵正按下
{
if(KEY0==0) key_tem=1;
else if(KEY1==0) key_tem=2;
else if(KEY2==0) key_tem=3;
else if(KEY3==1) key_tem=4;
if (key_tem == key_bak) //有鍵按下后第一次掃描不處理,與else配合第二次掃描有效,這樣實(shí)現(xiàn)了去抖動(dòng)
{
key_time++; //有鍵按下后執(zhí)行一次掃描函數(shù),該變量加1
keydown_data=key_tem; //按鍵值賦予keydown_data
if( (mode==0)&&(key_time>1) )//key_time>1按鍵值無(wú)效,這就是單按,如果mode為1就為連按
keydown_data=0;
}
else //去抖動(dòng)
{
key_time=0;
key_bak=key_tem;
}
}
else //鍵抬起
{
if(key_time>2) //按鍵抬起后返回一次按鍵值
{
keyup_data=key_tem; //鍵抬起后按鍵值賦予keydown_data
}
key_bak=0; //要清零,不然下次執(zhí)行掃描程序時(shí)按鍵的值跟上次按的值一樣,就沒(méi)有去抖動(dòng)處理了
key_time=0;
keydown_data=0;
}
}
|