单片机学习:使用矩阵按键显示数码管0-F的方法详解

1、硬件电路

2.软件编程思想

矩阵按键分两种

1、行列扫码

//数码管字摸
u8 gsmg_code[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                        0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};      //共阴 显示0-F

#include "reg52.h"

// 类型重命名
typedef unsigned char u8;
typedef unsigned int u16;

// 使用宏定义端口
#define SMG_A_DP_PORT	P0	// 数码管段选端口
#define KEY_MAXRIX_SCAN P1	// 按键 端口

// 数码管字模
u8 smg_code[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};	//共阴 显示0-F

void delpaly(u16 times)
{
	while(times--);

}

// 定义一个char 类型的函数 void 是没有形参
u8 key_maxrix_ranks_scan(void)
{
	u8 key_value = 0;   // 定义一个变量	来接收按键的状态 键值
	//1111 0111  这个代表第一列 按键没有按下为高 按下为低电平
	KEY_MAXRIX_SCAN = 0xf7;
	if(KEY_MAXRIX_SCAN!= 0xf7)
	{
		delpaly(1000);	// 消抖
	   	switch(KEY_MAXRIX_SCAN)
		{
		// 第一个按下 0111 1111	转换十六进制 0x7f 
		case 0x77: key_value = 1; break; 
		case 0xb7: key_value = 5; break; 
		case 0xd7: key_value = 9; break; 
		case 0xe7: key_value = 13; break; 	
		}
		while(KEY_MAXRIX_SCAN != 0xf7);  // 循环 当按键不等于0xf7 就结束了	
	}


	// 第二列 第三列 第四列跟第一列是一样的
	// 第二列
	KEY_MAXRIX_SCAN = 0xfb; // 1111 1011  代表第二列
	if(KEY_MAXRIX_SCAN!=0xfb)
	{
	   	delpaly(1000);	// 消抖
	 	switch(KEY_MAXRIX_SCAN)
		{
		case 0x7b: key_value = 2; break; // 0111 1011 
		case 0xbb: key_value = 6; break;  // 1011 1011  / 1101 1011  / 1110 1011
		case 0xdb: key_value = 10; break; 
		case 0xeb: key_value = 14; break; 	
		}
		while(KEY_MAXRIX_SCAN != 0xfb);
	}
	  
	
	// 第三列
	KEY_MAXRIX_SCAN = 0xfd;	  // 1111 1101 代表第三列
	if(KEY_MAXRIX_SCAN!=0xfd)
	{
	 	delpaly(1000);	// 消抖
		switch(KEY_MAXRIX_SCAN)
		{
		case 0x7d: key_value = 3; break;   // 0111  1101/ 1011 1101 / 1101 1101 / 1110 1101
		case 0xbd: key_value = 7; break; 
		case 0xdd: key_value = 11; break; 
		case 0xed: key_value = 15; break; 	
		}
		while(KEY_MAXRIX_SCAN != 0xfd);
	} 
 

	// 第四列
	KEY_MAXRIX_SCAN = 0xfe;	   // 1111 1110 代表第四列
	if(KEY_MAXRIX_SCAN!=0xfe)
	{
		delpaly(1000);	// 消抖
		switch(KEY_MAXRIX_SCAN)
		{
		case 0x7e: key_value = 4; break;   // 0111 1110  / 1011 1110  / 1101 1110  / 1110 1110
		case 0xbe: key_value = 8; break; 
		case 0xde: key_value = 12; break; 
		case 0xee: key_value = 16; break; 	
		}
		while(KEY_MAXRIX_SCAN != 0xfe); 
	}
		
	return key_value; 	  // 返回 按键的键值
}



void main()
{

	u8 key =0;  // 定义变量 key初始为0 
	while(1)
	{
		key = key_maxrix_ranks_scan();   // 使用函数 需要接收键值
		if(key!=0)
			SMG_A_DP_PORT = smg_code[key-1];  			
	}
}

2、线翻转扫描

#include "reg52.h"

// 类型重命名
typedef unsigned char u8;
typedef unsigned int u16;

// 使用宏定义端口
#define SMG_A_DP_PORT	P0	// 数码管段选端口
#define KEY_MAXRIX_SCAN P1	// 按键 端口

// 数码管字模
u8 smg_code[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};	//共阴 显示0-F

void delpaly(u16 times)
{
	while(times--);

}

// 线翻转法
u8 key_matrix_flip_scan(void)
{
	static u8 key_value =0;  // 要这个变量不坐变化的
	KEY_MAXRIX_SCAN = 0x0f; //0000 1111
	// 测试列
	if(KEY_MAXRIX_SCAN!= 0x0f)
	{
		delpaly(1000);
		switch(KEY_MAXRIX_SCAN)
		{
			KEY_MAXRIX_SCAN = 0x0f;
			case 0x07: key_value =1 ;break;	// 0000 0111 / 0000 1011 / 0000 1101 / 0000 1110 
			case 0x0b: key_value =2 ;break;	
			case 0x0d: key_value =3 ;break;
			case 0x0e: key_value =4 ;break; 
		}
		// 测试行
		KEY_MAXRIX_SCAN = 0xf0; // 1111 0000
		switch(KEY_MAXRIX_SCAN)
		{
			case 0x70: key_value = key_value  ;break;	// 0111 0000    、1011 0000 、 1101 0000 、 1110 0000
			case 0xb0: key_value=key_value+4 ;break;
			case 0xd0: key_value=key_value+8 ;break;
			case 0xe0: key_value=key_value+12 ;break; 
		}
		while(KEY_MAXRIX_SCAN !=0xf0);				
	}
	
	return key_value; 
		
}
void main()
{

	u8 key =0;  // 定义变量 key初始为0 
	while(1)
	{
		key = key_matrix_flip_scan();   // 使用函数 需要接收键值
		if(key!=0)
			SMG_A_DP_PORT = smg_code[key-1];  			
	}
}

物联沃分享整理
物联沃-IOTWORD物联网 » 单片机学习:使用矩阵按键显示数码管0-F的方法详解

发表评论