(1)单击K1点亮LED,单击K2熄灭LED,K1与K2组合按键蜂鸣器发声。
#include "reg52.h"
#define KEY_VOICE_TIME 50//按键触发后发出的声音长度
#define KEY_FILTER_TIME 25//按键滤波的“稳定时间”25ms
// #define KEY_INTERVAL_TIME 400//连续两次单击之间的最大有效时间
sbit beep=P2^3;//蜂鸣器
sbit P1_4=P1^4;//LED
sbit KEY_INPUT1=P3^4;//按键识别输入口
sbit KEY_INPUT2=P3^5;
volatile unsigned char vGu8BeepTimerFlag=0;
volatile unsigned int vGu16BeepTimerCnt=0;
// unsigned char Gu8LedStatus=0;//LED灯的状态,0代表灭,1代表亮
volatile unsigned char vGu8SingleKeySec=0;//单击按键的触发序号
volatile unsigned char vGu8CombinationKeySec=0;//组合按键的触发序号
void SystemInitial()
{
TMOD=0x01;
TH0=0xfc;
TL0=0x66;
EA=1;
ET0=1;
TR0=1;
}
void Delay(unsigned long u32DelayTime)
{
for(;u32DelayTime>0;u32DelayTime--);
}
void LedOpen()
{
P1_4=0;
}
void LedClose()
{
P1_4=1;
}
void PeripheralInitial()
{//led初始化没有放在SystemInitial中是因为led显示内容对上电瞬间要求不高,如果是控制继电器则应该放在SystemInitial中
LedClose();
}
void BeepOpen()
{
beep=0;
}
void BeepClose()
{
beep=1;
}
void VoiceScan()//蜂鸣器的非阻塞驱动."驱动层"的驱动函数,放在定时中断函数里每1ms扫描一次,保证声音长度的一致性
{
static unsigned char Su8Lock=0;
if(1==vGu8BeepTimerFlag && vGu16BeepTimerCnt>0)
{
if(0==Su8Lock)
{
Su8Lock=1;//触发声音后自锁起来,避免BeepOpen()被重复扫描影响执行效率,发声时只执行一次BeepOpen()函数即可
BeepOpen();//蜂鸣器发声,封装成函数为了代码的移植性
}
else//借用else结构实现先发声下一次中断再开始计时
{
vGu16BeepTimerCnt--;
if(0==vGu16BeepTimerCnt)
{
Su8Lock=0;//关闭声音后及时解锁为下一次触发做准备
BeepClose();
}
}
}
}
void KeyScan()//非阻塞,放在中断函数中"清零式滤波"
{
static unsigned char Su8KeyLock1;//1号按键的自锁
static unsigned int Su16KeyCnt1;//1号按键的计时器
static unsigned char Su8KeyLock2;
static unsigned int Su16KeyCnt2;
static unsigned char Su8CombinationKeyLock;//组合按键自锁
static unsigned int Su16CombinationKeyCnt;//组合按键计数器
if(0!=KEY_INPUT1 || 0!=KEY_INPUT2)//关键语句,同时按下即都是0时退出语句
{
Su8CombinationKeyLock=0;//
Su16CombinationKeyCnt=0;
}
else if(0 == Su8CombinationKeyLock)//else设计巧妙,等效于if(0==KEY_INPUT1 && 0==KEY_INPUT2 && 0==Su8CombinationKeyLock)
{
Su16CombinationKeyCnt++;
if(Su16CombinationKeyCnt>=KEY_FILTER_TIME)//滤波的稳定时间
{
Su8CombinationKeyLock=1;//自锁避免一直触发
vGu8CombinationKeySec=1;//组合按键按下标志位
}
}
if(0!=KEY_INPUT1)//IO口是高电平,没有按键按下,”去抖动延时计数器“一直被清零,如果受到外界或抖动干扰就可以去除瞬间的杂波干扰
{
Su8KeyLock1=0;//按键解锁
Su16KeyCnt1=0;//”去抖动延时计数器“,按键去抖动的重要语句,在抖动过程中一旦有高电平立刻置0直到稳定
}
else if(0 == Su8KeyLock1)//说明按键被按下,else设计很巧妙相当于KEY_INPUT1==0
{
Su16KeyCnt1++;//累加的过程就是在滤波,若在累加过程中受到干扰IO口触发高电平,这时马上将Su16KeyCnt1置0,即去除瞬间杂波
if(Su16KeyCnt1>=KEY_FILTER_TIME)//滤波的“稳定时间”
{
Su8KeyLock1=1;//按键自锁标志位,一旦触发按键标志位置1,防止按键按键按住不松手时不断触发按键
vGu8SingleKeySec=1;//按键1单击触发
}
}
if(0!=KEY_INPUT2)
{
Su8KeyLock2=0;
Su16KeyCnt2=0;
}
else if(0 == Su8KeyLock2)
{
Su16KeyCnt2++;
if(Su16KeyCnt2>=KEY_FILTER_TIME)
{
Su8KeyLock2=1;
vGu8SingleKeySec=2;
}
}
}
void SingleKeyTask()
{
if(0==vGu8SingleKeySec)
{
return;//序号为0无按键触发,退出当前函数.因为当按键多达几十个时就能避免主函数每次进入KeyTask函数时进入switch多次判断,可能会更高效
}
switch(vGu8SingleKeySec)
{
case 1:
LedOpen();
vGu8SingleKeySec=0;//响应按键服务程序后按键编号清零避免一直触发
break;
case 2:
LedClose();
vGu8SingleKeySec=0;
break;
}
}
void CombinationKeyTask()
{
if(0==vGu8CombinationKeySec)
{
return;
}
switch(vGu8CombinationKeySec)
{
case 1:
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=KEY_VOICE_TIME;//"应用层"只需赋值,就发出固定时间长度的声音
vGu8BeepTimerFlag=1;
vGu8CombinationKeySec=0;//响应按键服务程序后,按键编号清零避免一直触发
break;
}
}
void main()
{
SystemInitial();
Delay(10000);
PeripheralInitial();
while(1)
{
SingleKeyTask();
CombinationKeyTask();
}
}
void T0_time() interrupt 1
{
VoiceScan();
KeyScan();//因为KeyScan是特殊函数放在中断函数里,涉及到IO口输入信号的滤波,滤波就涉及到时间的及时性和均匀性,放在中断中更能保证时间的一致性
TH0=0xfc;//如蜂鸣器驱动,动态数码管驱动,按键扫描驱动
TL0=0x66;
}
(2)“电脑键盘式”组合按键。如同电脑键盘的“crtl+c”,先按下ctrl再按c才能触发。
K1按下一次LED亮或灭;先按住K2再按住K1触发组合键蜂鸣器响。
#include "reg52.h"
#define KEY_VOICE_TIME 50//按键触发后发出的声音长度
#define KEY_FILTER_TIME 25//按键滤波的“稳定时间”25ms
// #define KEY_INTERVAL_TIME 400//连续两次单击之间的最大有效时间
sbit beep=P2^3;//蜂鸣器
sbit P1_4=P1^4;//LED
sbit KEY_INPUT1=P3^4;//按键识别输入口
sbit KEY_INPUT2=P3^5;
volatile unsigned char vGu8BeepTimerFlag=0;
volatile unsigned int vGu16BeepTimerCnt=0;
unsigned char Gu8LedStatus=0;//LED灯的状态,0代表灭,1代表亮
volatile unsigned char vGu8SingleKeySec=0;//单击按键的触发序号
volatile unsigned char vGu8CombinationKeySec=0;//组合按键的触发序号
void SystemInitial()
{
TMOD=0x01;
TH0=0xfc;
TL0=0x66;
EA=1;
ET0=1;
TR0=1;
}
void Delay(unsigned long u32DelayTime)
{
for(;u32DelayTime>0;u32DelayTime--);
}
void LedOpen()
{
P1_4=0;
}
void LedClose()
{
P1_4=1;
}
void PeripheralInitial()
{//led初始化没有放在SystemInitial中是因为led显示内容对上电瞬间要求不高,如果是控制继电器则应该放在SystemInitial中
LedClose();
}
void BeepOpen()
{
beep=0;
}
void BeepClose()
{
beep=1;
}
void VoiceScan()//蜂鸣器的非阻塞驱动."驱动层"的驱动函数,放在定时中断函数里每1ms扫描一次,保证声音长度的一致性
{
static unsigned char Su8Lock=0;
if(1==vGu8BeepTimerFlag && vGu16BeepTimerCnt>0)
{
if(0==Su8Lock)
{
Su8Lock=1;//触发声音后自锁起来,避免BeepOpen()被重复扫描影响执行效率,发声时只执行一次BeepOpen()函数即可
BeepOpen();//蜂鸣器发声,封装成函数为了代码的移植性
}
else//借用else结构实现先发声下一次中断再开始计时
{
vGu16BeepTimerCnt--;
if(0==vGu16BeepTimerCnt)
{
Su8Lock=0;//关闭声音后及时解锁为下一次触发做准备
BeepClose();
}
}
}
}
void KeyScan()
{
static unsigned char Su8KeyLock1;
static unsigned int Su16KeyCnt1;
if(0!=KEY_INPUT1)
{
Su8KeyLock1=0;
Su16KeyCnt1=0;
}
else if(0 == Su8KeyLock1)
{
Su16KeyCnt1++;
if(Su16KeyCnt1>=KEY_FILTER_TIME)
{
if(0 == KEY_INPUT2)//"电脑组合按键关键语句",只有先按下K2再按下K1才能触发组合按键
{
Su8KeyLock1=1;
vGu8CombinationKeySec=1;
}
else
{
Su8KeyLock1=1;
vGu8SingleKeySec=1;
}
}
}
}
void SingleKeyTask()
{
if(0==vGu8SingleKeySec)
{
return;//序号为0无按键触发,退出当前函数.因为当按键多达几十个时就能避免主函数每次进入KeyTask函数时进入switch多次判断,可能会更高效
}
switch(vGu8SingleKeySec)
{
case 1:
if(0 == Gu8LedStatus)
{
Gu8LedStatus=1;
LedOpen();
}
else
{
Gu8LedStatus=0;
LedClose();
}
vGu8SingleKeySec=0;
break;
}
}
void CombinationKeyTask()
{
if(0==vGu8CombinationKeySec)
{
return;
}
switch(vGu8CombinationKeySec)
{
case 1:
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=KEY_VOICE_TIME;//"应用层"只需赋值,就发出固定时间长度的声音
vGu8BeepTimerFlag=1;
vGu8CombinationKeySec=0;//响应按键服务程序后,按键编号清零避免一直触发
break;
}
}
void main()
{
SystemInitial();
Delay(10000);
PeripheralInitial();
while(1)
{
SingleKeyTask();
CombinationKeyTask();
}
}
void T0_time() interrupt 1
{
VoiceScan();
KeyScan();//因为KeyScan是特殊函数放在中断函数里,涉及到IO口输入信号的滤波,滤波就涉及到时间的及时性和均匀性,放在中断中更能保证时间的一致性
TH0=0xfc;//如蜂鸣器驱动,动态数码管驱动,按键扫描驱动
TL0=0x66;
}
(3)独立按键的短按与长按
独立按键“短按”一次亮灭切换,“长按”一次蜂鸣器响
#include "reg52.h"
#define KEY_VOICE_TIME 50
#define KEY_SHOTR_TIME 25//短按时间
#define KEY_LONG_TIME 500//长按时间
sbit beep=P2^3;//蜂鸣器
sbit P1_4=P1^4;//LED
sbit KEY_INPUT1=P3^4;//按键识别输入口
// sbit KEY_INPUT2=P3^5;
volatile unsigned char vGu8BeepTimerFlag=0;
volatile unsigned int vGu16BeepTimerCnt=0;
unsigned char Gu8LedStatus=0;//LED灯的状态,0代表灭,1代表亮
volatile unsigned char vGu8SingleKeySec=0;
void SystemInitial()
{
TMOD=0x01;
TH0=0xfc;
TL0=0x66;
EA=1;
ET0=1;
TR0=1;
}
void Delay(unsigned long u32DelayTime)
{
for(;u32DelayTime>0;u32DelayTime--);
}
void LedOpen()
{
P1_4=0;
}
void LedClose()
{
P1_4=1;
}
void PeripheralInitial()
{//led初始化没有放在SystemInitial中是因为led显示内容对上电瞬间要求不高,如果是控制继电器则应该放在SystemInitial中
LedClose();
}
void BeepOpen()
{
beep=0;
}
void BeepClose()
{
beep=1;
}
void VoiceScan()
{
static unsigned char Su8Lock=0;
if(1==vGu8BeepTimerFlag && vGu16BeepTimerCnt>0)
{
if(0==Su8Lock)
{
Su8Lock=1;
BeepOpen();
}
else
{
vGu16BeepTimerCnt--;
if(0==vGu16BeepTimerCnt)
{
Su8Lock=0;
BeepClose();
}
}
}
}
void KeyScan()
{
static unsigned char Su8KeyLock1;
static unsigned int Su16KeyCnt1;
static unsigned char Su8KeyShortFlag=0;
if(0!=KEY_INPUT1)
{
Su8KeyLock1=0;
Su16KeyCnt1=0;
if(1 == Su8KeyShortFlag)
{
Su8KeyShortFlag=0;
vGu8SingleKeySec=1;//松手后在短按时间内才触发短按
}
}
else if(0 == Su8KeyLock1)
{
Su16KeyCnt1++;
if(Su16KeyCnt1>=KEY_SHOTR_TIME)//到达短按时间
{
Su8KeyShortFlag=1;//短按标志很重要,松手才能触发短按
}
if(Su16KeyCnt1>=KEY_LONG_TIME)//到达长按时间
{
Su8KeyLock1=1;//触发自锁,避免一直触发长按
Su8KeyShortFlag=0;//清除短按标志
vGu8SingleKeySec=2;//触发长按
}
}
}
void SingleKeyTask()
{
if(0==vGu8SingleKeySec)
{
return;
}
switch(vGu8SingleKeySec)
{
case 1:
if(0 == Gu8LedStatus)
{
Gu8LedStatus=1;
LedOpen();
}
else
{
Gu8LedStatus=0;
LedClose();
}
vGu8SingleKeySec=0;
break;
case 2:
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=KEY_VOICE_TIME;
vGu8BeepTimerFlag=1;
vGu8SingleKeySec=0;
break;
}
}
void main()
{
SystemInitial();
Delay(10000);
PeripheralInitial();
while(1)
{
SingleKeyTask();
}
}
void T0_time() interrupt 1
{
VoiceScan();
KeyScan();
TH0=0xfc;
TL0=0x66;
}
(4)按键按住不松手的连续均匀触发
按下K1,跑马灯左边跑一步;按下K2,右边跑一步;按住K1或K2不松手连续触发,跑马灯连续跑;按键单击一次时蜂鸣器叫一次,连续触发时不鸣叫。
#include "reg52.h"
#define KEY_VOICE_TIME 50
#define KEY_SHORT_TIME 25//按键滤波的“稳定时间”25ms
#define KEY_ENTER_CONTINUITY_TIME 300//从单击到连击间隔时间
#define KEY_CONTINUITY_TIME 80//连击间隔时间
#define BUS_P1 P1//p1口连接8个led灯
sbit beep=P2^3;//蜂鸣器
sbit KEY_INPUT1=P3^4;//按键识别输入口
sbit KEY_INPUT2=P3^5;
volatile unsigned char vGu8BeepTimerFlag=0;
volatile unsigned int vGu16BeepTimerCnt=0;
unsigned char Gu8LedStatus=0;//1左移的位数
unsigned char Gu8DisplayUpdata=1;//显示的刷新标志
volatile unsigned char vGu8KeySec=0;//按键的触发序号
volatile unsigned char vGu8ShiedVoiceFlag=0;//屏蔽声音标志
void SystemInitial()
{
TMOD=0x01;
TH0=0xfc;
TL0=0x66;
EA=1;
ET0=1;
TR0=1;
}
void Delay(unsigned long u32DelayTime)
{
for(;u32DelayTime>0;u32DelayTime--);
}
void PeripheralInitial()
{
}
void BeepOpen()
{
beep=0;
}
void BeepClose()
{
beep=1;
}
void VoiceScan()
{
static unsigned char Su8Lock=0;
if(1==vGu8BeepTimerFlag && vGu16BeepTimerCnt>0)
{
if(0==Su8Lock)
{
Su8Lock=1;
BeepOpen();
}
else
{
vGu16BeepTimerCnt--;
if(0==vGu16BeepTimerCnt)
{
Su8Lock=0;
BeepClose();
}
}
}
}
/*Gu8DisplayUpdata“显示刷新变量”在显示框架中很常见,目的是既能及时刷新显示,又能避免主函数
“不断执行显示代码”而影响程序效率*/
void DisplayTask()
{
if(1 == Gu8DisplayUpdata)
{
Gu8DisplayUpdata=0;
BUS_P1=~(1<<Gu8LedStatus);//1左移Gu8LedStatus位
}
}
void KeyScan()
{
static unsigned char Su8KeyLock1;
static unsigned int Su16KeyCnt1;
static unsigned int Su16KeyContinuityCnt1;
static unsigned char Su8KeyLock2;
static unsigned int Su16KeyCnt2;
static unsigned int Su16KeyContinuityCnt2;
if(0!=KEY_INPUT1)
{
Su8KeyLock1=0;
Su16KeyCnt1=0;
Su16KeyContinuityCnt1=0;
}
else if(0 == Su8KeyLock1)
{
Su16KeyCnt1++;
if(Su16KeyCnt1>=KEY_SHORT_TIME)//按键滤波时间25ms
{
Su8KeyLock1=1;//自锁起来,按住不放进入连续触发检测
vGu8KeySec=1;//触发一次K1按键
Su16KeyCnt1=0;
}
}
else if(Su16KeyCnt1<=KEY_ENTER_CONTINUITY_TIME)
{
Su16KeyCnt1++;//第一次按下按键之后到连续触发的时间间隔300ms
}
else//按住300ms后任然不放手进入连续触发
{
Su16KeyContinuityCnt1++;
if(Su16KeyContinuityCnt1>=KEY_CONTINUITY_TIME)//每80ms触发一次
{
Su16KeyContinuityCnt1=0;
vGu8KeySec=1;//触发
vGu8ShiedVoiceFlag=1;//连续触发屏蔽按键触发的声音
}
}
if(0!=KEY_INPUT2)
{
Su8KeyLock2=0;
Su16KeyCnt2=0;
Su16KeyContinuityCnt2=0;
}
else if(0 == Su8KeyLock2)
{
Su16KeyCnt2++;
if(Su16KeyCnt2>=KEY_SHORT_TIME)
{
Su8KeyLock2=1;
vGu8KeySec=2;//触发一次K2按键
Su16KeyCnt2=0;
}
}
else if(Su16KeyCnt2<=KEY_ENTER_CONTINUITY_TIME)
{
Su16KeyCnt2++;
}
else//按住300ms后任然不放手进入连续触发
{
Su16KeyContinuityCnt2++;
if(Su16KeyContinuityCnt2>=KEY_CONTINUITY_TIME)//每80ms触发一次
{
Su16KeyContinuityCnt2=0;
vGu8KeySec=2;//触发
vGu8ShiedVoiceFlag=1;//屏蔽按键触发的声音
}
}
}
void KeyTask()
{
if(0==vGu8KeySec)
{
return;
}
switch(vGu8KeySec)
{
case 1:
if(Gu8LedStatus>0)
{
Gu8LedStatus--;//跑马灯左跑
Gu8DisplayUpdata=1;//刷新显示
}
if(0==vGu8ShiedVoiceFlag)//没有屏蔽声音
{
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=KEY_VOICE_TIME;
vGu8BeepTimerFlag=1;
}
vGu8ShiedVoiceFlag=0;
vGu8KeySec=0;
break;
case 2:
if(Gu8LedStatus<7)
{
Gu8LedStatus++;
Gu8DisplayUpdata=1;
}
if(0==vGu8ShiedVoiceFlag)
{
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=KEY_VOICE_TIME;
vGu8BeepTimerFlag=1;
}
vGu8ShiedVoiceFlag=0;
vGu8KeySec=0;
break;
}
}
void main()
{
SystemInitial();
Delay(10000);
PeripheralInitial();
while(1)
{
KeyTask();
DisplayTask();//显示led任务函数
}
}
void T0_time() interrupt 1
{
VoiceScan();
KeyScan();
TH0=0xfc;
TL0=0x66;
}
(5)独立按键按住不松手的“先加速后匀速”的触发
功能:触发K1,自减1,最小值为0;触发K2,自加1,最大值800;单击一次蜂鸣器鸣叫一次,由单击进入连击蜂鸣器不鸣叫。
#include "reg52.h"
#define KEY_VOICE_TIME 50
#define KEY_SHORT_TIME 25//按键滤波的“稳定时间”25ms
#define KEY_ENTER_CONTINUITY_TIME 300//从单击到连击间隔时间
#define KEY_CONTINUITY_INITIAL_TIME 80//连击间隔时间
#define BUS_P1 P1//p1口连接8个led灯
#define KEY_SUB_DA_TIME 20//按键加速时每次减小的时间
#define KEY_CONTINUITY_MIN_TIME 5//加速之后匀速的间隔时间
sbit beep=P2^3;//蜂鸣器
sbit KEY_INPUT1=P3^4;//按键识别输入口
sbit KEY_INPUT2=P3^5;
volatile unsigned char vGu8BeepTimerFlag=0;
volatile unsigned int vGu16BeepTimerCnt=0;
unsigned int Gu16SetData=0;//"加速匀速的设置参数",0-800
unsigned char Gu8DisplayUpdata=1;//显示的刷新标志
volatile unsigned char vGu8KeySec=0;//按键的触发序号
volatile unsigned char vGu8ShiedVoiceFlag=0;//屏蔽声音标志
void SystemInitial()
{
TMOD=0x01;
TH0=0xfc;
TL0=0x66;
EA=1;
ET0=1;
TR0=1;
}
void Delay(unsigned long u32DelayTime)
{
for(;u32DelayTime>0;u32DelayTime--);
}
void PeripheralInitial()
{
}
void BeepOpen()
{
beep=0;
}
void BeepClose()
{
beep=1;
}
void VoiceScan()
{
static unsigned char Su8Lock=0;
if(1==vGu8BeepTimerFlag && vGu16BeepTimerCnt>0)
{
if(0==Su8Lock)
{
Su8Lock=1;
BeepOpen();
}
else
{
vGu16BeepTimerCnt--;
if(0==vGu16BeepTimerCnt)
{
Su8Lock=0;
BeepClose();
}
}
}
}
/*Gu8DisplayUpdata“显示刷新变量”在显示框架中很常见,目的是既能及时刷新显示,又能避免主函数
“不断执行显示代码”而影响程序效率*/
void DisplayTask()
{
if(1 == Gu8DisplayUpdata)//需要刷新一次
{
Gu8DisplayUpdata=0;
if(Gu16SetData<100)
{
BUS_P1=~(1<<0);
}
else if(Gu16SetData<200)
{
BUS_P1=~(1<<1);
}
else if(Gu16SetData<300)
{
BUS_P1=~(1<<2);
}
else if(Gu16SetData<400)
{
BUS_P1=~(1<<3);
}
else if(Gu16SetData<500)
{
BUS_P1=~(1<<4);
}
else if(Gu16SetData<600)
{
BUS_P1=~(1<<5);
}
else if(Gu16SetData<700)
{
BUS_P1=~(1<<6);
}
else
{
BUS_P1=~(1<<7);
}
}
}
void KeyScan()
{
static unsigned char Su8KeyLock1;
static unsigned int Su16KeyCnt1;
static unsigned int Su16KeyContinuityCnt1;
static unsigned int Su16KeyContinuityTime1=KEY_CONTINUITY_INITIAL_TIME;
static unsigned char Su8KeyLock2;
static unsigned int Su16KeyCnt2;
static unsigned int Su16KeyContinuityCnt2;
static unsigned int Su16KeyContinuityTime2=KEY_CONTINUITY_INITIAL_TIME;
if(0!=KEY_INPUT1)
{
Su8KeyLock1=0;
Su16KeyCnt1=0;
Su16KeyContinuityCnt1=0;
Su16KeyContinuityTime1=KEY_CONTINUITY_INITIAL_TIME;
}
else if(0 == Su8KeyLock1)
{
Su16KeyCnt1++;
if(Su16KeyCnt1>=KEY_SHORT_TIME)//按键滤波时间25ms
{
Su8KeyLock1=1;//自锁起来,按住不放进入连续触发检测
vGu8KeySec=1;//触发一次K1按键
Su16KeyCnt1=0;
}
}
else if(Su16KeyCnt1<=KEY_ENTER_CONTINUITY_TIME)
{
Su16KeyCnt1++;//第一次按下按键之后到连续触发的时间间隔300ms
}
else//按住300ms后任然不放手进入连续触发
{
Su16KeyContinuityCnt1++;
if(Su16KeyContinuityCnt1>=Su16KeyContinuityTime1)//自加或自减Su16KeyContinuityTime1进行加速
{
Su16KeyContinuityCnt1=0;
vGu8KeySec=1;//触发
vGu8ShiedVoiceFlag=1;//连续触发屏蔽按键触发的声音
if(Su16KeyContinuityTime1>=KEY_SUB_DA_TIME)
{
Su16KeyContinuityTime1=Su16KeyContinuityTime1-KEY_SUB_DA_TIME;//数值不断减小触发速度加快
}
if(Su16KeyContinuityTime1<KEY_CONTINUITY_MIN_TIME)//到达最小时间间隔时匀速
{
Su16KeyContinuityTime1=KEY_CONTINUITY_MIN_TIME;//匀速的时间间隔
}
}
}
if(0!=KEY_INPUT2)
{
Su8KeyLock2=0;
Su16KeyCnt2=0;
Su16KeyContinuityCnt2=0;
Su16KeyContinuityTime2=KEY_CONTINUITY_INITIAL_TIME;
}
else if(0 == Su8KeyLock2)
{
Su16KeyCnt2++;
if(Su16KeyCnt2>=KEY_SHORT_TIME)
{
Su8KeyLock2=1;//自锁起来,按住不放进入连续触发检测
vGu8KeySec=2;//触发一次K1按键
Su16KeyCnt2=0;
}
}
else if(Su16KeyCnt2<=KEY_ENTER_CONTINUITY_TIME)
{
Su16KeyCnt2++;//第一次按下按键之后到连续触发的时间间隔300ms
}
else//按住300ms后任然不放手进入连续触发
{
Su16KeyContinuityCnt2++;
if(Su16KeyContinuityCnt2>=Su16KeyContinuityTime2)//自加或自减Su16KeyContinuityTime1进行加速
{
Su16KeyContinuityCnt2=0;
vGu8KeySec=2;//触发
vGu8ShiedVoiceFlag=1;//连续触发屏蔽按键触发的声音
if(Su16KeyContinuityTime2>=KEY_SUB_DA_TIME)
{
Su16KeyContinuityTime2=Su16KeyContinuityTime2-KEY_SUB_DA_TIME;//数值不断减小触发速度加快
}
if(Su16KeyContinuityTime2<KEY_CONTINUITY_MIN_TIME)//到达最小时间间隔时匀速
{
Su16KeyContinuityTime2=KEY_CONTINUITY_MIN_TIME;//匀速的时间间隔
}
}
}
}
void KeyTask()
{
if(0==vGu8KeySec)
{
return;
}
switch(vGu8KeySec)
{
case 1://K1按键
if(Gu16SetData>0)
{
Gu16SetData--;//跑马灯左跑
Gu8DisplayUpdata=1;//刷新显示
}
if(0==vGu8ShiedVoiceFlag)//没有屏蔽声音
{
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=KEY_VOICE_TIME;
vGu8BeepTimerFlag=1;
}
vGu8ShiedVoiceFlag=0;
vGu8KeySec=0;
break;
case 2://K2按键
if(Gu16SetData<800)
{
Gu16SetData++;
Gu8DisplayUpdata=1;
}
if(0==vGu8ShiedVoiceFlag)
{
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=KEY_VOICE_TIME;
vGu8BeepTimerFlag=1;
}
vGu8ShiedVoiceFlag=0;
vGu8KeySec=0;
break;
}
}
void main()
{
SystemInitial();
Delay(10000);
PeripheralInitial();
while(1)
{
KeyTask();
DisplayTask();//显示led任务函数
}
}
void T0_time() interrupt 1
{
VoiceScan();
KeyScan();
TH0=0xfc;
TL0=0x66;
}