蓝桥杯单片机----矩阵键盘的基本控制

        在CT107D单片机综合训练平台上,首先将J5处的跳帽接到1~2引脚,使按键S4~S19按键组成4X4的矩阵键盘。

        需要注意的是比赛的时候用的IAP15f2k61s2单片机是没有P36和P37的,是用P44代替P37,P42代替P36,所有写程序的时候需要注意一下,大家应该对矩阵键盘的扫描原理清楚吧,这里不在对矩阵键盘的扫描原理做讲解,主要是针对一个题目做出相应程序设计。

内容设计:

        1.不同按键对应不同的键值,例如S7对应数字7,S19对应数字19,在数码管后两位上显示出来;

        2.数字不足两位的数码管应只显示一位,另外一个关闭。

#include<stc15f2k60s2.h>

#define uchar unsigned char   //定义无符号字符类型uchar
#define uint unsigned int     //定义无符号整型类型uint

uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//数字0~9,“-”,“关”
uchar qi,ba;   //定义字符型变量qi,ba,当作数码管显示控制变量
uchar num=0;

void delayms(int ms);          //延时函数
void allinit();                //初始化函数
void keyscan16();              //矩阵按键函数
void display4(uchar qi,uchar ba);   //第七、八段数码管函数

void main()//主函数
{
	allinit();                  //初始化函数
	while(1)
	{
		if(num>=10){qi=num/10;ba=num%10;}//键值大于等于10,数码管分两位显示
		else {qi=11;ba=num;}             //键值小于10,数码管显示一位,另外一位熄灭
		keyscan16();              //矩阵按键函数
		display4(qi,ba);          //第七、八段数码管函数
	}
}
void keyscan16()//矩阵按键函数
{
	uchar temp;                 //定义一个无符号变量temp
	P44=0;P42=1;P3=0x7f;        //让第一列按键为低电平
	temp=P3;                    //把P3的值赋给temp
	temp=temp&0x0f;             //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
	if(temp!=0x0f)              //判断第一列是否有按键按下
	{
		delayms(5);               //延时5ms,用来按键消抖
		temp=P3;                  //把P3的值重新赋给temp
		temp=temp&0x0f;           //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
		if(temp!=0x0f)            //再次判断第一列是否有按键按下
		{
			temp=P3;                //把P3的值重新赋给temp
			switch(temp)
			{
				case 0x7e:num=7;break;      //第一列第一个按键按下
				case 0x7d:num=6;break;      //第一列第二个按键按下
				case 0x7b:num=5;break;      //第一列第三个按键按下
				case 0x77:num=4;break;      //第一列第四个按键按下
			}
			while(temp!=0x0f)       //无按键按下则进入循环
			{
				temp=P3;              //把P3的值重新赋给temp
				temp=temp&0x0f;       //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
			}
		}
	}
	P44=1;P42=0;P3=0xbf;        //让第二列按键为低电平
	temp=P3;                    //把P3的值赋给temp
	temp=temp&0x0f;             //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
	if(temp!=0x0f)              //判断第一列是否有按键按下
	{
		delayms(5);               //延时5ms,用来按键消抖
		temp=P3;                  //把P3的值重新赋给temp
		temp=temp&0x0f;           //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
		if(temp!=0x0f)            //再次判断第一列是否有按键按下
		{
			temp=P3;                //把P3的值重新赋给temp
			switch(temp)
			{
				case 0xbe:num=11;break;      //第二列第一个按键按下
				case 0xbd:num=10;break;      //第二列第二个按键按下
				case 0xbb:num=9;break;      //第二列第三个按键按下
				case 0xb7:num=8;break;      //第二列第四个按键按下
			}
			while(temp!=0x0f)       //无按键按下则进入循环
			{
				temp=P3;              //把P3的值重新赋给temp
				temp=temp&0x0f;       //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
			}
		}
	}
	P44=1;P42=1;P3=0xdf;        //让第三列按键为低电平
	temp=P3;                    //把P3的值赋给temp
	temp=temp&0x0f;             //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
	if(temp!=0x0f)              //判断第一列是否有按键按下
	{
		delayms(5);               //延时5ms,用来按键消抖
		temp=P3;                  //把P3的值重新赋给temp
		temp=temp&0x0f;           //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
		if(temp!=0x0f)            //再次判断第一列是否有按键按下
		{
			temp=P3;                //把P3的值重新赋给temp
			switch(temp)
			{
				case 0xde:num=15;break;      //第三列第一个按键按下
				case 0xdd:num=14;break;      //第三列第二个按键按下
				case 0xdb:num=13;break;      //第三列第三个按键按下
				case 0xd7:num=12;break;      //第三列第四个按键按下
			}
			while(temp!=0x0f)       //无按键按下则进入循环
			{
				temp=P3;              //把P3的值重新赋给temp
				temp=temp&0x0f;       //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
			}
		}
	}
	P44=1;P42=1;P3=0xef;        //让第四列按键为低电平
	temp=P3;                    //把P3的值赋给temp
	temp=temp&0x0f;             //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
	if(temp!=0x0f)              //判断第一列是否有按键按下
	{
		delayms(5);               //延时5ms,用来按键消抖
		temp=P3;                  //把P3的值重新赋给temp
		temp=temp&0x0f;           //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
		if(temp!=0x0f)            //再次判断第一列是否有按键按下
		{
			temp=P3;                //把P3的值重新赋给temp
			switch(temp)
			{
				case 0xee:num=19;break;      //第四列第一个按键按下
				case 0xed:num=18;break;      //第四列第二个按键按下
				case 0xeb:num=17;break;      //第四列第三个按键按下
				case 0xe7:num=16;break;      //第四列第四个按键按下
			}
			while(temp!=0x0f)       //无按键按下则进入循环
			{
				temp=P3;              //把P3的值重新赋给temp
				temp=temp&0x0f;       //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
			}
		}
	}
}
void delayms(int ms)//延时函数
{
	uint i,j;
	for(i=ms;i>0;i--)
		for(j=845;j>0;j--);
}
void allinit()//初始化函数
{
	P2=0XA0;P0=0X00;      //关闭蜂鸣器继电器
	P2=0X80;P0=0XFF;      //关闭所有LED灯
	
	P2=0XC0;P0=0XFF;      //选中所有数码管段选
	P2=0XFF;P0=0XFF;      //关闭所有数码管
}
void display4(uchar qi,uchar ba)//第七、八段数码管函数
{
	P2=0XC0;P0=0X40;               //选中第七个数码管段选
	P2=0XFF;P0=tab[qi];            //让第一个数码管显示qi指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X80;               //选中第八个数码管段选
	P2=0XFF;P0=tab[ba];            //让第一个数码管显示ba指向的值
	delayms(1);                    //延时1ms
}

猜你喜欢

转载自blog.csdn.net/qq_45385706/article/details/115510146