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

COLUMN_O UTPUT1=0; COLUMN_O UTPUT2=1; COLUMN_O UTPUT3=1; } else i f(1==Su8Colu mnRecord) { COLUMN_O UTPUT1=1; COLUMN_O UTPUT2=0; COLUMN_O UTPUT3=1; } else { COLUMN_O UTPUT1=1; COLUMN_O UTPUT2=1; COLUMN_O UTPUT3=0; } Su16…

100%1 / 836
volatile unsigned int vGu16BeepTimerCnt=0;
unsigned char Gu8LedStatus_P1_4=0; //P1.4 所在的 LED 的状态
unsigned char Gu8LedStatus_P1_5=0; //P1.5 所在的 LED 的状态
volatile unsigned char vGu8SingleKeySec=0;
volatile unsigned char vGu8DoubleKeySec=0;
void main()
{
SystemInitial();
Delay(10000);
PeripheralInitial();
while(1)
{
SingleKeyTask();
DoubleKeyTask();
}
}
/* 注释一:
* 矩阵按键“无序”触发的两个最关键地方:
* (1)如果是 S1 按键先被按下并且单击触发之后,“马上更新输出列的信号状态”,然后切换
* “S1 后面所在的步骤里”,进入 S1 S2 两个按键的轮番循环监控之中,如果发现 S1 按键率先
* 被松开了,就把步骤切换到开始的第一步,重新开始新一轮的按键扫描。
* (2)如果是 S2 按键先被按下并且单击触发之后,“马上更新输出列的信号状态”,然后切换
* “S2 后面所在的步骤里”,进入 S1 S2 两个按键的轮番循环监控之中,如果发现 S2 按键率先
* 被松开了,就把步骤切换到开始的第一步,重新开始新一轮的按键扫描。
* (3)上面两个描述中的两种步骤,“S1 后面所在的步骤里”和“S2 后面所在的步骤里”是分开的,
* 不共用的,这是本节破题的关键
*/
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;
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)
{
vGu8SingleKeySec=1; //单击任务,触发 1 号键 对应 S1
//“马上更新输出列的信号状态”
COLUMN_OUTPUT1=1;
COLUMN_OUTPUT2=0; //列 2 也输出 0,下一步监 S2,非常关键的代码!
COLUMN_OUTPUT3=1;
Su16KeyCnt=0; //去抖动延时清零,为下一步计时做准备
Su8KeyStep=4; //切换到“S1 后面所在的步骤里,破题的关键!!!
}
else if(1==Su8ColumnRecord)
{
vGu8SingleKeySec=2; //单击任务,触发 2 号键 对应 S2
//“马上更新输出列的信号状态”
COLUMN_OUTPUT1=0; //列 1 也输 0,下一步监 S1,非常关键的代码!
COLUMN_OUTPUT2=1;
COLUMN_OUTPUT3=1;
Su16KeyCnt=0; //去抖动延时清零,为下一步计时做准备
Su8KeyStep=8; //切换到“S2 后面所在的步骤里,破题的关键!!!
}
else if(2==Su8ColumnRecord)
{
vGu8SingleKeySec=3;
}
}
}
else if(1==ROW_INPUT1&&0==ROW_INPUT2&&1==ROW_INPUT3)
{
Su16KeyCnt++;
if(Su16KeyCnt>=KEY_SHORT_TIME)
{
Su8KeyLock=1;