首先分析单片机的按键默认是什么电平,按键按下是什么电平
笔者的单片机默认是高电平,按下为低电平
#define KB1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#define KB2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)
#define KB3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)
#define KB4 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2)
//端口状态
#define KEYPORT KB1 | (KB2<<1) | (KB3<<2) | (KB4<<3) | 0xf0
unsigned char Trg; //按键触发
unsigned char Cont;//按键长按
//三行按键核心代码
void Key_Read( void )
{
unsigned char ReadData = ~(KEYPORT); // 1. Read KEYPORT ^(xor) 在这里就是取反
Trg = ReadData & (ReadData ^ Cont); // 2
Cont = ReadData; // 3
}
int main(void)
{
while(1) //假设:循环用定时器10ms跑一次
{
Key_Read();
if(Trg==0x01) //B1按下
{
//下边写了对B1的长短按,所以这边可以删去执行代码
}
else if(Trg==0x02) //B2按下
{
lcd_number+=2;
}
else if(Trg==0x04) //B3按下
{
lcd_number+=3;
}
else if(Trg==0x08) //B4按下
{
lcd_number+=4;
}
if(Cont==0x01) //B1长按检测,开始计算按下时间
{
key1_time++;
}
if(Trg==0x00 && Cont==0x00) //按键松手检测
{
if(key1_time> 0 && key1_time<50) //B1短按
{
lcd_number++;
}
else if (key1_time >= 50) //B1长按
{
lcd_number+=10;
}
key1_time = 0;
key1_release = 1;
}
}
}
首先,按键IO口默认接高电平,按下按键后进入低电平
(1)默认的时候,KB1=KB2=KB3=KB4=1
KEYPORT = 1|1<<1|1<<2|1<<3|0XF0 = 0xFF;
ReadData = KEYPORT^0XFF = 0XFF^0XFF=0x00;
Trg = ReadData & (ReadData ^ Cont) = 0x00 & (0x00 ^ Cont) = 0 ∵与上后边不管什么值都为0
Cont = ReadData = 0x00;
也就是说,默认状态 三个值都为0
(2)有某个按键按下后:
KEYPORT:{KB1: 0xfe KB2: 0xfd KB3: 0xfb KB4: 0xf7}
ReadData = KEYPORT^OXFF ={0x01, 0x02, 0x04, 0x08}
1)以KB1短按为例
ReadData = 0xfe^0xff = 0x01;
Trg = ReadData & (ReadData ^ Cont) = 0x01 & (0x01 ^ Cont) = 0x01;
Cont = ReadData = 0x01;
1)以KB2短按为例
ReadData = 0xfd^0xff = 0x02;
Trg = 0x02 & (0x02 ^ 0x00) = 0x02;
Cont = ReadData = 0x02;
1)KB1长按
//先会执行这个状态Trg会变成0x01
ReadData = 0xfe^0xff = 0x01;
Trg = ReadData & (ReadData ^ Cont) = 0x01 & (0x01 ^ Cont) = 0x01;
Cont = ReadData = 0x01;
2)连续按下,所以再次计算执行三行程序,唯一不同的是Cont = 0x01
ReadData = 0x01;
Trg = 0x01 & (0x01 ^ 0x01) = 0x00;
Cont = 0x01;
3)如果按键还没有释放,再次扫描到这三行程序,计算得出依旧是:
ReadData = 0x01;
Trg = 0x00;
Cont = 0x01;
4)如果按键松开了
ReadData = KEYPORT^0XFF = 0XFF^0XFF=0x00;
Trg = ReadData & (ReadData ^ Cont) = 0x00 & (任何东西) = 0x00;
Cont = ReadData = 0x00;