《蓝桥杯CT107D单片机竞赛板》:矩阵键盘模块
Posted 是七喜呀!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《蓝桥杯CT107D单片机竞赛板》:矩阵键盘模块相关的知识,希望对你有一定的参考价值。
矩阵键盘模块
实验简介
CT107D单片机开发板上的矩阵键盘控制, 指示灯亮灭,数码管显示按键值
实验原理图
实验原理
-
器件介绍:见独立按键模块,一个独立按键需要一个I/O口,如我们实现多按键控制功能的项目,如果仅使用独立按键,单片机的I/O口一定是不够的,为了
减少I/O
引脚使用数量
,就在单片机上引入
了矩阵键盘
。根据上面的原理图,4 * 4的独立按键,每一行有4个独立按键的一端连接,每一列有对应的独立按键的另外一端连接,共使用了8个I/O口(如果使用独立按键则需要16个I/O口,的确大大减少了I/O口使用数量!),采用矩阵键盘的行列扫描法,在能够实现独立按键功能的基础上,还能扩展其特有的功能。 -
基本原理:与独立按键一样,我们仍然采用软件消抖,具体操作为,先设置按键IO口输入为高电平,读取IO口是否有按键被按下(即有低电平出现),使用软件
延时函数10ms
,再次检测IO口是否仍为低电平,若是,则有按键被按下,进而继续下面的按键程序。 -
行列扫描法:我们先使得列对应的管脚P34,P35,P42,P44送入低电平(0),而行对应的管脚P30,P31,P32,P33送入高电平(1),每当我们按下矩阵按键上的一个键时,我们就能确定一行,例如下图中我们按下S12这个键,此时我们可以确定它所在的行为第4行(因为与其同行的其他三个按键按下也能检测到低电平),再使得列为高电平时,行为低电平,则能够确定其列数为第3列,故我们可知该键为S12, 同理我们能够检测其他按键。
-
实现须知:HC573芯片的锁存端LE得输入高电平,即Y4C输入高电平,来控制LED对应的管脚。下图知Y4C,受Y4控制,WR输入固定为低电平(0),了解数字电路中或非门知识,我们得使得Y4输出低电平,才能使的Y4C输出高电平,而Y4为74HC138芯片(38译码器)的一个管脚,查阅对应芯片手册可知,其真值表满足C = 1,B = 0,A = 0,(对应管脚P27,P26,P25),才能使得Y4输出低电平,同时代码实现时要保证管脚P2的其他的管脚(0~4)保持原来的状态 。同理控制数码管的Y6C和Y7C,以及控制蜂鸣器的Y5C也一样
- 注意:按键功能选择KBD(J5上的跳线2与1相连,此时切换至4 * 4矩阵键盘模块)
实验程序
显示对应的按键值
//config.h--用于声明头文件,声明函数,声明一些经常使用的变量或难书写的语句
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>//对应芯片函数头文件,定义了一些特殊功能寄存器
//typedef unsigned char uchar;
#define uchar unsigned char
void Delay1ms(); //@12.000MHz
void Delay10ms(); //@12.000MHz
#endif
//main.c--4 * 4矩阵键盘实现显示对应的按键值,按键值范围0 ~ 15,从左至右,从上到下
#include "config.h"
uchar key_num = 20;
//共阴数码管段码表
uchar smgduan[] = //标准字库
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black - H J K L N o P U t G Q r M y
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
uchar smgwei[] = 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80; //位码
uchar tab[8];
void dig_display(uchar pos, letter)
P2 = (P2 & 0x1f) | 0xc0;
P0 = smgwei[pos - 1];
P2 &= 0x1f;
P2 = (P2 & 0x1f) | 0xe0;
P0 = ~smgduan[letter];
P2 &= 0x1f;
Delay1ms();//给足显示
void display()
uchar i;
for (i = 0; i < 8; i++)
dig_display(i + 1, tab[i]);
void display_ds(uchar p1, p2, p3, p4, p5, p6, p7, p8)
tab[0] = p1;
tab[1] = p2;
tab[2] = p3;
tab[3] = p4;
tab[4] = p5;
tab[5] = p6;
tab[6] = p7;
tab[7] = p8;
void closeBeep()
P2 = (P2 & 0x1f) | 0xa0;
P06 = 0, P04 = 0;//关闭蜂鸣器和继电器
P2 &= 0x1f;//P27 ~ P25清零
void led_initAlllight()
P2 = (P2 & 0x1f) | 0x80;
P0 = 0x00;
P2 &= 0x1f;
void key_scanf()
static uchar key_state = 0, row = 0;
switch(key_state)
case 0:
P3 = 0x0f, P42 = 0, P44 = 0;
if (P3 != 0x0f)//判断有无按键按下
Delay10ms();//消抖
if (P3 != 0x0f)
key_state = 1;
break;
case 1:
P3 = 0x0f, P42 = 0, P44 = 0;//先送行为高电平,列为低电平,找出哪一行
if (P3 != 0x0f)
if (P30 == 0) row = 1, key_state = 2;
if (P31 == 0) row = 2, key_state = 2;
if (P32 == 0) row = 3, key_state = 2;
if (P33 == 0) row = 4, key_state = 2;
switch(row)
case 1:
P3 = 0xf0, P42 = 1, P44 = 1;
if (P44 == 0) key_num = 0;
if (P42 == 0) key_num = 1;
if (P35 == 0) key_num = 2;
if (P34 == 0) key_num = 3;
break;
case 2:
P3 = 0xf0, P42 = 1, P44 = 1;
if (P44 == 0) key_num = 4;
if (P42 == 0) key_num = 5;
if (P35 == 0) key_num = 6;
if (P34 == 0) key_num = 7;
break;
case 3:
P3 = 0xf0, P42 = 1, P44 = 1;
if (P44 == 0) key_num = 8;
if (P42 == 0) key_num = 9;
if (P35 == 0) key_num = 10;
if (P34 == 0) key_num = 11;
break;
case 4:
P3 = 0xf0, P42 = 1, P44 = 1;
if (P44 == 0) key_num = 12;
if (P42 == 0) key_num = 13;
if (P35 == 0) key_num = 14;
if (P34 == 0) key_num = 15;
break;
case 2://按完键之后,就没有按键下去
P3 = 0x0f, P42 = 0, P44 = 0;
if (P3 == 0x0f)
key_state = 0;
break;
void main()
closeBeep();
led_initAlllight();
while(1)
display();//显示初始化
key_scanf();
display_ds(16, 16, 16, 16, 16, 16, key_num / 10, key_num % 10);//数码管黑的段码显示为16
void Delay1ms() //@12.000MHz
unsigned char i, j;
i = 12;
j = 169;
do
while (--j);
while (--i);
void Delay10ms() //@12.000MHz
unsigned char i, j;
i = 117;
j = 184;
do
while (--j);
while (--i);
2 * 2变式矩阵按键实现独立按键
- 我们使用4 * 4左下角的 2 * 2小矩阵按键来实现四个独立按键并显示对应的键值实验
- 注意:便是独立按键我们跳线帽接
KBD
(即1 和 2连)
主要代码改变部分
void key_scanf()
static uchar key_state = 0, row = 0;
switch(key_state)
case 0:
P32 = 1, P33 = 1, P42 = 0, P44 = 0;
if ((P32 != 1) || (P33 != 1))//判断有无按键按下
Delay10ms();//消抖
if ((P32 != 1) || (P33 != 1))
key_state = 1;
break;
case 1:
P32 = 1, P33 = 1, P42 = 0, P44 = 0;//先送行为高电平,列为低电平,找出哪一行
if ((P32 != 1) || (P33 != 1))
if (P32 == 0) row = 3, key_state = 2;
if (P33 == 0) row = 4, key_state = 2;
switch(row)
case 3:
P32 = 0, P33 = 0, P42 = 1, P44 = 1;
if (P44 == 0) key_num = 8;
if (P42 == 0) key_num = 9;
break;
case 4:
P32 = 0, P33 = 0, P42 = 1, P44 = 1;
if (P44 == 0) key_num = 12;
if (P42 == 0) key_num = 13;
break;
case 2://按完键之后,就没有按键下去
P32 = 1, P33 = 1, P42 = 0, P44 = 0;
if ((P32 == 1) && (P33 == 1))
key_state = 0;
break;
2 * 2变式矩阵键盘控制蜂鸣器
//main.c--使用小2 * 2的小矩阵按键实现独立按键功能,按下S5键,蜂鸣器发声,按下S8键蜂鸣器关闭,按下另外两个键维持蜂鸣器当前的状态
#include "config.h"
#include "config.h"
uchar key_num = 20;
uchar start = 0;
void key_scanf()
static uchar key_state = 0, row = 0;
switch(key_state)
case 0:
P32 = 1, P33 = 1, P42 = 0, P44 = 0;
if ((P32 != 1) || (P33 != 1))//判断有无按键按下
Delay10ms();//消抖
if ((P32 != 1) || (P33 != 1))
key_state = 1;
break;
case 1:
P32 = 1, P33 = 1, P42 = 0, P44 = 0;//先送行为高电平,列为低电平,找出哪一行
if ((P32 != 1) || (P33 != 1))
if (P32 == 0) row = 3, key_state = 2;
if (P33 == 0) row = 4, key_state = 2;
switch(row)
case 3:
P32 = 0, P33 = 0, P42 = 1, P44 = 1;
if (P44 == 0) key_num = 8;
if (P42 == 0) key_num = 9;
break;
case 4:
P32 = 0, P33 = 0, P42 = 1, P44 = 1;
if (P44 == 0) key_num = 12;
if (P42 == 0) key_num = 13;
break;
case 2://按完键之后,就没有按键下去
P32 = 1, P33 = 1, P42 = 0, P44 = 0;
if ((P32 == 1) && (P33 == 1))
key_state = 0;
break;
if (8 == key_num)
start = 1;
else if (13 == key_num)
start = 0;
else
start = 3;
void closeBeep()
P2 = (P2 & 0x1f) | 0xa0;
P06 = 0, P04 = 0;
P2 &= 0x1f;
Delay10ms();
void openBeep()
P2 = (P2 & 0x1f) | 0xa0;
P06 = 1, P04 = 1;
P2 &= 0x1f;
Delay10ms()以上是关于《蓝桥杯CT107D单片机竞赛板》:矩阵键盘模块的主要内容,如果未能解决你的问题,请参考以下文章