51单片机学习日志-11
之前的实验中,我们通过使用按键输入信号到单片机中,再通过单片机输出信号控制数码管,实现了单片机输入与输出的结合,而且对于单片机控制多个数码管的情况也进行了一些探究,最终确定了使用动态扫描的方法来实现对数码管的控制。对于多个输出控制对象来说可以使用动态扫描的方法,而对于多个输入设备是不是也可以通过动态扫描的方法进行呢,所以这里就设置了一种情况,需要单片机接收16个按键的信号,而且每个按键的信号都要实现独立的功能,这时候一般的想法就是有多少个按键,就使用多少个端口进行信号的接收,但是如果是16个端口的话,那就会占用非常多的端口数量,所以需要通过一些其他的方法来进行处理,下面就来介绍一下所使用的这种方法。
这是电路连接图,可以看到一共有16个按键,其中被分为四行四列,每一列的按键的左端连接在同一条线路上,这一条线路连接在单片机的一个引脚上,其作用是为了对按键进行列选择,而每一行按键的右端连接在同一条线路上,而这一条线路连接在单片机的一个引脚上,用来进行对每列按键的再选择。所以通过这个按键的连线可以看到,其实逻辑就是,先通过第一种线路进行列按键的选择,而其他列的按键暂时不用进行检测,然后通过这一列对应的端口输入,从而判断到底是哪一个按键被按下,这样如果这一列有按键按下,就可以知道到底是哪一个按键按下,之后再对其他列的按键进行检测,同样可以知道这一列有没有按下的按键,这样循环一次就知道是不是有按键被按下,而且还知道是哪一个按键被按下,再通过被按下的按键来决定到顶需要进行怎样的处理。
首先依旧是需要对所使用到的端口进行配置,其中用来控制按键选择的端口配置位输出模式,检测按键位置的端口配置为输入模式,而控制发光二极管的端口配置为输出模式(这里输入选择了第一种准双向模式,所以需要对端口设置为高电平,才能进行输入),同时这里设置了一个变量,用来表示此时按下的按钮是哪一个,之后将这个变量赋值为255,就进入大循环了(256是2的8次方,也就是说如果转化为二进制数的话,前7位都是1)。在大循环中,显示用一个函数检测按键的输入,并把按键的编码输出,进行按键的检测后,再进行信号的输出,这里同样用到了一个函数进行信号的输出。这样大循环就结束了,但是由于这里用到的两个函数很重要,所以要对这两个函数进行讲解。
首先要注意的是,这里对端口配置寄存器的定义被放在了另一个头文件中了,而这个头文件同时还包含了其他的定义,以及函数的定义,下面一起来看一下。
这个头文件最开始还是一些端口配置寄存器的定义,然后是一个数组,这个数组的作用是用来对发光二极管的状态进行分配的,也就是说通过数组的下标就可以控制发光二极管的输出状态了,例如对于下标为零的数组元素,就是所有的发光二极管都不点亮,而对于下标为一的数组元素,只有最低位的那个发光二极管点亮,这样就可以通过控制下标,来对端口寄存器进行赋值,从而控制发光二极管的发光状态。接下来就是延时函数的定义,这个以前说过。再来就是检测按键函数,这个是要重点讲解的。在这个函数中,先是定义了两个变量,其中一个变量用来存储按键的编号,另一个用来存储端口输入状态。首先将按键编号设置为225,这是在没有按键按下的情况下的取值,也是最初的取值。之后先对端口进行电平设置,这一步其一是为了对列按键进行选择,还有就是为后续的输入做准备,然后再用变量读出端口值,这里其实就可以判断是哪个按钮了,但是有高四位的干扰,所以需要将高四位进行去除,之后再进行选择,这样就可以得到具体的按键编号了。之后再检测第二列、第三列以及第四列的按键有没有被按下,最后再返回按键编号。所以说这个函数就是对按键进行一次扫描,如果在这次扫描中,有按键按下了,那么就说明返回值不是255,而是一个具体值,这其实和之前一个按键有一点相似,一个按键的情况就是如果按下了就是低电平,不然就是高电平。最后是点亮发光二极管的函数,这里是输入需要表示的数字,也就是按键的编码,其中有检测到的话就输出对应的变化,而这里的变化由前面的数组来定义。以下是具体代码。










浙公网安备 33010602011771号