![9f5930f66883fdab81bcc466aca9c0aa.gif](https://i-blog.csdnimg.cn/blog_migrate/4db00c3fb5c486d9a37276b495ba0419.gif)
![5b3f080dc1724548a4d70e633d38c21b.png](https://i-blog.csdnimg.cn/blog_migrate/a49284a88d4bcf405354bfc45a018e3b.jpeg)
这是 北航士谔书院 的第 925 篇推送
首先在此向全国人民谢罪:
昨天推送中介绍的利用STC-ISP软件生成延时函数的方法之中往往要用到_nop_()函数,这个函数包含在头文件中。
今天我们一起来探索独立按键以及矩阵键盘的使用。(基于STC15F2K60S.h头文件)
今天的主要内容有:
1.对于电位更简单的处理方法
十六进制
2.独立按键
抖动的处理
delay滤波
3.操作方案
松手执行
按下执行
4.矩阵键盘
“两列失效”的处理
通过电路图解决
1.电位的简易处理
我们以昨天介绍的LED模块的引脚为例,P0系列共有8个引脚,每个引脚有1、0两种状态,若是仅仅点亮LED2,3,那么写成二进制就是(1001 1111)2(从P00->P07)。
实际中,我们从高位写向低位并且写成16进制,上例应写为 P0 = 0xF9;
void main(void)
{
setup();
P0 = 0xF9;
while(1);
}
依据这个原理,我们可以简化流水灯的写法,关键代码如下:
val = 0x01;
while(1)
{
int i;
for(i=0;i<8;i++)
{
P0 = val<
P0 = ~P0;
delay();
}
}
2.独立按键
在开始之前请确认J5跳线在BTN上。独立按键在最左一列,也就是S4-S7
![b7487fbeb00eb6c133ddc8a2828d03b4.png](https://i-blog.csdnimg.cn/blog_migrate/9a615077b3bbfad6975e3fd9741ffa08.png)
我们可以比较明显的看出分别对应P30-P33,在跳线之后,左侧已经接地,所以如果我们检测到P30-P33为“0”,那么我们可以确定,对应按键已经按下。我们借用这个原理,写一个测试程序,如果按下Button(i) 那么点亮LED(i)。
当关键代码如下时,我们会发现LED的亮度很不稳定,因为没有任何的延时,这样的话,LED的亮度不稳定代表了LED的亮灭频率不稳定。最后可以归结为键按下的过程中键帽与下方的电极接触不稳定。我们可以通过很粗暴的滤波解决这个问题。
while(1)
{
if(P30==0) P00 = 0;
if(P31==0) P01 = 0;
if(P32==0) P02 = 0;
if(P33==0) P03 = 0;
//delay();
P0 = 0xFF;
}
只需要跳过那部分不稳定的波形就好了,大概5-10ms
int jud
int check()
{
if(P30==0)
{
delay();//5ms
if(P30==0)
return 1;
}
else return 0;
}
void main()
{
setup();
while(1)
{
jud = check();
if(jud)
{
P00 = 0;
jud = 0;
}
else P00 = 1;
}
}
按下执行如上所述,下面介绍抬起执行,即P3i回复为1时执行语句仅一次,防止多次执行
int check()
{
if(P30==0)
{
delay();
if(P30==0)
while(!P30)
return 1;
}
else return 0;
}
3.矩阵键盘
![cc3efd7d38e848e76a9e4971b49fc6c1.png](https://i-blog.csdnimg.cn/blog_migrate/441ce12bca4c40351de2ccf7994475d1.png)
![051acc941f0d46e55cd7c164018eb9c9.png](https://i-blog.csdnimg.cn/blog_migrate/effdf146e23f82879bafbc795eae6fd5.jpeg)
我们对比这两张(平台矩阵键盘部分的电路以及15转接板的电路(STC15F2K60S2))可以发现矩阵键盘模块所需要的WR以及RD脚并非P36P37而是P42P44,这个会影响我们之后的工作(一会谈)
注意跳线到KBD!
我们基本按照独立键盘的方法进行编码,只不过进行矩阵的“扫描”,(逐列进行)
对于第一列,需要先行建立一个0电平(在左侧),当接通按键时,另一侧从正变成零电平,可以通过这种变化确定某一列的某个按键被按下了。
第一列如下
P3 = 0x7F;//0111 1111 其实这里第一位的“0”并不是电平 只是为了区分不同的case
P44 = 0;//这才是真正的0电平
temp = P3;
temp = temp & 0x0F;
if(temp!=0x0f)
{
Delay5ms();//延时滤波
temp = P3;//0111 1111
temp = temp & 0x0F;
if(temp!=0x0f)
{
temp = P3;
switch(P3)
{
case 0x7E:
P0 = 0x00;break;
case 0x7D:
P0 = 0x00 + 1;break;
case 0x7B:
P0 = 0x00 + 1 + 2;break;
case 0x77:
P0 = 0x00 + 1 + 2 + 4;break;
}
}
}
第二列如下
P3 = 0xBF;//发送值改变
P42 = 0;
temp = P3;
temp = temp & 0x0F;
if(temp!=0x0f)
{
Delay5ms();
temp = P3;//0111 1111
temp = temp & 0x0F;
if(temp!=0x0f)
{
temp = P3;
switch(P3)//观察case和第一列有什么区别
{
case 0xBE:
P0 = 0x00;break;
case 0xBD:
P0 = 0x00 + 2;break;
case 0xBB:
P0 = 0x00 + 2 + 2*2;break;
case 0xB7:
P0 = 0x00 + 2 + 4 + 2*4;break;
}
}
}
case的不同源自于发送的P3的信号的不同,虽然前两位没有改变电平,但是却起到了区分情况的作用,大家不妨试试将一二列发送信号都改为11开头,(有惊喜)
此外,矩阵键盘的三四列除了不使用P4外相同,按键抬起防止多次执行与独立按键基本一致,不再赘述~
Tips:
如果您选择使用reg52.h 请声明以下代码:
#include
sfr P4=0xc0;
sbit P42=P4^2;
sbit P44=P4^4;//其实这就是把和15头文件不一样的地方加上了:)
图文|范云潜
编辑|尹辰昕
出品|士谔书院X大班
![f88ac3ba6707053940cb78c2c8ae329e.png](https://i-blog.csdnimg.cn/blog_migrate/8f5ce29c138b127f7af61b06d2d85c2c.jpeg)