假设PB6、7、4 三个端口:
按下为低电平(0)、否则为高电平(1)。
void ReadKey(void)
{
//1.获取GPIB->IDR寄存器值(获取键值)
u16 ReadData = (GPIO_InputData( GPIOB ) & 0xD0) ^ 0xD0;
//2.判断哪一位发生改变(按键按下)
Trg = ReadData & (ReadData ^ cont);
//3.在按键按下后,哪一位发生改变(按键松开)
Rel = ReadData ^ Trg ^ cont;
//4.按键按下没有发生改变(长按) – 保存上一次 获取的按键值
cont = ReadData;
}
解析:
按键使用时,分为四种状态:
未按下
按下(短按)
长按
松开
在以上4总状态下,解析ReadKey()函数。
注意:
容易迷惑的地方在于 GPIO_InputDta()函数获取的值应该为多少
由于知道 PB6、7、4 默认状态为1,按下为0 则获取的IDR 寄存器值为
1101 0000(0xD0)
&/^ 两种逻辑运算符需要知道。
&: 0 & 1 = 0 ( 真 与 假 = 假)
^: 0 ^ 1 = 1 1 ^ 1 = 0 ( 相同为0,不同为1)
按键未被按下
ReadData = (GPIO_InputData( GPIOB ){ 0xD0 默认值} & 0xD0) ^ 0xD0 = 0x00;
Trg = ReadData & (ReadData ^ cont) = 0x00 & (0x00 ^ 0x00) = 0x00;
Rel = ReadData ^ Trg ^ cont = 0x00 ^ 0x00 ^ 0x00 = 0x00;
cont = ReadData = 0x00;
按键被按下(短按)
//这里GPIO_InputData 获取的是PB6 bit位为0 0x90
ReadData = (GPIO_InputData( GPIOB ){ 0x90 默认值} & 0xD0) ^ 0xD0 = 0x40;
Trg = ReadData & (ReadData ^ cont) = 0x40 & (0x40 ^ 0x00) = 0x40;
Rel = ReadData ^ Trg ^ cont = 0x40 ^ 0x40 ^ 0x00 = 0x00;
cont = ReadData = 0x40;
按键没有松开(长按)
//这里GPIO_InputData 获取的是PB6 bit位为0 则为0x90
ReadData = (GPIO_InputData( GPIOB ){ 0x90 默认值} & 0xD0) ^ 0xD0 = 0x40;
Trg = ReadData & (ReadData ^ cont) = 0x40 & (0x40 ^ 0x40) = 0x00;
Rel = ReadData ^ Trg ^ cont = 0x40 ^ 0x00 ^ 0x40 = 0x00;
cont = ReadData = 0x40;
按键松开(释放)
//这里GPIO_InputData 获取的是PB6 bit位为1 则为0xD0
ReadData = (GPIO_InputData( GPIOB ){ 0xD0 默认值} & 0xD0) ^ 0xD0 = 0x00;
Trg = ReadData & (ReadData ^ cont) = 0x00 & (0x00 ^ 0x40) = 0x00;
Rel = ReadData ^ Trg ^ cont = 0x00 ^ 0x00 ^ 0x40 = 0x40;
cont = ReadData = 0x00;
总结:
根据4种按键状态,trg、rel、cont 三个参数都会发生改变。并且在不同的状态,这三个参数改变的也不同。
Trg:决定了IDR寄存器中哪一位发生了改变 即:按键按下
Rel:决定了在改变过后,哪一位再次发生变化 即:松开标志位
Cont:保存上一次对应IO 的状态,当第二次程序运行函数时,使上一次和这一次进行对比,如果没改变对应标志 不变。发生改变(即保存上一次的ReadData) 也发生改变。即:按键长按标志。
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』