从单片机基础到程序框架(全集 2019pdf版) - 第546页
void BeepO pen(void) { P3_4=0; } void BeepC lose(void ) { P3_4=1; } void Voice Scan(void ) { static u nsigned cha r Su8Lock= 0; if(1==vGu8 BeepTimer Flag&&vGu16B eepTimerC nt>0) { if(0==Su 8Lock) { Su8Lock=1; …

}
vGu8ShieldVoiceFlag=0; //及时把屏蔽标志清零,避免平时正常的单击声音也被淹没。
vGu8KeySec=0; //响应按键服务处理程序后,按键编号必须清零,避免一致触发
break;
default:
vGu8KeySec=0;
break;
}
}
void T0_time() interrupt 1
{
VoiceScan();
KeyScan();
TH0=0xfc;
TL0=0x66;
}
void SystemInitial(void)
{
TMOD=0x01;
TH0=0xfc;
TL0=0x66;
EA=1;
ET0=1;
TR0=1;
}
void Delay(unsigned long u32DelayTime)
{
for(;u32DelayTime>0;u32DelayTime--);
}
void PeripheralInitial(void)
{
}

void BeepOpen(void)
{
P3_4=0;
}
void BeepClose(void)
{
P3_4=1;
}
void VoiceScan(void)
{
static unsigned char Su8Lock=0;
if(1==vGu8BeepTimerFlag&&vGu16BeepTimerCnt>0)
{
if(0==Su8Lock)
{
Su8Lock=1;
BeepOpen();
}
else
{
vGu16BeepTimerCnt--;
if(0==vGu16BeepTimerCnt)
{
Su8Lock=0;
BeepClose();
}
}
}
}

第一百零七节: 开关感应器的识别与软件滤波。
【107.1 开关感应器的识别与软件滤波。】
上图 107.1.1 独立按键模拟开关感应器
上图 107.1.2 LED 电路
什么叫开关感应器?凡是只能输出 0 和 1 这两种状态的感应器都可以统称为开关感应器。前面花了大量
的章节讲按键,按键的识别主要是识别电平变化状态的“下降沿”,程序代码中有 1 个特别的变量标志叫“自
锁标志”,还有 1 个用来消除抖动的“计时器”。本节讲的开关感应器跟按键很相似,差别在于,开关感应器
是识别电平变化状态的“电平”,程序代码中没有“自锁标志”,但是多增加了 1 个用来消除抖动的“计时器”,
也就是一共有两个用来消除抖动的“计时器”,这两个“计时器”相互“清零”相互“抗衡”,从而实现了开
关感应器的“消抖”处理,专业术语也叫“软件滤波”。消抖的时间跟按键差不多,我的经验值是 20ms 到 30ms
之间,我平时在项目中喜欢用 20ms。
在显示框架方面,除了之前讲过 Gu8DisplayUpdate 这类“显示刷新变量”,本节介绍另外一种常用的显
示框架,原理是“某数值跟上一次对比,如果发生了变化(两数值不一样),则自动刷新显示,并及时记录当
前值”。
本节例程实现的功能如下:用 K1 独立按键模拟开关感应器,K1 独立按键“没有被按下”时是高电平,
单片机识别到这种“高电平”,就让 P1.4 所在的 LED 灯发亮;K1 独立按键“被按下”时是低电平,单片机识
别到这种“低电平”,就让 P1.4 所在的 LED 灯熄灭。
#include "REG52.H"