蓝桥杯这块板子有矩阵按键和独立按键,可以根据换跳帽来切换,下面简单介绍一下这两种按键的程序和基本的原理。
其他51的板子原理也基本相同,下面的代码也可以参考。
独立按键
相对于矩阵按键,独立按键简单很多,就只有四个按钮,判断四个按键哪个被按下的情况较为简单
独立按键的写法也不止一种,这里就介绍两种
方法一:
实现比较简单,就是一个个判断,检测到为低电平的话就判断按键按下了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| sbit S7 = P3^0; sbit S6 = P3^1; sbit S5 = P3^2; sbit S4 = P3^3;
void key_scan() { if(S4 == 0) { delay(5); if(S4 == 0) { } } else if(S5 == 0) { delay(5); if(S5 == 0) { } } else if(S6 == 0) { delay(5); if(S6 == 0) { } } else if(S7 == 0) { delay(5); if(S7 == 0) { } } }
|
方法二:
检测P3口的低四位,若S4被按下,则第四位P3^3为0,所以P3&0xf的值为0x07,其他三个按键也以此类推。这种方法把按键的检测程序和功能程序分开了,如果不想要按下按键后按键里面的功能一直执行的话,按键功能每次执行完要把按键的值归零,否则单片机会一直执行那个按键里面的功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| char press_flag = 0,key_value = 0;
void key_scan() { if((P3&0x0f) != 0x0f&&!press_flag) { delay(50); if((P3&0x0f) != 0x0f&&!press_flag) { press_flag = 1; switch(P3&0x0f) { case 0x07: key_value = 4; break; case 0x0b: key_value = 5; break; case 0x0d: key_value = 6; break; case 0x0e: key_value = 7; break; } } } if((P3&0x0f) == 0x0f&&press_flag) press_flag = 0; }
void key_func() { switch(key_value) { case 4: key_value = 0; break; case 5: key_value = 0; break; case 6: key_value = 0; break; case 7: key_value = 0; break; } }
|
矩阵按键
相对于独立按键来说,矩阵按键相对是要复杂一点,这里就介绍一种方法
原理:
这个方法和上面独立按键的方法2实现的思路差不多。因为51单片机的资源很有限,所以这里用了八个引脚来实现一个4×4的矩阵按键。这里对照一下原理图:
第一步:列扫描,先将P3的低四位置为0,高四位置为1,但是这款单片机的P36和P37被P42和P44代替了,所以P42和P44要单独位定义,然后将其置为1。初始值设置完之后就要进行检测了,因为P3的低四位为0,所以当按键按下时接到对应列的那条线会被拉到低电平P44对应的是第一列,其他参照上面的原理图以此类推。
第二部:行扫描,反过来,将P3的低四位置为1,高两位以及P42和P44置为0,哪一行的按键被按下对应行的值会被置为0,这一步和上面独立按键的扫描相似。
经过行和列的扫描就可以确定下来是那个一个按键被按下了,行和列就可以看成是横坐标和纵坐标,这里是先确定纵坐标,再确定横坐标,通过这样的一个坐标就可以确定被按下按键的位置。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| sfr P3 = 0xc0; sbit P42 = P4^2; sbit P44 = P4^4; sbit P34 = P3^4; sbit P35 = P3^5; char key_value = 0,key_past = 0,key_now = 0;
void key_scan() { P3 = 0xf0; P42 = 1; P44 = 1; if(P42 != 1||P44 != 1||P34 != 1||P35 != 1) { key_past = key_now; key_now = 1; if(!(key_past == 1&&key_now == 1)) delay(5); if((P42 != 1||P44 != 1||P34 != 1||P35 != 1)&&!(key_past == 1&&key_now == 1)) { if(P44 == 0) key_value = 4; else if(P42 == 0) key_value = 8; else if(P35 == 0) key_value = 12; else if(P34 == 0) key_value = 16; P3 = 0x0f; P42 = 0; P44 = 0; switch(P3&0x0f) { case 0x07: key_value += 0; break; case 0x0b: key_value += 1; break; case 0x0d: key_value += 2; break; case 0x0e: key_value += 3; break; } } } else { key_past = key_now; key_now = 0; } }
|
这里没有写按键的功能函数,这个就和独立按键的第二种方法类似,传入key_value的值然后执行对应的功能函数,执行完一次之后如果不想要一直执行的话就在执行完之前将key_value的值归零。