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

{ Su8KeyTo uchCnt1=0; //统计按键次 数清零 vGu8Sing leKeySec=1; //单击 任务,触发 1 号键 对应 S1 键 vGu8Doub leKeySec=1; //双击 任务,触发 1 号键 对应 S1 键 } } else i f(1==Su8Colu mnRecord) / /第 2 列输出低电 平 { vGu8Single KeySec=2; //触发 2 号键 对应 S2 键 } else…

100%1 / 836
}
break;
case 3:
if(1==ROW_INPUT1&&1==ROW_INPUT2&&1==ROW_INPUT3)
{
Su8KeyStep=1; //如果没有按键按下,返回到第一个运行步骤重新开始扫描!!!!!!
Su8KeyLock=0; //按键自锁标志清零
Su16KeyCnt=0; //按键去抖动延时计数器清零,此行非常巧妙
if(Su8KeyTouchCnt1>=1) //之前已经有按键触发过一次,启动间隔时间的计数器
{
Su16KeyIntervalCnt1++; //按键间隔的时间计数器累加
if(Su16KeyIntervalCnt1>=KEY_INTERVAL_TIME) //达到最大允许的间隔时间,溢出无效
{
Su16KeyIntervalCnt1=0; //时间计数器清零
Su8KeyTouchCnt1=0; //清零按键的按下的次数,因为间隔时间溢出无效
}
}
Su8ColumnRecord++; //输出下一列
if(Su8ColumnRecord>=3)
{
Su8ColumnRecord=0; //依次输出完 3 列之后,继续从第 1 开始输出低电平
}
}
else if(0==Su8KeyLock) //有按键按下,且是第一次触发
{
if(0==ROW_INPUT1&&1==ROW_INPUT2&&1==ROW_INPUT3)
{
Su16KeyCnt++; //去抖动延时计数器
if(Su16KeyCnt>=KEY_SHORT_TIME)
{
Su8KeyLock=1;//自锁 1,避免一直触发,只有松开按键,此标志位才会被清零
if(0==Su8ColumnRecord) //第 1 列输出低电
{
Su16KeyIntervalCnt1=0; //按键有效间隔的时间计数器清零
Su8KeyTouchCnt1++; //记录当前单击的次数
if(1==Su8KeyTouchCnt1) //只按了 1
{
vGu8SingleKeySec=1; //单击任务,触发 1 号键 对应 S1
}
else if(Su8KeyTouchCnt1>=2) //连续按了两次以上
{
Su8KeyTouchCnt1=0; //统计按键次数清零
vGu8SingleKeySec=1; //单击任务,触发 1 号键 对应 S1
vGu8DoubleKeySec=1; //双击任务,触发 1 号键 对应 S1
}
}
else if(1==Su8ColumnRecord) //第 2 列输出低电
{
vGu8SingleKeySec=2; //触发 2 号键 对应 S2
}
else if(2==Su8ColumnRecord) //第 3 列输出低电
{
vGu8SingleKeySec=3; //触发 3 号键 对应 S3
}
}
}
else if(1==ROW_INPUT1&&0==ROW_INPUT2&&1==ROW_INPUT3)
{
Su16KeyCnt++; //去抖动延时计数器
if(Su16KeyCnt>=KEY_SHORT_TIME)
{
Su8KeyLock=1;//自锁 1,避免一直触发,只有松开按键,此标志位才会被清零
if(0==Su8ColumnRecord) //第 1 列输出低电
{
vGu8SingleKeySec=4; //触发 4 号键 对应 S4
}
else if(1==Su8ColumnRecord) //第 2 列输出低电
{
vGu8SingleKeySec=5; //触发 5 号键 对应 S5
}
else if(2==Su8ColumnRecord) //第 3 列输出低电
{
vGu8SingleKeySec=6; //触发 6 号键 对应 S6
}
}
}
else if(1==ROW_INPUT1&&1==ROW_INPUT2&&0==ROW_INPUT3)
{
Su16KeyCnt++; //去抖动延时计数器
if(Su16KeyCnt>=KEY_SHORT_TIME)
{
Su8KeyLock=1;//自锁 1,避免一直触发,只有松开按键,此标志位才会被清零
if(0==Su8ColumnRecord) //第 1 列输出低电
{
vGu8SingleKeySec=7; //触发 7 号键 对应 S7
}
else if(1==Su8ColumnRecord) //第 2 列输出低电
{
vGu8SingleKeySec=8; //触发 8 号键 对应 S8
}
else if(2==Su8ColumnRecord) //第 3 列输出低电
{
vGu8SingleKeySec=9; //触发 9 号键 对应 S9
}
}
}
}
break;
}
}
void SingleKeyTask(void) //按键单击的任务函数,放在主函数内
{
if(0==vGu8SingleKeySec)
{
return; //按键的触发序号是 0 意味着无按键触发,直接退出当前函数,不执行此函数下面的代码
}
switch(vGu8SingleKeySec) //根据不同的按键触发序号执行对应的代
{
case 1: //S1 键的单击任务
//通过 Gu8LedStatus 的状态切换,来反复切换 LED 的“灭”与“亮”的状
if(0==Gu8LedStatus)
{
Gu8LedStatus=1; //标识并且更改当前 LED 灯的状态。0 就变成 1。
LedOpen(); //点亮 LED
}
else
{
Gu8LedStatus=0; //标识并且更改当前 LED 灯的状态。1 就变成 0。
LedClose(); //关闭 LED
}