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

上图 10 2.1.3 3*3 矩阵按键的 电路 “任意 行输入”是指 能兼容“异行 输入”与 “同行输入” 这两种按键 状态。 何谓 “异行输入 ” 何谓 “同行输入” ?如上图矩阵按 键, P2.2, P2.1, P2.0 是输 入行, P2.5, P2.4, P2.3 是输出列。 以 S 1 按键为 例,很明显 ,S2 和 S3 都是属于 S 1 的“同行输入” ,都是属于 P2.2 的输入行。除了 S2 和 S3 以外,其它 所…

100%1 / 836
第一百零二节: 两个“任意行输入”矩阵按键的“有序”组合触发。
【102.1 “异行输入”“同行输入”“有序”
上图 102.1.1 有源蜂鸣器电路
上图 102.1.2 LED 电路
上图 102.1.3 3*3 矩阵按键的电路
“任意行输入”是指能兼容“异行输入”与“同行输入”这两种按键状态。
何谓“异行输入何谓“同行输入”?如上图矩阵按键,P2.2,P2.1,P2.0 是输入行,P2.5,P2.4,P2.3
是输出列。 S1 按键为例,很明显,S2 S3 都是属于 S1 的“同行输入”,都是属于 P2.2 的输入行。除了
S2 S3 以外,其它所有的按键都是 S1 的“异行输入”,比如 S5 按键就是 S1 的“异行输入”,因为 S1 是属
P2.2 的输入行, S5 是属于 P2.1 的输入行。
何谓“有序”组合触发?就是两个按键的触发必须遵守“先后顺序”才能构成“组合触发”。比如,像
电脑的复制快捷键(Ctrl+C)你必须先按 Ctrl 按住 C 此时“复制快捷键才有效,如果你先按住 C
按住 Ctrl 此时“复制快捷键”无效。
“异行输入”与“同行输入,相比之下“同行输入”更难更有代表性,如果把“同行输入”的程序写
出来了,那么完全按“同行输入”的思路,就可以把“异行输入”的程序写出来因此只要同行输入
的程序写出来了,也就意味着“任意行输入的程序也就实现了。本节 S1 S2 “同行输入”按键为例,
S1 是主键,类似复制快捷键的 Ctrl ;S2 是从键,类似复制快捷键的 C 要触发组合键(S1+S2)必须
先按 S1 再按 S2 才有效。功能如下:(1)S1 每单击一次,LED 要么从“灭”变成“亮”要么从“亮”变
“灭在两种状态之间切换。(2)如果先按住 S1 再按 S2就认为构造了“有序组合键,蜂鸣器发出“嘀”
的一声。
#include "REG52.H"
#define KEY_VOICE_TIME 50
#define KEY_SHORT_TIME 20
void T0_time();
void SystemInitial(void) ;
void Delay(unsigned long u32DelayTime) ;
void PeripheralInitial(void) ;
void BeepOpen(void);
void BeepClose(void);
void LedOpen(void);
void LedClose(void);
void VoiceScan(void);
void KeyScan(void);
void SingleKeyTask(void);
void DoubleKeyTask(void);
sbit P3_4=P3^4;
sbit P1_4=P1^4;
sbit ROW_INPUT1=P2^2; //第 1 行输入口。
sbit ROW_INPUT2=P2^1; //第 2 行输入口。
sbit ROW_INPUT3=P2^0; //第 3 行输入口。
sbit COLUMN_OUTPUT1=P2^5; //第 1 列输出口。
sbit COLUMN_OUTPUT2=P2^4; //第 2 列输出口。
sbit COLUMN_OUTPUT3=P2^3; //第 3 列输出口。
volatile unsigned char vGu8BeepTimerFlag=0;
volatile unsigned int vGu16BeepTimerCnt=0;
unsigned char Gu8LedStatus=0;
volatile unsigned char vGu8SingleKeySec=0;
volatile unsigned char vGu8DoubleKeySec=0;
void main()
{
SystemInitial();
Delay(10000);
PeripheralInitial();
while(1)
{
SingleKeyTask();
DoubleKeyTask();
}
}
/* 注释一:
* 两个“任意行输入”矩阵按键“有序”触发的两个最关键地方:
* (1)当 S1 按键被按下单击触发之后, “马上更新输出列的信号状态”,然后切换到后面的步骤。
* (2)在后面的步骤里,进入到 S1 S2 两个按键的轮番循环监控之中,如果发现 S1 按键率先
* 被松开了,就把步骤切换到开始的第一步,重新开始新一轮的按键扫描。
* (3)按照这个模板,只需“更改不同的列输出,判断不同的行输入,就可以实现“任意行输入
* 矩阵按键的“有序”组合触发。
*/
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: