数码管显示4×4键盘矩阵按键

//方法1-推荐
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit BEEP = P3^7;     //蜂鸣器


//定义数码管0到F
uchar code DSY_CODE[]=
{
 	0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x00
};

uchar Pre_KeyNO = 16,KeyNO = 16;	   //1 0000  为了后面的扫描按键

void DelayMS(uint ms)
{
 	uchar t;
	while(ms--)
	{
	 	for(t=0;t<120;t++);
	}
}


//检查是那个按键被按下
void Keys_Scan()
{
 	uchar Tmp;
	P1 = 0x0f;
	DelayMS(1);
	Tmp = P1 ^ 0x0f;				//
	switch(Tmp)				   //列
	{
	 	case 1: KeyNO = 0; break;
		case 2: KeyNO = 1; break;
		case 4: KeyNO = 2; break;
		case 8: KeyNO = 3; break;
		default: KeyNO = 16;
	}
	P1 = 0xf0;
	DelayMS(1);
   Tmp = P1  ^ 0xf0;
//	Tmp = P1 >> 4 ^ 0x0f;
	switch(Tmp)					   //行
	{
	 	case 1: KeyNO += 0; break;
		case 2: KeyNO += 4; break;
		case 4: KeyNO += 8; break;
		case 8: KeyNO += 12;
	}
}

//蜂鸣器函数
void Beep()
{
 	uchar i;
	for(i=0;i<100;i++)
	{
	 	DelayMS(1);
		BEEP = ~BEEP;
	}
	BEEP = 1;
}


void main()
{
 	P0 = 0x00;     //给数码管引脚初始化,数码管全灭
	while(1)
	{
	 	P1 = 0xf0;		//给P1初始化,但按键有一个被按下,P1  !=  0xf0
		if(P1 != 0xf0)
			Keys_Scan();
		if(Pre_KeyNO != KeyNO)    //当KeyNO不等于16时,有按键被按下,进行数码管点亮
		{
		 	P0 = ~DSY_CODE[KeyNO];	 //数码管是共阴极的
			Beep();
			Pre_KeyNO = KeyNO;
		}
		DelayMS(100);
	}
}
方法2
#include <reg52.h>

#define LED_PORT P0//定义数码管接口
#define KEY_PORT P1//定义键盘接口
sbit BEE=P3^0;//定义蜂鸣器接口

char rowValue;//按键所在的行值   从0开始
char columnValue;//按键所在的列值  从0开始


/***********************
**按键键值所对应的编码**
**   0  1  2  3       **
**   4  5  6  7       **
**   8  9  A  B       **
**   C  D  E  F       **
***********************/
char keyCode[][4]={0x3f,0x06,0x5b,0x4f,
									 0x66,0x6d,0x7d,0x07,
									 0x7f,0x6f,0x77,0x7c,
									 0x39,0x5e,0x79,0x71};

									 
/*******************************************************
函数名:ledDsplay()
功能:根据按键的“行值”和“列值”,把按键的值显示到数码管,
			当“行值”和“列值”为“-1”时,数码管灭灯
输入参数:
				row:按键的“行值
				column:按键的“列值”
输出参数: 无
返回值:无
*******************************************************/
void ledDsplay(char row,char column)
{
	if((-1==row) && (-1==column))
		LED_PORT = 0;//来数码管
	else
	  LED_PORT = keyCode[row][column];//显示键值
}

void delay(unsigned int d)
{
	while(--d);
}


#define BEE_ON BEE=1    //宏定义 蜂鸣器开
#define BEE_OFF BEE=0   //宏定义 蜂鸣器关

/*******************************************************
函数名:findColumn()
功能:根据按键接口所读入的值,判断按键的列值
输入参数:
				value:从按键接口读入的值
输出参数: 无
返回值:-1:没有任何列被按下    其它:按键的列值
*******************************************************/
char findColumn(char value)
{
	char i;
	value=value>>4;
	for(i=0;i<4;i++)
	{
		if(0==((value>>i)&0x01))
			return i;
	}
	return -1;
}


/*******************************************************
函数名:scanKey()
功能:扫描键盘,如果键盘有按键按下,则把按键的
      行值和列值保存在全局变量rowValue和columnValue
输入参数:无
输出参数: 当返回值为0时,输出参数为全局变量rowValue和columnValue
返回值:0有按键按下  -1没有按键按下
*******************************************************/
char scanKey()
{
	char scanRow;
	for(scanRow=0;scanRow<4;scanRow++)
	{
		KEY_PORT = ~(1<<scanRow);//扫描第0行
		if((KEY_PORT&0xf0) != 0xf0)
		{
			delay(1250);//延时去抖
			if((KEY_PORT&0xf0) != 0xf0)//真的有按下
			{
				BEE_ON;
				columnValue=KEY_PORT&0xf0;
				while(1)
				{
					if((KEY_PORT&0xf0) == 0xf0)//按键凝似台起
					{
						delay(1250);
						if((KEY_PORT&0xf0) == 0xf0)//按键确定台起
						{
							BEE_OFF;
							if(-1!=findColumn(columnValue)){
								rowValue= scanRow;
								columnValue=findColumn(columnValue);
								return 0;
							}
						}
					}
				}
			}
		}
	}
	
	return -1;
	
}

void main()
{
	BEE_OFF;
	ledDsplay(-1,-1);//初始化,数码管灭
	while(1)
	{
		if(0==scanKey())//如果有按键被按下
			ledDsplay(rowValue,columnValue);
  }
}



用定时器0的中断,进行键盘扫描,判断键位

//实例78:矩阵式键盘按键音
#include<reg52.h>   //包含51单片机寄存器定义的头文件
sbit Beep=P3^0;    //将sound位定义为P3.0

unsigned char Pre_KeyNO = 16,KeyNO = 16;	   //1 0000  为了后面的扫描按键
//定义数码管0到F
unsigned char code DSY_CODE[]=
{
 	0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x00
};
/**************************************************************
函数功能:蜂鸣器发声延时约120ms
**************************************************************/
 void delay_sound(void)   
{
   unsigned char i;
	for(i=0;i<250;i++)
	       ;
 }
/**************************************************************
函数功能:软件延时子程序约20ms
**************************************************************/
 void delay20ms(void)   
{
   unsigned char i,j;
	for(i=0;i<100;i++)
	 for(j=0;j<60;j++)
           ;
 }

void Beep2(void)
{
	unsigned char i;
 				for(i=0;i<200;i++)  //让P3.7引脚电平不断取反输出音频
           {
              Beep=0;
             delay_sound();
			 	  Beep=1;
				  delay_sound();
				}	
}
/**************************************************************
函数功能:主函数
**************************************************************/ 
 void main(void)
 {
   EA=1;                  //开总中断
	ET0=1;                 //定时器T0中断允许       
   TMOD=0x01;             //使用定时器T0的模式1
	TH0=(65536-500)/256;   //定时器T0的高8位赋初值
	TL0=(65536-500)%256;   //定时器T0的高8位赋初值 
	TR0=1;                 //启动定时器T0	   	   
	while(1)               //无限循环,等待键盘按下
		;

}
/**************************************************************
函数功能:定时器0的中断服务子程序,进行键盘扫描,判断键位
**************************************************************/ 
 void time0_interserve(void) interrupt 1 using 1    //定时器T0的中断编号为1,使用第一组寄存器
  {
    unsigned char i;
		unsigned char Tmp;
     TR0=0;                   //关闭定时器T0
     P1=0xf0;                 //所有行线置为低电平“0”,所有列线置为高电平“1”
	  if((P1&0xf0)!=0xf0)      //列线中有一位为低电平“0”,说明有键按下
	     delay20ms();           //延时一段时间、软件消抖
	  if((P1&0xf0)!=0xf0)      //确实有键按下
	    {
          Tmp = P1 ^ 0x0f;
				switch(Tmp)				   //列
			{
				case 1: KeyNO = 0; break;
				case 2: KeyNO = 1; break;
				case 4: KeyNO = 2; break;
				case 8: KeyNO = 3; break;
				default: KeyNO = 16;
				}
			P1 = 0xf0;
     delay20ms();  
			Tmp = P1  ^ 0xf0;
//		Tmp = P1 >> 4 ^ 0x0f;
				switch(Tmp)					   //行
			{
				case 1: KeyNO += 0; break;
				case 2: KeyNO += 4; break;
				case 4: KeyNO += 8; break;
				case 8: KeyNO += 12;
			}				
			
		if(Pre_KeyNO != KeyNO)    //当KeyNO不等于16时,有按键被按下,进行数码管点亮
		{
		 	P0 = ~DSY_CODE[KeyNO];	 //数码管是共阴极的
			Beep2();
			Pre_KeyNO = KeyNO;
		}
	
       }
     TR0=1;                    //关定时器T0
     TH0=(65536-500)/256;      //定时器T0的高8位赋初值
	  TL0=(65536-500)%256;      //定时器T0的高8位赋初值		 
 }

代码与仿真文件   https://download.csdn.net/download/m0_48459378/23977439

  • 13
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值