8*8矩阵键盘扫描

原理讲解

在这里插入图片描述

对应代码(51单片机)

unsigned char code Table_KeyValue[64]={
    
    0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09  //键值
								,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13
								,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d
								,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
								,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31
								,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b
								,0x3c,0x3d,0x3e,0x3f,0x40};

unsigned char code Table_RowScan[8]={
    
    0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};		
//行扫描表格
/*
0从最低向高扫描
 f     e
1111 1110  
 f     d
1111 1101
 f     b
1111 1011
 f     7
1111 0111
 e     f
1110 1111
 d     f
1101 1111
 b     f
1011 1111
 7     f
0111 1111
*/
unsigned char code Table_ColumnScan[8]={
    
    0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};  //列扫描表格

unsigned char key_value=0;

/******************************************************************* 
  P1.7  P1.6  P1.5  P1.4  P1.3  P1.2  P1.1  P1.0
   C8	 C7	   C6	 C5	   C4	 C3	   C2	 C1
  
  P2.7  P2.6  P2.5  P2.4  P2.3  P2.2  P2.1  P2.0
   R8	 R7	   R6	 R5	   R4	 R3	   R2	 R1
*********************************************************************/
unsigned char keyscan(void)  //主要的矩阵键盘扫描函数。
{
    
    
	unsigned char row;            //行值
	unsigned char col;           //列值
	unsigned char key_value;    //键值

	key_value=0;  //先设定没有按键按下
	 //行扫描,将行的每一位依次清0 判断在哪一列
	for(row=0;row<8;row++)	 
	{
    
    
		P2=Table_RowScan[row];	 //设置行扫描值
		//没有按键按下P1每一位都为一,与上0xff等于0xff 但当按键按下时P1有一位为0 所以小于0xff
		if((P1&0xff)<0xff)  
		{
    
    
		//按键去抖动,不同速度的MCU调节一下延时时间即可
			delayms(10);    
			if((P1&0xff)<0xff)
			{
    
    
			//确定是哪一行后,再列扫描,根据行扫描值找出按键所在列
				for(col=0;col<8;col++)	 
				{
    
    
				//设置行对应的列有按键按下 P1(1011 1111)& (0100 0000)确定是哪个按键按下
					if((P1&Table_ColumnScan[col])==0x00) 
					{
    
    
						key_value=Table_KeyValue[row*8+col];	 //获取键值,识别按键
	
						while((P1&Table_ColumnScan[col])==0x00); //当没有松手时候停在这
						
						break;
					}
				}
			}			
		} 			
	}
	return key_value;  	
}

对应代码(STM32单片机)

unsigned char Table_KeyValue[64]={
    
    0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09  //键值
								,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13
								,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d
								,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
								,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31
								,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b
								,0x3c,0x3d,0x3e,0x3f,0x40};

unsigned char Table_RowScan[8]={
    
    0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};		//行扫描表格
unsigned char Table_ColumnScan[8]={
    
    0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};  //列扫描表格

unsigned char key_value=0;

void IO_init(void)
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure;
		
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);	         //使能PA和PC端口时钟
	
	//配置PC口为数据输出端【控制行值】
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		                                //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		                                //IO口速度为50MHz
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;		//配置PC0-PC7	
	GPIO_Init(GPIOC, &GPIO_InitStructure);					                                    //根据设定参数初始化GPIOC
	
	//配置PA口为数据输入端【读取列值】
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;   //配置PA0-PA7
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                                       //设置成上拉输入
	
	GPIO_Init(GPIOA, &GPIO_InitStructure);					                                    //根据设定参数初始化GPIOA
	
}

 /******************************************************************* 
   PA7  PA6   PA5  PA4  PA3  PA2  PA1  PA0
   C8	  C7	  C6	 C5	  C4	 C3	  C2	 C1
  
   PC7  PC6   PC5  PC4   PC3  PC2  PC1  PC0
   R8	  R7	  R6	 R5	   R4	  R3	 R2	  R1
*********************************************************************/
unsigned char keyscan(void)            //主要的矩阵键盘扫描函数
{
    
    
	unsigned char row;            //行值
	unsigned char col;            //列值
	unsigned char key_value;      //键值
	unsigned char Col_temp;       //列中转值

	key_value=0;                  //键值初始化【没有按键按下】

	for(row=0;row<8;row++)	      //行扫描【C1-C8依次将其中一位清零以判断列值】
	{
    
    

		GPIO_Write(GPIOC, Table_RowScan[row]);   //设置行扫描值
		     
		Col_temp=(GPIO_ReadInputData(GPIOA));	   //读取列值

		if(Col_temp<0xff)		        //将行的其中一位清零,若有按键按下则列的对应位也清零,值小于0xff
		{
    
    
			delayms(10);			        //按键去抖动,不同速度的MCU调节一下延时时间即可
			if(Col_temp<0xff)
			{
    
    
				
				for(col=0;col<8;col++)	  //列扫描,根据行扫描值找出按键所在行对应的列
				{
    
    
					if((Col_temp&Table_ColumnScan[col])==0x00)	 //该行扫描值对应的列有按键按下
					{
    
    
						key_value=Table_KeyValue[row*8+col];		 //获取键值
						
						Col_temp=(GPIO_ReadInputData(GPIOA));
						while((Col_temp&Table_ColumnScan[col])==0x00)							//防止连键
						{
    
    
								Col_temp=(GPIO_ReadInputData(GPIOA));	                //更新列读取值,以判断按键是否松开							
								delayms(10);                                          //加延时是防止按键抖动导致读取值出错
						}
						
						break;
					}
				}
			}			
		} 			
	}
	return key_value;  	
}

猜你喜欢

转载自blog.csdn.net/ai_moe/article/details/128699282
今日推荐