数码管显示4×4矩阵键盘的键号

电路图

数码管显示4×4矩阵键盘的键号_第1张图片

分析

  • P1.0 ~ P1.3控制键盘的列(置0代表按钮被按下)
  • P1.4 ~ P1.7控制键盘的行(置0代表按钮被按下)
  • 数码管为共阳极,低电平有效,P0.0 ~ P0.7置0对应数码管中的a,b,c,d,e,f,g,dp段亮

完整程序

方法一(推荐)

#include
#include
//段选segment			  	0    1    2    3    4    5    6    7    8   9     A	   b    C    d	  E	   F
unsigned char code seg[]={
     0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xA1,0x86,0x8e};
unsigned char temp,i; //临时变量temp,循环变量i
sbit k1=P1^0;//控制列
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;

void delay(int a)//延时函数,增大从一个状态到另一个状态之间的时间,避免因变化过快而超出人眼视觉停留的最佳时间
{
     
	while(a--);
}

void main()
{
     	
	while(1)
   {
       
   	  P1=0xef;// 选择第一行P1.7~P1.4 e(1110) P1.3~P1.0 f(1111)  
	  for(i=0;i<=3;i++)
	  {
     
	  	if(k1==0)//k1=P1^0,k1=0,P1^0=0检查第一行第一列按钮是否有按钮被按下
	    //第一次循环检查第一行第一列按钮
		//第二次循环检查第一行第二列按钮…… 
			P0=seg[i*4+0];                     //i=0 seg[0]为数字0 //i=1 seg[4]为数字4 //i=2 seg[8]为数字8 //i=3 seg[12]为字母C
		if(k2==0)//检查第二行是否有按钮被按下
		//第一次循环检查第二行第一列按钮
		//第二次循环检查第二行第二列按钮……		
			P0=seg[i*4+1];                     //i=0 seg[1]为数字1 //i=1 seg[5]为数字5 //i=2 seg[9]为数字9 //i=3 seg[13]为字母d
		if(k3==0)//检查第三行是否有按钮被按下
		//第一次循环检查第三行第一列按钮
		//第二次循环检查第三行第二列按钮……	
			P0=seg[i*4+2];					   //i=0 seg[2]为数字2 //i=1 seg[6]为数字6 //i=2 seg[10]为字母A	//i=3 seg[14]为字母E
		if(k4==0)//检查第四行是否有按钮被按下
		//第一次循环检查第四行第一列按钮
		//第二次循环检查第四行第二列按钮……	
			P0=seg[i*4+3];					   //i=0 seg[3]为数字3 //i=1 seg[7]为数字7 //i=2 seg[11]为字母b	//i=3 seg[15]为字母F
		delay(300);//消抖
		temp=P1;//第一次循环为temp=0xef,第二次循环为temp=0xbf,……
		temp=temp<<1;//此左移并非函数_crol_() 
		//第一次循环0xef左移1位 1101 1110 //第二次循环0xef再次左移1位 1011 1100 /……
		temp=temp | 0x0f;
		//第一次循环 1110 1111  0xef	 第二次循环0xef左移一位后:1101 1110  
		//               |				                               |
		//           0000 1111  0x0f	                           0000 1111  0x0f
		//           1110 1111  0xef(选择第一行)	               1101 1111  0xbf(选择第二行)  
		P1=temp; //将临时量temp赋值给P1,以便下次循环,进入扫描下一行
   	   }
	} 
}	

方法二

#include
#include
//段选segment			  	0    1    2    3    4    5    6    7    8   9     A	   b    C    d	  E	   F
unsigned char code led[]={
     0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xA1,0x86,0x8e};
// unsigned char code led[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
unsigned char temp,i; //临时变量temp,循环变量i
sbit k4=P1^4;//控制行
sbit k5=P1^5;
sbit k6=P1^6;
sbit k7=P1^7;

void delay(int a)//延时函数,增大从一个状态到另一个状态之间的时间,避免因变化过快而超出人眼视觉停留的最佳时间
{
     
	while(a--);
}

void main()
{
     	
	while(1)
   {
       
   	  	P1=0xfe;//P1.7~P1.4 (1111) P1.3~P1.0 (1110)选择第一列		  1111 1101      1111  1011   1111  0111
		for(i=0;i<=3;i++)
		{
     
			if(k4==0)//1110 1110 第一列第一行  数字1
			P0=led[0+i];//i=0	数字0                        i=1 数字1	    i=2 数字2  	    i=3  数字3
			if(k5==0)//1101 1110 第一列第二行  数字4
			P0=led[4+i];//i=0	数字4   					 i=1 数字5	    i=2 数字6		i=3  数字7
			if(k6==0)//1011 1110 第一列第三行  数字8
			P0=led[8+i];//i=0	数字8						 i=1 数字9	    i=2 字母A(10)   i=3  字母B(11)
			if(k7==0)//0111 1110 第一列第四行  字母C
			P0=led[12+i];//i=0 字母C(12)					 i=1 字母D(13)	i=2 字母E(14)	i=3  字母F(16)
			 delay(25000);
			if(i!=3)//选列只需要移动三次(0,1,2)防止第4次左移
			{
     
			temp=P1;	
			temp=temp<<1;			          //1111 1100   P1 1111 1010  P1  1111 0110    
			temp=temp | 0x01;                 //0000 0001  <<1 0000 0001 <<1  0000 0001
			P1=temp;				          //1111 1101      1111 1011      1111 0111
			}	  
		}
   } 
}	

方法三

#include
//段选segment			  	0    1    2    3    4    5    6    7    8   9     A	   b    C    d	  E	   F   
unsigned char code seg[]={
     0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xA1,0x86,0x8e};
unsigned char temp,key; //临时变量temp,seg[key]下标
sbit k1=P1^0;
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;

void delay(int a)//延时函数,增大从一个状态到另一个状态之间的时间,避免因变化过快而超出人眼视觉停留的最佳时间
{
     
	while(a--);
}

void display()
{
     
	delay(30000);
	P0=seg[key];
	
}

void main()
{
     	
	 
	P0=0xff;//清屏
	
	while(1)
  {
       
  		
	//选择第一行
	 P1=0xef;//行P1.7~P1.4 1110  列P1.3~P1.0 1111						  
	 temp=P1;
	 if( (temp&0xef)!=0xef ) //扫描第一行						 
	 {
     														   
		delay(15);//消抖									   
	    if((temp&0xef)!=0xef) //消抖后再次扫描第一行
	    {
     
	 	  switch(temp)
		  {
     
		   case 0xee:key=0;break;//第一行第一列	P1.7~P1.4行1110 P1.3~P1.0列1110
		   case 0xed:key=1;break;//第一行第二列	P1.7~P1.4行1110 P1.3~P1.0列1101
		   case 0xeb:key=2;break;//第一行第三列	P1.7~P1.4行1110 P1.3~P1.0列1011
		   case 0xe7:key=3;break;//第一行第四列	P1.7~P1.4行1110 P1.3~P1.0列0111
		  }
	    }
		display();  	  
	 }
	 
	 
	 //选择第二行
	 P1=0xbf;//行P1.7~P1.4 1101  列P1.3~P1.0 1111
	 temp=P1;
	 if((temp&0xbf)!=0xbf) //扫描第二行								 
	{
     														  
		delay(15);	//消抖									   
	   if((temp&0xbf)!=0xbf)
	   {
     
	 	 switch(temp)
		{
     
		 case 0xbe:key=4;break;//第二行第一列 P1.7~P1.4行1101 P1.3~P1.0列1110
		 case 0xbd:key=5;break;//第二行第二列 P1.7~P1.4行1101 P1.3~P1.0列1101
		 case 0xbb:key=6;break;//第二行第三列 P1.7~P1.4行1101 P1.3~P1.0列1011
		 case 0xb7:key=7;break;//第二行第四列 P1.7~P1.4行1101 P1.3~P1.0列0111
		 }
	  	}
		display();
	}
	
	
	//选择第三行
	P1=0x9f;//行P1.7~P1.4 1011  列P1.3~P1.0 1111
	 temp=P1;
	 if((temp&0x9f)!=0x9f) //扫描第三行					  
	{
     												
		delay(15);	//消抖								  
	   if((temp&0x9f)!=0x9f)
	  {
     
	 	switch(temp)
		{
     
		 case 0x9e:key=8;break;//第三行第一列  P1.7~P1.4行1011 P1.3~P1.0列1110
		 case 0x9d:key=9;break;//第三行第二列  P1.7~P1.4行1011 P1.3~P1.0列1101
		 case 0x9b:key=10;break;//第三行第三列 P1.7~P1.4行1011 P1.3~P1.0列1011
		 case 0x97:key=11;break;//第三行第四列 P1.7~P1.4行1011 P1.3~P1.0列0111
		 }
	  }
	  display();
	}
	

	//选择第四行
	 P1=0x7f;//行P1.7~P1.4 0111  列P1.3~P1.0 1111
	 temp=P1;
	 if((temp&0x7f)!=0x7f) //扫描第四行
	{
     
		delay(15);	//消抖
	   if((temp&0x7f)!=0x7f)
	   {
     
	 	  switch(temp)
		 {
     
		 case 0x7e:key=12;break;//第四行第一列 P1.7~P1.4行0111 P1.3~P1.0列1110
		 case 0x7d:key=13;break;//第四行第二列 P1.7~P1.4行0111 P1.3~P1.0列1101
		 case 0x7b:key=14;break;//第四行第三列 P1.7~P1.4行0111 P1.3~P1.0列1011
		 case 0x77:key=15;break;//第四行第四列 P1.7~P1.4行0111 P1.3~P1.0列0111
		 }
	  }
	  display();
	}
	
  }  	 
}	

效果图

数码管显示4×4矩阵键盘的键号_第2张图片

你可能感兴趣的:(默认分类,单片机)