矩阵键盘的编程

矩阵键盘图理论上可以实现42键无冲检测

KEY_H1,KEY_H2,KEY_H3,KEY_H4,KEY_H5,KEY_H6,KEY_H7接单片机普通端口且需要带上拉功能。
KEY_L1,KEY_L2,KEY_L3,KEY_L4,KEY_L5,KEY_L6接单片机普通端口且需要带上拉功能。

一共6*7=42个按键

按键检测子函数:

#define KEY_H1 	P53
#define KEY_H2  P23	 
#define KEY_H3	P04  
#define KEY_H4	P35  
#define KEY_H5	P34  
#define KEY_H6	P51  
#define KEY_H7	P50  

#define KEY_L1	P26
#define KEY_L2  P10
#define KEY_L3  P25
#define KEY_L4  P24
#define KEY_L5  P57
#define KEY_L6	P56

#define KEY_H1_OUTPUT_MODE  GPIO_SetMode(P5,BIT3,GPIO_MODE_OUTPUT);  //KEY_H1设置成输出模式
#define KEY_H1_QUASI_MODE   GPIO_SetMode(P5,BIT3,GPIO_MODE_QUASI);  //KEY_H1设置成准双向模式

#define KEY_H2_OUTPUT_MODE  GPIO_SetMode(P2,BIT3,GPIO_MODE_OUTPUT);  //KEY_H2设置成输出模式
#define KEY_H2_QUASI_MODE   GPIO_SetMode(P2,BIT3,GPIO_MODE_QUASI);  //KEY_H2设置成准双向模式

#define KEY_H3_OUTPUT_MODE  GPIO_SetMode(P0,BIT4,GPIO_MODE_OUTPUT);  //KEY_H3设置成输出模式
#define KEY_H3_QUASI_MODE   GPIO_SetMode(P0,BIT4,GPIO_MODE_QUASI);  //KEY_H3设置成准双向模式

#define KEY_H4_OUTPUT_MODE  GPIO_SetMode(P3,BIT5,GPIO_MODE_OUTPUT);  //KEY_H4设置成输出模式
#define KEY_H4_QUASI_MODE   GPIO_SetMode(P3,BIT5,GPIO_MODE_QUASI);  //KEY_H4设置成准双向模式

#define KEY_H5_OUTPUT_MODE  GPIO_SetMode(P3,BIT4,GPIO_MODE_OUTPUT);  //KEY_H5设置成输出模式
#define KEY_H5_QUASI_MODE   GPIO_SetMode(P3,BIT4,GPIO_MODE_QUASI);  //KEY_H5设置成准双向模式

#define KEY_H6_OUTPUT_MODE  GPIO_SetMode(P5,BIT1,GPIO_MODE_OUTPUT);  //KEY_H6设置成输出模式
#define KEY_H6_QUASI_MODE   GPIO_SetMode(P5,BIT1,GPIO_MODE_QUASI);  //KEY_H6设置成准双向模式

#define KEY_H7_OUTPUT_MODE  GPIO_SetMode(P5,BIT0,GPIO_MODE_OUTPUT);  //KEY_H7设置成输出模式
#define KEY_H7_QUASI_MODE   GPIO_SetMode(P5,BIT0,GPIO_MODE_QUASI);  //KEY_H7设置成准双向模式
//每4ms调用一次
void Keyscan()
{	
	static _u16 Kcount;
	static _u8 Key_num_old,Flag_key,en;
	_u8	i;
	//首先所有端口全部开上拉
	GPIO_SetMode(P2,BIT6|BIT5|BIT4|BIT3,GPIO_MODE_QUASI);
	GPIO_SetMode(P5,BIT6|BIT7|BIT3|BIT1|BIT0,GPIO_MODE_QUASI);
    GPIO_SetMode(P0,BIT4,GPIO_MODE_QUASI);
	GPIO_SetMode(P1,BIT0,GPIO_MODE_QUASI);
	GPIO_SetMode(P3,BIT4|BIT5,GPIO_MODE_QUASI);	

	P0->DOUT|=0x00000010;
	P1->DOUT|=0x00000001;
	P2->DOUT|=0x00000078;
	P5->DOUT|=0x000000CB;
	P3->DOUT|=0x00000030;   
 
    Key_mum=0;  			//Key_mum 按下按键的数量
	for(i=0;i<42;i++)
	{		
		Key_n[i]=0;		   //Key_n[i] 是储存按键编号用,如果检测到有n个按键按下,则Key_n前n个数据储存的是按键编号。	
		if(i<7)
		{
			Key_data[i]=0;	//把42个按键按行分为7组,每一组有6个按键,如果有按键按下相应的组的对应位就置1
		}
	}	

	KEY_H1_OUTPUT_MODE;	
	KEY_H1=0;           //KEY_H1设置成输出,并输出0
	Keydata_load(0);    //检测在KEY_L的6个端口上是否有被拉低
	KEY_H1_QUASI_MODE;
	KEY_H1=1; 

	KEY_H2_OUTPUT_MODE;	
	KEY_H2=0;           
	Keydata_load(1);    
	KEY_H2_QUASI_MODE;
	KEY_H2=1;    
	
	KEY_H3_OUTPUT_MODE;	
	KEY_H3=0;           
	Keydata_load(2);    
	KEY_H3_QUASI_MODE;
	KEY_H3=1;	

	KEY_H4_OUTPUT_MODE;	
	KEY_H4=0;           
	Keydata_load(3);    
	KEY_H4_QUASI_MODE;
	KEY_H4=1;	

	KEY_H5_OUTPUT_MODE;	
	KEY_H5=0;           
	Keydata_load(4);    
	KEY_H5_QUASI_MODE;
	KEY_H5=1;	
	
	KEY_H6_OUTPUT_MODE;	
	KEY_H6=0;           
	Keydata_load(5);    
	KEY_H6_QUASI_MODE;
	KEY_H6=1;	

	if(Compar_keydata())
	{
		Kcount=0;
        Key_data_old[0]=Key_data[0];
        Key_data_old[1]=Key_data[1];
        Key_data_old[2]=Key_data[2];
        Key_data_old[3]=Key_data[3];
        Key_data_old[4]=Key_data[4];
        Key_data_old[5]=Key_data[5];  
		Key_data_old[6]=Key_data[6]; 
        Key_num_old=Key_num; 
        Flag_key_en=0;    		
	}
	else
	{	
        if(Key_num_old==2)
        {
            if(!Flag_key_en)
            {
                Kcount++;
                if(Kcount>=500)  //如果同事按下两个按键,且长按
                {
                    Kcount=0;
                    Flag_key_en=1;
                    Flag_key_long=1;
                }
            }
        }
		else if(Key_num_old==1) //如果只有1个按键按下 //消抖
        {
            if(!Flag_key_en)
            {
                Kcount++;
                if(Kcount>=10)  //消抖40ms
                {
                    Kcount=0;
                    Flag_key_en=1;
                    Flag_key_short=1;
                }
            }            
        }
		else
		{
			Kcount=0;
		}	 		
	}
}


void Key_deal()
{
	_u8 i;
	if(Flag_key_short)
	{
		Flag_key_short=0;//只有1个按键按下
		//根据Key_n[0]的值判定是哪个按键,进行相应处理
	}
	if(Flag_key_long)
	{
		Flag_key_long=0;
		//根据Key_n[0],Key_n[1]的值判定是哪两个键,进行相应处理
	}
}







uint8_t Compar_keydata()
{
    uint8_t i;
    for(i=0;i<7;i++)
    {
        if(Key_data[i]!=Key_data_old[i]) //如果按键有有变化
        {
            return 1;
        }    
    }
    return 0;
}



void Keydata_load(uint8_t i)
{
   if(!KEY_L1)
   {
        Key_data[i]|=0x01;
        Key_n[Key_num]=i*6+1;  //储存按键编号
        Key_num++;
   }
   if(!KEY_L2)
   {
        Key_data[i]|=0x02;
        Key_n[Key_num]=i*6+2;
        Key_num++;
   } 
   if(!KEY_L3)
   {
        Key_data[i]|=0x04;
        Key_n[Key_num]=i*6+3;
        Key_num++;
   }        
   if(!KEY_L4)
   {
        Key_data[i]|=0x08;
        Key_n[Key_num]=i*6+4;
        Key_num++;
   }
   if(!KEY_L5)
   {
        Key_data[i]|=0x10;
        Key_n[Key_num]=i*6+5;
        Key_num++;
   }
   if(!KEY_L6)
   {
        Key_data[i]|=0x20;
        Key_n[Key_num]=i*6+6;
        Key_num++;
   }      
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值