蓝桥杯-单片机组基础5:矩阵键盘与数码管显示,附带小蜜蜂程序代码
蓝桥杯单片机组备赛指南请查看这篇文章:戳此跳转蓝桥杯备赛指南文章
本文章针对蓝桥杯-单片机组比赛开发板所写,代码可直接在比赛开发板上使用。
型号:国信天长4T开发板(绿板),芯片:IAP15F2K61S2
(使用国信天长蓝板也可以完美兼容,与绿板几乎无差别)
1.编程目的
通过对矩阵键盘的设置,实现将键盘对应的键值显示在数码管上。重点在于其中的逻辑功能和硬件资源。
2.原理介绍
2.1 矩阵键盘原理图
截取自SCH_硬件原理图V30.pdf)
矩阵键盘,如原理图所示就是每一个按键都被安置在了行列之间的连接点上。对于其中的每一个按键,其左端与右端都与一个P3引脚连接。例如,我们以S11为例,其左端与P4^2相连,右端与P3^0相连;当我们定义P4^2为低电平,并赋值P3^2为高电平,则某个时刻我们查询到P3^2变成低电平时,表明按键S11被按下。(这就是传统的逐行扫描法)
采取上述思路进行编程,我们可以很迅速的写出逻辑代码,但缺点是会特别特别特别特别长!网络上有人写了一个更为简略的编程思路,采用编码之后,再逐行读取对值进行累加,从而通过最终编码推断出具体是哪一行,但是我还没看懂,等我研究好了会更新文章并放出链接。
本文采用传统的逐行扫描思路。编程时:
1.先将矩阵键盘的4列(P4^4、P4^2、P3^5、P3^4)中的第一列赋值为0,其他3列全部赋值为1,然后再将4行(P3^0、P3^1、P3^2、P3^3)全部赋值为1;之后逐个读取4行,若第一行为0,则按下S7;若第一行不为0第二行为0,则按下S6;若第一第二行不为0第三行为0,则按下S5;若第一第二行第三行不为0第四行为0,则按下S4。
2.将矩阵键盘的第二列赋值为0,其余3列赋值为1,然后再将4行全部赋值为1;之后逐个读取4行,若第一行为0,则按下S11;若第一行不为0第二行为0,则按下S10;若第一第二行不为0第三行为0,则按下S9,若第一第二行第三行不为0第四行为0,则按下S8。
3.将矩阵键盘的第三列赋值为0,其余3列赋值为1,然后再将4行全部赋值为1……
4.将矩阵键盘的第四列赋值为0……
(看的出来真的很繁琐对吧,代码量真的很长,但思路最为易理解,编程时可以新建一个C文件,再引用头文件的方式节省主函数文件的大小)
注意,使用矩阵键盘时,需要将J5跳线帽接到KBD一端。
2.2 数码管原理图
针对该部分的原理讲解可参考:戳此跳转到 基础3——数码管的原理讲解,文章有具体的原理。
编程时,先设置74HC138译码器的“CBA”输入端口为“110”,选中Y6C引脚为低电平,从而激活锁存器,再对P0端口进行赋值,选中数码管的公共端com8~com1中的某一个位。
然后设置74HC138译码器的“CBA”输入端口为“111”,选中Y7C引脚为低电平,从而激活锁存器,再对P0端口进行赋值,设置需要在数码管上显示的内容。
3.代码参考
小蜜蜂矩阵键盘课程代码如下:
代码效果://矩阵键盘输入键值,数码管显示按键内容
//矩阵键盘输入键值,数码管显示按键内容
#include < REG52.H >
#include < INTRINS.H >
sfr P4 = 0xc0;
sbit C1 = P4^4;
sbit C2 = P4^2;
sbit C3 = P3^5;
sbit C4 = P3^4;
sbit L1 = P3^0;
sbit L2 = P3^1;
sbit L3 = P3^2;
sbit L4 = P3^3;
sbit HC173_A = P2^5;
sbit HC173_B = P2^6;
sbit HC173_C = P2^7;
unsigned char code SMG_duanma [18]=
{ 0xc0 , 0xf9 , 0xa4 , 0xb0 , 0x99 , 0x92 , 0x82 , 0xf8 ,
0x80 , 0x90 , 0x88 , 0x80 , 0xc6 , 0xc0 , 0x86 , 0x8e ,
0xbf , 0x7f };
void select_HC173 ( unsigned char channal )
{
switch ( channal )
{
case 4:
HC173_A = 0;
HC173_B = 0;
HC173_C = 1;
break;
case 5:
HC173_A = 1;
HC173_B = 0;
HC173_C = 1;
break;
case 6:
HC173_A = 0;
HC173_B = 1;
HC173_C = 1;
break;
case 7:
HC173_A = 1;
HC173_B = 1;
HC173_C = 1;
break;
}
}
void Input_SMG ( unsigned char pos_SMG , unsigned char value_SMG )
{
select_HC173 ( 6 );
P0 = 0x01 << pos_SMG;
select_HC173 ( 7 );
P0 = value_SMG;
}
void Delay2ms ()
{
unsigned char i,j;
_nop_ ();
_nop_ ();
i=22;
j=128;
do
{
while ( j-- );
}while ( i-- );
}
void clean_shake ( unsigned char t )
{
do
{
Delay2ms ();
}while ( --t );
}
int scan_keysKBD ( )
{
static unsigned char key_state = 0;
// L1
L1 = 0;
L2 = L3 = L4 = 1;
C1 = C2 = C3 = C4 = 1;
if ( C1 == 0 )
{
clean_shake ( 2 );
if ( C1 == 0 )
{
while ( C1 == 0 );
key_state = 0 ;
}
else ;
}
else if ( C2 == 0 )
{
clean_shake ( 2 );
if ( C2 == 0 )
{
while ( C2 == 0 );
key_state = 1 ;
}
else ;
}
else if ( C3 == 0 )
{
clean_shake ( 2 );
if ( C3 == 0 )
{
while ( C3 == 0 );
key_state = 2 ;
}
else ;
}
else if ( C4 == 0 )
{
clean_shake ( 2 );
if ( C4 == 0 )
{
while ( C4 == 0 );
key_state = 3 ;
}
else ;
}
//L2
L2 = 0;
L1 = L3 = L4 = 1;
C1 = C2 = C3 = C4 = 1;
if ( C1 == 0 )
{
clean_shake ( 2 );
if ( C1 == 0 )
{
while ( C1 == 0 );
key_state = 4 ;
}
else ;
}
else if ( C2 == 0 )
{
clean_shake ( 2 );
if ( C2 == 0 )
{
while ( C2 == 0 );
key_state = 5 ;
}
else ;
}
else if ( C3 == 0 )
{
clean_shake ( 2 );
if ( C3 == 0 )
{
while ( C3 == 0 );
key_state = 6 ;
}
else ;
}
else if ( C4 == 0 )
{
clean_shake ( 2 );
if ( C4 == 0 )
{
while ( C4 == 0 );
key_state = 7 ;
}
else ;
}
//L3
L3 = 0;
L2 = L1 = L4 = 1;
C1 = C2 = C3 = C4 = 1;
if ( C1 == 0 )
{
clean_shake ( 2 );
if ( C1 == 0 )
{
while ( C1 == 0 );
key_state = 8 ;
}
else ;
}
else if ( C2 == 0 )
{
clean_shake ( 2 );
if ( C2 == 0 )
{
while ( C2 == 0 );
key_state = 9 ;
}
else ;
}
else if ( C3 == 0 )
{
clean_shake ( 2 );
if ( C3 == 0 )
{
while ( C3 == 0 );
key_state = 10 ;
}
else ;
}
else if ( C4 == 0 )
{
clean_shake ( 2 );
if ( C4 == 0 )
{
while ( C4 == 0 );
key_state = 11 ;
}
else ;
}
//L4
L4 = 0;
L2 = L3 = L1 = 1;
C1 = C2 = C3 = C4 = 1;
if ( C1 == 0 )
{
clean_shake ( 2 );
if ( C1 == 0 )
{
while ( C1 == 0 );
key_state = 12 ;
}
else ;
}
else if ( C2 == 0 )
{
clean_shake ( 2 );
if ( C2 == 0 )
{
while ( C2 == 0 );
key_state = 13 ;
}
else ;
}
else if ( C3 == 0 )
{
clean_shake ( 2 );
if ( C3 == 0 )
{
while ( C3 == 0 );
key_state = 14 ;
}
else ;
}
else if ( C4 == 0 )
{
clean_shake ( 2 );
if ( C4 == 0 )
{
while ( C4 == 0 );
key_state = 15 ;
}
else ;
}
return key_state;
}
void KBD_SMGrunning ()
{
unsigned char value_duanma;
value_duanma = scan_keysKBD ();
Input_SMG ( 1 , SMG_duanma [ value_duanma] );
clean_shake ( 5 );
}
void main ()
{
while (1)
{
KBD_SMGrunning ();
}
}
4.消抖种类介绍(客观题)
4.1 硬件消抖
是通过在按键输出电路上添加一定的硬件线路来消除抖动,一般采用R-S触发器或单稳态电路。采用两个与非门组成的R-S触发器消抖电路如下所示:
当没有按键按下时,开关倒向下方,此时上面的与非门输入高电平,下面的与非门输入低电平,输出为高电平
当有按键按下时,开关倒向上方,此时上面的与非门输入低电平,下面的与非门输入高电平,由于反馈作用,使得输出瞬间变成低电平。而不会产生抖动波形,从而实现标准矩形波的输出。
4.2 软件消抖
是采用延时程序消除抖动。由于抖动波形的时间较短,因此可以在检测到按键按下时,进入演示程序,等跳过抖动波形之后再次检测,如果检测到按键依旧被按下,则判定按键成功。在单片机应用中,一般都采用软件消抖。
作者:听风吹雨archie