蓝桥杯单片机(三)矩阵按键

上章说了独立按键
蓝桥杯单片机(二)独立按键
这章说一下矩阵按键
蓝桥杯单片机(三)矩阵按键_第1张图片
所谓矩阵按键,就是每一个按键的两端都同时由单片机的IO口进行控制,如原理图所示,上图要想使用矩阵按键,就需要使用跳线帽将排针2引脚和1引脚连接在一起。
连接好了以后,这四排四列就可以看成四列独立按键,也可以看成四排独立按键,假设现在把它当成四列独立按键,使用时只需要依次每一列进行独立按键检测就行了,首先将P37,P36,P35,P34也就是P3高四位选择一位置0,比如检测S4,S5,S6,S7这一列时,只需要

P3 &=0X7F;

蓝桥杯单片机(三)矩阵按键_第2张图片

这样就相当于将S4-S7一端接地,另外一端接单片机IO口了
但是,如上图,由于在蓝桥杯单片机这款开发板上P37,P36是接到了单片机的P42和P44,所以要使用

P3 &=0X7F;P42=1;P44=0;

接下来就是矩阵按键的代码:

void Jkey_scan(void)
{
	unsigned char i,key;
	for(i=0x80;i>8;i >>=1)
	{
	//每次循环选中一列按键
		if(i==0x80){P44=0;P42=1;P3=~i;}
		else if(i==0x40){P44=1;P42=0;P3=~i;}
		else {P44=1;P42=1;P3=~i;}
	//使用key保存P3口的状态	
		if(i==0x80){key=P3;key&=0x7f;}
		else if(i==0x40){key=P3;key&=0xbf;}
		else {key=P3;}
	//被按下就在case语句中选中任务	
		if((key&0x0f)!=0x0f)
		{
			delay5ms();
			if((key&0x0f)!=0x0f)
			{
				switch(key)
				{
					case 0x7e:break;
					case 0x7d:break;
					case 0x7b:break;
					case 0x77:break;
				
					case 0xbe:break;
					case 0xbd:break;
					case 0xbb:break;
					case 0xb7:break;	

					case 0xde:break;
					case 0xdd:break;
					case 0xdb:break;
					case 0xd7:break;

					case 0xee:break;
					case 0xed:break;
					case 0xeb:break;
					case 0xe7:break;						
				}
			}
			//松手检测,没松手就一直单片机循环
			while((key&0x0f)!=0x0f)
			{
				key=P3;
			}
		}
	}
}

首先定义一个for循环,i每次取值为0X80,0X40,0X20,0X10,0X08就大于8了就退出循环了,首先当i=0X80时,先使用if语句选中对应第一列按键,也就是P44=0;P42=1;P3=~i;,假设现在第一列第一个按键被按下,P3=0X77,然后将P3的值给key,key&0X7F=0X77,这样按键状态就由key保存了,然后判断key&0X0F是否等于0X0F判断由按键是否被按下,被按下先用5ms延时消抖,然后再判断使用switch进行任务选择。最后while循环进行松手检测,不松手就不会进行下一次按键扫描。
然后我这里也给出一个矩阵按键控制LED的实例:

#include 

void Jkey_scan(void);
void delay5ms(void);

void main(void)
{
	P2=0XA0;P0=0X00;P2=0X80;P0&=0XFF;
	while(1)
	{
		Jkey_scan();
	}
}

void Jkey_scan(void)
{
	unsigned char i,key;
	for(i=0x80;i>8;i >>=1)
	{
		if(i==0x80){P44=0;P42=1;P3=~i;}
		else if(i==0x40){P44=1;P42=0;P3=~i;}
		else {P44=1;P42=1;P3=~i;}
		if(i==0x80){key=P3;key&=0x7f;}
		else if(i==0x40){key=P3;key&=0xbf;}
		else {key=P3;}
		if((key&0x0f)!=0x0f)
		{
			delay5ms();
			if((key&0x0f)!=0x0f)
			{
				switch(key)
				{
					case 0x7e:P2=0X80;P0&=0XFE;break;
					case 0x7d:P2=0X80;P0&=0XFD;break;
					case 0x7b:P2=0X80;P0&=0XFB;break;
					case 0x77:P2=0X80;P0&=0XF7;break;
				
					case 0xbe:P2=0X80;P0&=0XEF;break;
					case 0xbd:P2=0X80;P0&=0XDF;break;
					case 0xbb:P2=0X80;P0&=0XBF;break;
					case 0xb7:P2=0X80;P0&=0X7F;break;	

					case 0xde:P2=0X80;P0|=0X01;break;
					case 0xdd:P2=0X80;P0|=0X02;break;
					case 0xdb:P2=0X80;P0|=0X04;break;
					case 0xd7:P2=0X80;P0|=0X08;break;

					case 0xee:P2=0X80;P0|=0X10;break;
					case 0xed:P2=0X80;P0|=0X20;break;
					case 0xeb:P2=0X80;P0|=0X40;break;
					case 0xe7:P2=0X80;P0|=0X80;break;						
				}
			}
			while((key&0x0f)!=0x0f)
			{
				key=P3;
			}
		}
	}
}

void delay5ms(void)		//@11.0592MHz
{
	unsigned char i, j;

	i = 54;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}

代码作用就是前两列按键控制LED亮,后两列按键控制指定LED熄灭。
效果如下:

你可能感兴趣的:(单片机,蓝桥杯,矩阵)