蓝桥杯单片机——按键的多样操作
按键扫描的底层代码
unsigned char Key_Read()
{unsigned char temp = 0;ET0 = 0;P44 = 0;P42 = 1;P35 = 1;P34 = 1;if(P33 == 0) temp = 4;if(P32 == 0) temp = 5;if(P31 == 0) temp = 6;if(P30 == 0) temp = 7;P44 = 1;P42 = 0;P35 = 1;P34 = 1;if(P33 == 0) temp = 8;if(P32 == 0) temp = 9;if(P31 == 0) temp = 10;if(P30 == 0) temp = 11;P44 = 1;P42 = 1;P35 = 0;P34 = 1;if(P33 == 0) temp = 12;if(P32 == 0) temp = 13;if(P31 == 0) temp = 14;if(P30 == 0) temp = 15;P44 = 1;P42 = 1;P35 = 1;P34 = 0;if(P33 == 0) temp = 16;if(P32 == 0) temp = 17;if(P31 == 0) temp = 18;if(P30 == 0) temp = 19;ET0 = 1;P3 = 0xff;return temp;
}
这种扫描方法是采用的逐列扫描的方式。需要注意的是串口用P30作为TX,P31作为RX,如果发生了冲突导致串口无法接收数据,可以再扫描按键时候关闭串口中断ES = 0;在使用NE555测量频率时,也会用到P34引脚,如果发生了冲突,也可以在扫描按键时关闭T0计数TR0 = 0。在扫描结束,即在函数末尾应该将关掉的重新打开。
按键的长按操作
void Key_Long_Pro()
{if(Key_Slow_Down) return;Key_Slow_Down = 1;Key_Val = Key_Read();Key_Down = Key_Val & (Key_Old ^ Key_Val);Key_Up = ~Key_Val & (Key_Old ^ Key_Val);Key_Old = Key_Val;if(Key_Down == 4){Long_Press_Flag = 1;}if(Key_Up == 4){if(time_2s >= 2000){Seg_Buf[0] = 1;}else{Seg_Buf[0] = 0;}time_2s = 0;Long_Press_Flag = 0;}if(Key_Down == 5){Long_Press_Flag = 1;}if(time_2s >= 2000){Seg_Buf[1] = 2;}if(Key_Up == 5){if(time_2s < 2000){Seg_Buf[1] = 3;}time_2s = 0;Long_Press_Flag = 0;}
}
void Timer0_Routine() interrupt 1
{if(Long_Press_Flag){if(++time_2s >= 2000){time_2s = 2001;}}
}
按键的多击操作
void Key_Again_Pro()
{if(Key_Slow_Down) return;Key_Slow_Down = 1;Key_Val = Key_Read();Key_Down = Key_Val & (Key_Old ^ Key_Val);Key_Up = ~Key_Val & (Key_Old ^ Key_Val);Key_Old = Key_Val;if(Key_Down == 4){Key_Click_Count++;Key_Click_Flag = 1;time_200ms = 0;}if(time_200ms >= 200){if(Key_Click_Count == 1){Seg_Buf[0] = 1;}else if(Key_Click_Count == 2){Seg_Buf[0] = 2;}time_200ms = 0;Key_Click_Count = 0;Key_Click_Flag = 0;}
}
void Timer0_Routine() interrupt 1
{if(Key_Click_Flag){if(++time_200ms >= 200){time_200ms = 201;}}
}