51单片机编程应用(C语言):矩阵键盘

16个按键只要8个I/O口,本来16个按键要16个I/O口。

 矩阵键盘可以按行扫描也可以按列扫描,扫描原理很简单,变成之前的独立按键,比如

按行扫描,看原理图如下,我们P17=0,另外三个置1,那么第一行就选中了,另外三行没有选中。

就变成我们熟悉的独立按键了,用独立按键的方式编写即可,检测P13的值是0吗,如果是的,那就s1按下了,检测P12是0吗,如果是的,那s2按下了。

代码如下(按列扫描),而且规定了每个按键的值是多少。


/***键盘扫描函数***/
unsigned char MatrixKey()
{
	unsigned char KeyNumber=0;
	
	P1=0xFF;
	P1_3=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
	
	P1=0xFF;
	P1_2=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
	
	P1=0xFF;
	P1_1=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
	
	P1=0xFF;
	P1_0=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
	
	return KeyNumber;
}

下面写一个相关的实例吧,比如我们介绍过数码管和矩阵按键了,也讲过数码管了,这两个结合一起使用一下。(51单片机来调试)按了矩阵键盘对应的数,数码管拿两位来显示

代码如下:

#include <REGX52.H>
//数码管段码表
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//延时子函数
void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}
//数码管显示子函数
void Nixie(unsigned char Location,Number)
{
	switch(Location)		//位码输出
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
	P0=NixieTable[Number];	//段码输出
	Delay(1);				//显示一段时间
	P0=0x00;				//段码清0,消影
}
/***键盘扫描函数***/
unsigned char MatrixKey()
{
	unsigned char KeyNumber=0;
	
	P1=0xFF;
	P1_3=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
	
	P1=0xFF;
	P1_2=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
	
	P1=0xFF;
	P1_1=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
	
	P1=0xFF;
	P1_0=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
	
	return KeyNumber;
}
void main()
{
	unsigned char keyNumber;
	unsigned char a=0;
	unsigned char b=0;
	while(1)
	{
		keyNumber=MatrixKey();	
		
		if(keyNumber)
		{
            if(keyNumber<10)
			{
				a=0;
				b=keyNumber;
			}
			if(keyNumber>10)
			{
				a=keyNumber/10;
				b=keyNumber%10;
			}
			if(keyNumber==10)
			{
				a=1;
				b=0;
			}
	}
		Nixie(1,a);
		Nixie(2,b);
		Nixie(3,0);
	    Nixie(4,0);
		Nixie(5,0);
		Nixie(6,0);
		Nixie(7,0);
		Nixie(8,0);
	}
}

我是合在一起了的,其实都是我写过的每一个模块,自己可以按之前的博文来分开,

现象如下面视频所示: 

调试结果

 矩阵键盘与动态数码管的结合:

比如,按下哪个键,对应的数字,在数码管上显示。

思路还是蛮简单的,就是把几个模块化合在一起:代码如下

#include <REGX52.H>
//数码管段码表
unsigned char NixieTable[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6};

//延时子函数
void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}
//数码管显示子函数
void Nixie(unsigned char Location,Number)
{
	switch(Location)		//位码输出
	{
		case 1:P0_0=0;P0_1=0;break;//
		case 2:P0_0=0;P0_1=1;break;//选择第1个数码管
		case 3:P0_0=1;P0_1=0;break;//选择第2个数码管
		case 4:P0_0=1;P0_1=1;break;//
	}
	P2=NixieTable[Number];	//段码输出
	Delay(1);				//显示一段时间
	P2=0x00;				//段码清0,消影
}
/***键盘扫描函数***/
unsigned char MatrixKey()
{
	unsigned char KeyNumber=0;
	
	P1=0xFF;
	P1_3=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
	
	P1=0xFF;
	P1_2=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
	
	P1=0xFF;
	P1_1=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
	
	P1=0xFF;
	P1_0=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
	
	return KeyNumber;
}
void main()
{
	unsigned char keyNumber;
	unsigned char a=0;
	unsigned char b=0;
	while(1)
	{
		keyNumber=MatrixKey();	
		
		if(keyNumber)
		{
            if(keyNumber<10)
			{
				a=0;
				b=keyNumber;
			}
			if(keyNumber>10)
			{
				a=keyNumber/10;
				b=keyNumber%10;
			}
		}
		Nixie(2,a);
		Nixie(3,b);
	    
	}
}

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-02-04 20:42:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-04 20:42:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-04 20:42:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-04 20:42:01       18 阅读

热门阅读

  1. 海量微服务关联关系挖掘与告警拓扑展示

    2024-02-04 20:42:01       27 阅读
  2. React中的事件处理逻辑

    2024-02-04 20:42:01       31 阅读
  3. WiFi测试的核心思路和主要工具

    2024-02-04 20:42:01       28 阅读
  4. 工程师 - headless模式

    2024-02-04 20:42:01       32 阅读
  5. 二叉树的构造代码

    2024-02-04 20:42:01       28 阅读
  6. C 练习实例55-学习使用按位取反~

    2024-02-04 20:42:01       19 阅读
  7. go使用gopprof分析内存泄露

    2024-02-04 20:42:01       33 阅读
  8. Go 语言实现并发、通道原理(附带案例)

    2024-02-04 20:42:01       33 阅读
  9. 自学PyQt6杂记索引

    2024-02-04 20:42:01       30 阅读