热度 3|
以下是从网路上获取的新型按键扫描的代码.
源程序主要部分如下:
volatile unsigned char Trg;
volatile unsigned char Cont;
volatile unsigned char Release;
void KeyRead( void )
{
unsigned char ReadData = (~PINB)^0xff; // 1 读键值
Trg = ReadData & (ReadData ^ Cont); // 2 得到按下触发值
Release= (ReadData ^ Trg ^ Cont); // 3 得到释放触发值
Cont = ReadData; // 4 得到所有未释放的键值
}
volatile unsigned char Trg;
volatile unsigned char Cont;
volatile unsigned char Release;
void KeyRead( void )
{
unsigned char ReadData = PINB^0xff; // 1 读键值
Trg = ReadData & (ReadData ^ Cont); // 2 得到按下触发值
Release= (ReadData ^ Trg ^ Cont); // 3 得到释放触发值
Cont = ReadData; // 4 得到所有未释放的键值
}
首先感觉程序的逻辑可以优化一下,因此就自作主张用了数字电路上逻辑优化方法
void KeyRead( void )
{
unsigned char ReadData = (~PINB)&0xff; // 1 读键值
Trg = (~Cont) & ReadData; // 2 得到按下触发值
Release= Cont &(~ReadData); // 3 得到释放触发值
Cont = ReadData; // 4 得到所有未释放的键值
}
刚开始看的时候,对红色部分的说明不太明白,不知道为什么可以直接优化成上面的代码。
后来自己琢磨了一下,原来是使用了逻辑运算优化出来的。
Trg = ReadData & (ReadData ^ Cont);
ReadData & (ReadData ^ Cont)= ReadData &((~ReadData )& Cont + ReadData &(~Cont))
= ReadData & (~Cont)
所以Trg = ReadData &(~Cont);
Release= (ReadData ^ Trg ^ Cont);同理可得Release= Cont &(~ReadData);
反来想一下,那从真值表可不可以获取到以上的公式,答案是肯定的。
ReadData | Cont | Trg | Release |
0 | 0 | 0 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 0 |
0 | 1 | 0 | 1 |
0 | 0 | 0 | 0 |
从真值表可以得出Trg = ReadData &(~Cont);
Release= Cont &(~ReadData);
这样使用真值表就可以轻松的得到按键的扫描程序了,同理其他的一些算法也可以从真值表轻松的获取,节省了很多工夫。
有人会问道,这个程序缺少了防抖动的措施。确实是少了这部分的代码,其实防抖动的一样可以通过真值表来获取,这个本人已经验证过,只是算法就相对于现在的复杂一些。后续的会增加这部分的真值表。