蓝桥杯突击3:独立按键和矩阵键盘(包含对IAP15芯片的适配)

这次学习独立按键和矩阵键盘:

 

       首先找到按键的原理图:

                                              

       我们发现, 按键的S7,S6,S5,S4左端连接J5上的2口, 这里我们需要找到板子的J5口:

                                                       

 

J5口上的BTN为Button(按键)的缩写, KBD为Keyboard(键盘)的缩写.观察原理图, 我们可以发现,当跳帽与BTN相连接时使用独立按键模式, 与KBD连接时使用矩阵键盘.

 

首先讲解独立按键:

用跳帽将J5的BTN与中间短接,那么当独立按键S7,S6,S5,S4中任意一个按下去时,其相应的端口就会检测到一个下降沿信号,利用单片机检测这个下降沿信号,就可以:

下面附上利独立按键控制LED的代码:

#include <reg52.h>

typedef unsigned char uchar;
typedef unsigned int uint;

sbit k1=P3^0;
sbit k2=P3^1;
sbit k3=P3^2;
sbit k4=P3^3;
sbit BUZZ=P0^6;
sbit RELAY=P0^4;

void CloseBUZZ();
void Key();

void main()
{
	CloseBUZZ();
	while (1)
	{
		Key();
	}
}

void CloseBUZZ()
{
	BUZZ=0;
	RELAY=0;
	P2=(P2&0x1f)|0xa0;
	P2&=0x1f;
}

//使用按键控制LED

void Key()
{
	if (k1==0)
	{
		P0=0xfe;
		P2=(P2&0x1f)|0x80;
		P2&=0x1f;
	}
	
	if (k2==0)
	{
		P0=0xfd;
		P2=(P2&0x1f)|0x80;
		P2&=0x1f;
	}
	
	if (k3==0)
	{
		P0=0xfb;
		P2=(P2&0x1f)|0x80;
		P2&=0x1f;
	}
	
	if (k4==0)
	{
		P0=0xf7;
		P2=(P2&0x1f)|0x80;
		P2&=0x1f;
	}
}

效果:每个按键可以控制一个LED

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                                   

之后介绍矩阵键盘,:

CT107D的开发板没有引出P3^6和P3^7,而是引出P4^2代替P3^6,用P4^4代替P3^7.

首先将跳帽接到KBD, 当我们设置P4^4(P3^7)为低电平时,第一列的按键左端变为低电平, 即设P3 = 0x7F, P4^2=1,P4^4=0;那么当第一列有按键按下时,P3的低四位会检测到下降沿. 例如,当P3 = 0x7E时, 就是第一列第一行的按键按下, 当P3 = 0x7D时,就是第一列第二行按键按下.

以此类推, 就有了所有按键的检测方法:

将矩阵键盘依照下面排序:

0     1     2     3

4     5     6     7

8     9     10   11

12   13   14   15

当按下相应的按键时数码管显示对应数字的十六进制.

 

下面附上矩阵键盘代码:

#include <reg52.h>

typedef unsigned char uchar;
typedef unsigned int uint;

/*
蓝桥杯的开发板没有引出P3^6和P3^7
而是 P4^2 -> P3^6;
     P4^4 -> P3^7;
*/

sbit BUZZ=P0^6;
sbit RELAY=P0^4;
sfr P4=0xC0;
sbit P42=P4^2;
sbit P44=P4^4;

uchar table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,  0x88,0x83,0xC6,0xA1,0x86,0x8E};
uchar KeyValue;

void CloseBUZZ();
void Display();
void delay(uint i);
void KeyBoard();

void main()
{
	CloseBUZZ();
	while (1)
	{
		Display();
		KeyBoard();
	}
}

void CloseBUZz()
{
	BUZZ=0;
	RELAY=0;
	P2=(P2&0x1f)|0xa0;
	P2&=0x1f;
}

void delay(uint i)
{
	while (i--);
}	

void KeyBoard()
{
	uchar temp;
	P3=0x7f;
	P42=1;
	P44=0;
	temp=P3;
	temp&=0x0f;
	if (temp!=0x0f)   //检测低四位
	{
		delay(10);
		temp=P3;
		temp&=0x0f;    //消抖   
		if (temp!=0x0f)
		{
			temp=P3;
			switch (temp)      //temp的与运算影响不带P3,所以如此检测
			{
				case (0x7e):KeyValue=0;break;
				case (0x7d):KeyValue=4;break;
				case (0x7b):KeyValue=8;break;
				case (0x77):KeyValue=12;break;
				default:break;
			}
			while (temp!=0x0f)
			{
				temp=P3;
				temp&=0x0f;
			}
		}
	}
		
	
	P3=0xbf;
	P42=0;
	P44=1;
	temp=P3;
	temp&=0x0f;
	if (temp!=0x0f)
	{
		delay(10);
		temp=P3;
		temp&=0x0f;
		if (temp!=0x0f)
		{
			temp=P3;
			switch (temp)
			{
				case (0xbe):KeyValue=1;break;
				case (0xbd):KeyValue=5;break;
				case (0xbb):KeyValue=9;break;
				case (0xb7):KeyValue=13;break;
				default:break;
			}
			while (temp!=0x0f)
			{
				temp=P3;
				temp&=0x0f;
			}
		}
	}
		
	
	P3=0xdf;
	P42=1;
	P44=1;
	temp=P3;
	temp&=0x0f;
	if (temp!=0x0f)
	{
		delay(10);
		temp=P3;
		temp&=0x0f;
		if (temp!=0x0f)
		{
			temp=P3;
			switch (temp)
			{
				case (0xde):KeyValue=2;break;
				case (0xdd):KeyValue=6;break;
				case (0xdb):KeyValue=10;break;
				case (0xd7):KeyValue=14;break;
				default:break;
			}
			while (temp!=0x0f)
			{
				temp=P3;
				temp&=0x0f;
			}
		}
	}
		
	
	P3=0xef;
	P42=1;
	P44=1;
	temp=P3;
	temp&=0x0f;
	if (temp!=0x0f)
	{
		delay(10);
		temp=P3;
		temp&=0x0f;
		if (temp!=0x0f)
		{
			temp=P3;
			switch (temp)
			{
				case (0xee):KeyValue=3;break;
				case (0xed):KeyValue=7;break;
				case (0xeb):KeyValue=11;break;
				case (0xe7):KeyValue=15;break;
				default:break;
			}
			while (temp!=0x0f)
			{
				temp=P3;
				temp&=0x0f;
			}
		}
	}
}

void Display()
{
	P0=0xff;
	P2=(P2&0x1f)|0xe0;
	P2&=0x1f;
	
	P0=0x80;
	P2=(P2&0x1f)|0xc0;
	P2&=0x1f;
	
	P0=table[KeyValue];
	P2=(P2&0x1f)|0xe0;
	P2&=0x1f;
}

本文章供学习交流使用, 如果转载请注明出处.

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值