从单片机基础到程序框架(全集 2019pdf版).pdf - 第526页

{ Su16KeyC nt=0; Su8KeySt ep++; } break; case 3: if(1==RO W_INPUT1&&1 ==ROW_INPU T2&&1==ROW_ INPUT3) { Su8KeySt ep=1; //返回 步骤 1 继续扫描 Su8KeyLo ck=0; Su16KeyC nt=0; Su8Colum nRecord++; if(Su8Co lumnRecord&g…

100%1 / 836
/* 注释二:
* 本节破题的关键:
* 矩阵按键涉及的按键数量很多,但是实际项目上一般只需要少数个别按键具备这种
* “单击”与“连续均匀触发”的特殊技能,因此,在代码上,必须把这类“特殊技能按键”与
* “大众按键”区分开来,才能相互清晰互不干扰。本节的“特殊技能按键” S1 S9。
* 如果觉得本节的讲解不够详细具体,请先阅读一下前面章节“独立按键按住不松手的连续均匀触发”
*/
void KeyScan(void) //此函数放在定时中断里每 1ms 扫描一次
{
static unsigned char Su8KeyLock=0;
static unsigned int Su16KeyCnt=0;
static unsigned char Su8KeyStep=1;
static unsigned char Su8ColumnRecord=0;
switch(Su8KeyStep)
{
case 1:
if(0==Su8ColumnRecord)
{
COLUMN_OUTPUT1=0;
COLUMN_OUTPUT2=1;
COLUMN_OUTPUT3=1;
}
else if(1==Su8ColumnRecord)
{
COLUMN_OUTPUT1=1;
COLUMN_OUTPUT2=0;
COLUMN_OUTPUT3=1;
}
else
{
COLUMN_OUTPUT1=1;
COLUMN_OUTPUT2=1;
COLUMN_OUTPUT3=0;
}
Su16KeyCnt=0;
Su8KeyStep++;
break;
case 2: //等待列输出稳定,但不是去抖动延时
Su16KeyCnt++;
if(Su16KeyCnt>=2)
{
Su16KeyCnt=0;
Su8KeyStep++;
}
break;
case 3:
if(1==ROW_INPUT1&&1==ROW_INPUT2&&1==ROW_INPUT3)
{
Su8KeyStep=1; //返回步骤 1 继续扫描
Su8KeyLock=0;
Su16KeyCnt=0;
Su8ColumnRecord++;
if(Su8ColumnRecord>=3)
{
Su8ColumnRecord=0;
}
}
else if(0==Su8KeyLock)
{
if(0==ROW_INPUT1&&1==ROW_INPUT2&&1==ROW_INPUT3)
{
Su16KeyCnt++;
if(Su16KeyCnt>=KEY_SHORT_TIME)
{
Su8KeyLock=1;
if(0==Su8ColumnRecord)
{
vGu8KeySec=1; //触发一次单击
Su16KeyCnt=0; //计时器清零,为即将来临的计时做准备
Su8KeyStep=4; //跳到 S1 按键的专属区,脱离大众按键
}
else if(1==Su8ColumnRecord)
{
vGu8KeySec=2;
}
else if(2==Su8ColumnRecord)
{
vGu8KeySec=3;
}
}
}
else if(1==ROW_INPUT1&&0==ROW_INPUT2&&1==ROW_INPUT3)
{
Su16KeyCnt++;
if(Su16KeyCnt>=KEY_SHORT_TIME)
{
Su8KeyLock=1;
if(0==Su8ColumnRecord)
{
vGu8KeySec=4;
}
else if(1==Su8ColumnRecord)
{
vGu8KeySec=5;
}
else if(2==Su8ColumnRecord)
{
vGu8KeySec=6;
}
}
}
else if(1==ROW_INPUT1&&1==ROW_INPUT2&&0==ROW_INPUT3)
{
Su16KeyCnt++;
if(Su16KeyCnt>=KEY_SHORT_TIME)
{
Su8KeyLock=1;
if(0==Su8ColumnRecord)
{
vGu8KeySec=7;
}
else if(1==Su8ColumnRecord)
{
vGu8KeySec=8;
}
else if(2==Su8ColumnRecord)
{
vGu8KeySec=9; //触发一次单击
Su16KeyCnt=0; //计时器清零,为即将来临的计时做准备
Su8KeyStep=6; //跳到 S9 按键的专属区,脱离大众按键
}
}
}