蓝桥杯单片机关于矩阵键盘输入数字与数码管显示输出(IAP15F2K61S2)
·
笔者通过第十一届蓝桥杯单片机模拟I智能门锁和第十五届蓝桥杯单片机模拟I的题目,发现关于矩阵键盘输入和数码管实现输出的部分方法。
笔者能力有限,部分逻辑可能存在问题,欢迎各位大佬指出错误,谢谢!
第十一届模拟I
第十五届模拟I

一、矩阵键盘
键盘引脚

使用矩阵键盘需要在J5把按键帽连接KBD
矩阵键盘的使用我们基本上是扫描按键引脚,可以按行扫描,也可以按列扫描
笔者这里以按行扫描为例子
我们知道,判断按键按下,我们需要识别出某一行是相同电平,在这个图中,当K1按下后,与GND相连,电平由高电平,变为低电平,我们就可以知道,KeyIn1被接通,由此可以知道,我们矩阵键盘有8个引脚,所以,我们只需要把引脚配置成相同电平,再每一行独立检测,就可以知道哪一个按键按下了。
二、数码管
数码管位选

数码管段选


数码管的位选和段选
位选74HC573锁存器需要打开Y6C口
段选74HC573锁存器需要打开Y7C口
锁存器通道选择代码
void hc(unsigned char n)//锁存器通道选择
{
switch(n)
{
case 0:
P2 = P2 & 0x1f;
break;
case 4:
P2 = (P2 & 0x1f) | 0x80;//LED
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;//蜂鸣器,继电器
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;//数码管位选
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;//数码管段选
break;
}
}
三、结合
方法一:
定义一个按键数组,记录按键输入的数字,再通过不断替换数组的数字,显示在数码管上面
sbit K1 = P3^0;
sbit K2 = P3^1;
sbit K3 = P3^2;
sbit K4 = P3^3;
sbit K5 = P3^4;
sbit K6 = P3^5;
sbit K7 = P4^2;
sbit K8 = P4^4;
code unsigned char Seg_Table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};//数码管段选数组
unsigned char Key_pass[4]={0};//键盘输入的数字(以四个数字为例)
unsigned char Key_count;//键盘输入的数字的位数
void Nixie_pos_num(unsigned char pos,num)//数码管位置,显示的数字
{
hc(6);
P0 = 0x01 << (pos-1);
hc(7);
P0 = num;
delay(100);
P0 = 0xff;
hc(0);
}
void Nixie_Show()//数码管显示内容
{
Nixie_pos_num(1,Seg_Table[12]);//C
Nixie_pos_num(2,Seg_Table[16]);//16是数码管熄灭,赋值0xff防止数码管频闪
Nixie_pos_num(3,Seg_Table[16]);
Nixie_pos_num(4,Seg_Table[16]);
//这里数码管显示需要判断输入是数字多少位
if(Key_count == 1)//输入一位
{
Nixie_pos_num(8,Seg_Table[Key_pass[0]]);//数字从数组中获取
}
else if(Key_count == 2)//输入两位
{
Nixie_pos_num(7,Seg_Table[Key_pass[0]]);
Nixie_pos_num(8,Seg_Table[Key_pass[1]]);
}
else if(Key_count == 3)//输入三位
{
Nixie_pos_num(6,Seg_Table[Key_pass[0]]);
Nixie_pos_num(7,Seg_Table[Key_pass[1]]);
Nixie_pos_num(8,Seg_Table[Key_pass[2]]);
}
else if(Key_count == 4)//输入四位
{
Nixie_pos_num(5,Seg_Table[Key_pass[0]]);
Nixie_pos_num(6,Seg_Table[Key_pass[1]]);
Nixie_pos_num(7,Seg_Table[Key_pass[2]]);
Nixie_pos_num(8,Seg_Table[Key_pass[3]]);
}
}
void Key_Num()
{
K1 = K2 = K3 = K5 = K6 = K7 = K8 = 1;K4 = 0;//最下面一行扫描
if(K7 == 0 || K6 == 0 || K5 == 0)
{
delay(100);
if(K7 == 0)//s8按下
{
if(Key_count < 4)//判断按键是否超过4个数字
{
Key_pass[Key_count] = 7;
Key_count++;
}
while(K7 == 0)
{
Nixie_Show();
}
}
if(K6 == 0)//s12按下
{
if(Key_count < 4)//判断按键是否超过4个数字
{
Key_pass[Key_count] = 8;
Key_count++;
}
while(K6 == 0)
{
Nixie_Show();
}
}
if(K5 == 0)//s16按下
{
if(Key_count < 4)//判断按键是否超过4个数字
{
Key_pass[Key_count] = 9;
Key_count++;
}
while(K5 == 0)
{
Nixie_Show();
}
}
}
K1 = K2 = K4 = K5 = K6 = K7 = K8 = 1;K3 = 0;//最倒数第二行扫描
if(K8 == 0 || K7 == 0 || K6 == 0 || K5 == 0)
{
delay(100);
//清零按键
if(K8 == 0)//s5按下
{
Key_count = 0;//按键次数清零
Key_pass[0]=Key_pass[1]=Key_pass[2]=Key_pass[3]=0;//数码管全部熄灭状态
while(K8 == 0)
{
Nixie_Show();
}
}
if(K7 == 0)//s9按下
{
if(Key_count < 4)//判断按键是否超过4个数字
{
Key_pass[Key_count] = 4;
Key_count++;
}
while(K7 == 0)
{
Nixie_Show();
}
}
if(K6 == 0)//s13按下
{
if(Key_count < 4)//判断按键是否超过4个数字
{
Key_pass[Key_count] = 5;
Key_count++;
}
while(K6 == 0)
{
Nixie_Show();
}
}
if(K5 == 0)//s17按下
{
if(Key_count < 4)//判断按键是否超过4个数字
{
Key_pass[Key_count] = 6;
Key_count++;
}
while(K5 == 0)
{
Nixie_Show();
}
}
}
K1 = K3 = K4 = K5 = K6 = K7 = K8 = 1;K2 = 0;//第三行扫描
if(K8 == 0 || K7 == 0 || K6 == 0 || K5 == 0)
{
delay(100);
if(K8 == 0)//s6按下
{
if(Key_count < 4)//判断按键是否超过4个数字
{
Key_pass[Key_count] = 0;
Key_count++;
}
while(K8 == 0)
{
Nixie_Show();
}
}
if(K7 == 0)//s9按下
{
if(Key_count < 4)//判断按键是否超过4个数字
{
Key_pass[Key_count] = 1;
Key_count++;
}
while(K7 == 0)
{
Nixie_Show();
}
}
if(K6 == 0)//s13按下
{
if(Key_count < 4)//判断按键是否超过4个数字
{
Key_pass[Key_count] = 2;
Key_count++;
}
while(K6 == 0)
{
Nixie_Show();
}
}
if(K5 == 0)//s17按下
{
if(Key_count < 4)//判断按键是否超过4个数字
{
Key_pass[Key_count] = 3;
Key_count++;
}
while(K5 == 0)
{
Nixie_Show();
}
}
}
}
方法二:
定义一个变量Keynumber,不同按键按下,返回的变量Keynumber不同,在通过数码管显示出来
sbit K1 = P3^0;
sbit K2 = P3^1;
sbit K3 = P3^2;
sbit K4 = P3^3;
sbit K5 = P3^4;
sbit K6 = P3^5;
sbit K7 = P4^2;
sbit K8 = P4^4;
unsigned int Password,Count;
unsigned char KeyNum;
unsigned char Key()
{
unsigned char KeyNumber=0;
K4 = K2 = K3 = K5 = K6 = K7 = K8 = 1;K1 = 0;
if(K8==0){Delay(20);while(K8==0);Delay(20);KeyNumber=1;}
if(K7==0){Delay(20);while(K7==0);Delay(20);KeyNumber=5;}
if(K6==0){Delay(20);while(K6==0);Delay(20);KeyNumber=9;}
if(K5==0){Delay(20);while(K5==0);Delay(20);KeyNumber=13;}
K1 = K4 = K3 = K5 = K6 = K7 = K8 = 1;K2 = 0;
if(K8==0){Delay(20);while(K8==0);Delay(20);KeyNumber=2;}
if(K7==0){Delay(20);while(K7==0);Delay(20);KeyNumber=6;}
if(K6==0){Delay(20);while(K6==0);Delay(20);KeyNumber=10;}
if(K5==0){Delay(20);while(K5==0);Delay(20);KeyNumber=14;}
K1 = K2 = K4 = K5 = K6 = K7 = K8 = 1;K3 = 0;
if(K8==0){Delay(20);while(K8==0);Delay(20);KeyNumber=3;}
if(K7==0){Delay(20);while(K7==0);Delay(20);KeyNumber=7;}
if(K6==0){Delay(20);while(K6==0);Delay(20);KeyNumber=11;}
if(K5==0){Delay(20);while(K5==0);Delay(20);KeyNumber=15;}
K1 = K2 = K3 = K5 = K6 = K7 = K8 = 1;K4 = 0;
if(K8==0){Delay(20);while(K8==0);Delay(20);KeyNumber=4;}
if(K7==0){Delay(20);while(K7==0);Delay(20);KeyNumber=8;}
if(K6==0){Delay(20);while(K6==0);Delay(20);KeyNumber=12;}
if(K5==0){Delay(20);while(K5==0);Delay(20);KeyNumber=16;}
return KeyNumber;
}
void Key_Num()
{
KeyNum=Key();
if(KeyNum)
{
if(KeyNum<=10) //如果S1~S10按键按下
{
if(Count<4) //如果输入次数小于4
{
Password*=10; //左移一位
Password+=KeyNum%10; //获取一位密码
Count++; //计次加一
}
}
}
四、演示


五、总结
注意:以上代码这是一个参考,并不是所有题目都可以这样做,需要读者感觉题目要求配置。同时这是笔者的一个方法,代码是不完整的,目的是提供读者一个参考方向。
以上是笔者自己总结的一些方法,能力有限,可能复杂化了很多东西。本文是基于读者已经熟练掌握了矩阵键盘,数码管的单独模块后的代码显示,如果出现看不懂的代码,需要读者先学习关于数码管,矩阵键盘的基础知识哈。
更多推荐



所有评论(0)