从单片机基础到程序框架(全集 2019pdf版).pdf - 第457页
} 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; BeepOpen (); } else { vGu16Bee …

}
vGu8ShieldVoiceFlag=0; //及时把屏蔽标志清零,避免平时正常的单击声音也被淹没。
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();
}
}
}
}

第九十九节: “行列扫描式”矩阵按键的单个触发(原始版)。
【99.1 “行列扫描式”矩阵按键。】
上图 99.1.1 有源蜂鸣器电路
上图 99.1.2 3*3 矩阵按键的电路
上图是 3*3 的矩阵按键电路,其它 4*4 或者 8*8 的矩阵电路原理是一样的,编程思路也是一样的。相对
独立按键,矩阵按键因为采用动态行列扫描的方式,能更加节省 IO 口,比如 3*3 的 3 行 3 列,1 行占用 1
根 IO 口,1 列占用 1 根 IO 口,因此 3*3 矩阵按键占用 6 个 IO 口(3+3=6),但是能识别 9 个按键(3*3=9)。
同理,8*8 矩阵按键占用 16 个 IO 口(8+8=16),但是能识别 64 个按键(8*8=64)。
矩阵按键的编程原理。如上图 3*3 矩阵按键的电路,行 IO 口(P2.2,P2.1,P2.0)定为输入,列 IO 口
(P2.5,P2.4,P2.3)定为输出。同一时刻,列输出的 3 个 IO 口只能有 1 根是输出 L(低电平),其它 2 根
必须全是 H(高电平),然后依次轮番切换输出状态,列输出每切换一次,就分别读取一次行输入的 3 个 IO
口,这样一次就能识别到 3 个按键的状态,如果列连续切换 3 次就可以读取全部 9 个按键的状态。列的 3 种
输出状态分别是:(P2.5 为 L,P2.4 为 H,P2.3 为 H),(P2.5 为 H,P2.4 为 L,P2.3 为 H),(P2.5 为 H,
P2.4 为 H,P2.3 为 L)。为什么列输出每切换一次就能识别到 3 个按键的状态?因为,首先要明白一个前提,
在没有任何按键“被按下”的时候,行输入的 3 个 IO 口因为内部上拉电阻的作用,默认状态都是 H 电平。
并且,H 与 H 相互短接输出为 H,H 与 L 相互短接输出 L,也就是,L(低电平)的优先级最大,任何 H(高电
平)碰到 L(低电平)输出的结果都是 L(低电平)。L(低电平)就像数学乘法运算里的数字 0,任何数跟 0
相乘必然等于 0。多说一句,这个“L 最高优先级”法则是有前提的,就是 H(高电平)的产生必须是纯粹靠