蓝桥杯-单片机组基础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

物联沃分享整理
物联沃-IOTWORD物联网 » 蓝桥杯-单片机组基础5:矩阵键盘与数码管显示,附带小蜜蜂程序代码

发表评论