高级会员 
  
	- 积分
 - 926
 
        - 金钱
 - 926 
 
       - 注册时间
 - 2018-11-2
 
      - 在线时间
 - 175 小时
 
 
 
 | 
 
 
 楼主 |
发表于 2024-8-5 18:18:02
|
显示全部楼层
 
 
 
这是矩阵键盘驱动 
H文件: 
#ifndef __Key_matrix_H 
#define __Key_matrix_H  
 
#include "Header.h" 
 
/*务必把这4个输出IO设置为上拉输入*/ 
#define KEY_HOR1 PAin(7) 
#define KEY_HOR2 PAin(6) 
#define KEY_HOR3 PAin(5) 
#define KEY_HOR4 PAin(4) 
/*务必把这4个输出IO设置为开漏*/ 
#define KEY_LON1 PBout(0) 
#define KEY_LON2 PCout(5) 
#define KEY_LON3 PCout(4) 
//#define KEY_LON4 PCout(4) 
 
#define KEY_PRESS_TIME 20//消抖常数 
#define KEY_LONG_PRESS_TIME 1000//单个按键长按阈值1s 
/*通过读取(只读)这三个变量即可获得按键的单按、长按和组合键信息*/ 
extern volatile uint16_t Key_Phy_Num; 
extern volatile uint8_t Key_Pulse_Num; 
extern volatile uint16_t Key_LP_Num; 
 
typedef enum 
{ 
    KPL_DISABLE=0, 
    KPL_ENABLE 
}K_L_P;//按键的长按状态 
typedef struct 
{ 
    K_L_P KEY_LONG_PRESS; 
    uint16_t KeyOpenCount; 
    uint8_t KOC_EN; 
    uint16_t KeyCloseCount; 
    uint8_t KCC_EN; 
}Key_Para; 
 
extern Key_Para Key_1,Key_2,Key_3,Key_4,Key_5,Key_6,Key_7,Key_8, 
                Key_9,Key_10,Key_11,Key_12,Key_13,Key_14,Key_15,Key_16; 
 
void Clear_Key_Pulse_Num(void);//当读取完Key_Pulse_Num后调用 
void KeyCount_Run(void);//在1ms滴答里调用 
void Key_Scan(void);//大循环或者滴答里边都行 
 
#endif 
 
C文件: 
#include "Key_matrix.h" 
 
Key_Para Key_1,Key_2,Key_3,Key_4,Key_5,Key_6,Key_7,Key_8, 
         Key_9,Key_10,Key_11,Key_12,Key_13,Key_14,Key_15,Key_16; 
volatile uint16_t Key_Phy_Num=0;  //Key_Phy_Num每一个bit代表一个按键的状态 
volatile uint8_t Key_Pulse_Num=0;//当某一个按键从按下到弹起的过程中(非长按)始终只有该按键被操作,则Key_Pulse_Num被修改为该键的序号 
volatile uint16_t Key_LP_Num=0;   //Key_LP_Num每一个bit代表一个按键的长按状态 
uint8_t KeyCom=0;//组合键是否出现 
 
static void Key_Num_Read(Key_Para* Key,uint16_t KPN,uint8_t Pulse,uint8_t Key_Hor) 
{ 
  if(Key_Hor == 0) 
    { 
        Key->KOC_EN=0;//按键按下立即清除(松开)计数 
        if(Key->KeyCloseCount > KEY_PRESS_TIME) 
        { 
            /*消抖方法为检测到按键被(持续)按下超过20ms*/ 
            Key_Phy_Num|=KPN;//消抖完毕后记录被按下的按键的键值 
            if(Key->KeyCloseCount > KEY_LONG_PRESS_TIME) 
            { 
                /*检测到按键被(持续)按下超过3秒*/ 
                Key->KEY_LONG_PRESS=KPL_ENABLE; 
        Key_LP_Num|=KPN; 
        Key->KCC_EN=0; 
            } 
      else 
      { 
        /*时间不够启动计数*/ 
        Key->KCC_EN=1; 
      } 
        } 
        else 
        { 
            /*时间不够启动计数*/ 
            Key->KCC_EN=1; 
        } 
    } 
    else 
    { 
        Key->KCC_EN=0;//按键松开立即清除(按下)计数 
        if(Key->KeyOpenCount > KEY_PRESS_TIME) 
        { 
      if((Key_Phy_Num==KPN)&&(KeyCom==0)&&(Key->KEY_LONG_PRESS!=KPL_ENABLE)) 
      { 
        //按键被按下过&&非长按&&不是在组合键周期,该按键释放时发出生命周期为直到被读取或者直到有新按键被按下的脉冲 
        Key_Pulse_Num=Pulse; 
      } 
      //清除该位 
      Key_Phy_Num&=(~KPN); 
      Key_LP_Num&=(~KPN); 
            /*检测到(持续)松开20ms*/ 
            Key->KEY_LONG_PRESS=KPL_DISABLE; 
      Key->KOC_EN=0; 
        } 
        else 
        { 
            Key->KOC_EN=1; 
        } 
    } 
} 
/********************************************************/ 
static void Key_Count(Key_Para *Key) 
{ 
    if(Key->KOC_EN==0) 
    { 
        Key->KeyOpenCount=0; 
    } 
    else if(Key->KeyOpenCount>=50000) 
    { 
        Key->KeyOpenCount=50000; 
    } 
    else 
    { 
        Key->KeyOpenCount++; 
    } 
 
    if(Key->KCC_EN==0) 
    { 
        Key->KeyCloseCount=0; 
    } 
    else if(Key->KeyCloseCount>=50000) 
    { 
        Key->KeyCloseCount=50000; 
    } 
    else 
    { 
        Key->KeyCloseCount++; 
    } 
} 
/********************************************************/ 
void Clear_Key_Pulse_Num(void) 
{ 
    Key_Pulse_Num=0; 
} 
/********************************************************/ 
void KeyCount_Run(void) 
{ 
    Key_Count(&Key_1); 
    Key_Count(&Key_2); 
    Key_Count(&Key_3); 
    Key_Count(&Key_4); 
    Key_Count(&Key_5); 
    Key_Count(&Key_6); 
    Key_Count(&Key_7); 
    Key_Count(&Key_8); 
    Key_Count(&Key_9); 
    Key_Count(&Key_10); 
    Key_Count(&Key_11); 
    Key_Count(&Key_12); 
//    Key_Count(&Key_13); 
//    Key_Count(&Key_14); 
//    Key_Count(&Key_15); 
//    Key_Count(&Key_16); 
} 
/********************************************************/ 
static void Recognition_KeyCombination(void) 
{ 
    uint8_t i=0,j=0; 
    uint16_t Data=0; 
     
    Data=Key_Phy_Num; 
    for(i=0;i<16;i++) 
    { 
        if(Data&0x8000) 
        { 
            j++; 
        } 
        Data<<=1; 
    } 
    /*发现多个bit为1,那指定多个按键按下了*/ 
    if(j>1) 
    { 
        KeyCom=1; 
    } 
    /*一切归于平静,又是一个因果循环*/ 
    if(Key_Phy_Num==0x0) 
    { 
        KeyCom=0; 
    } 
} 
/********************************************************/ 
void Key_Scan(void) 
{     
  static uint8_t ScanCount=0; 
   
  Recognition_KeyCombination(); 
    switch(ScanCount) 
  { 
    case 0: 
    { 
      KEY_LON1=0;KEY_LON2=1;KEY_LON3=1;//KEY_LON4=1; 
      Key_Num_Read(&Key_1,(uint16_t)0x0001   ,1,KEY_HOR1); 
      Key_Num_Read(&Key_2,(uint16_t)0x0001<<1,2,KEY_HOR2); 
      Key_Num_Read(&Key_3,(uint16_t)0x0001<<2,3,KEY_HOR3); 
      Key_Num_Read(&Key_4,(uint16_t)0x0001<<3,4,KEY_HOR4); 
            KEY_LON1=1;KEY_LON2=0;KEY_LON3=1;//KEY_LON4=1; 
      ScanCount++; 
    }break; 
    case 1: 
    { 
      KEY_LON1=1;KEY_LON2=0;KEY_LON3=1;//KEY_LON4=1; 
      Key_Num_Read(&Key_5,(uint16_t)0x0001<<4,5,KEY_HOR1); 
      Key_Num_Read(&Key_6,(uint16_t)0x0001<<5,6,KEY_HOR2); 
      Key_Num_Read(&Key_7,(uint16_t)0x0001<<6,7,KEY_HOR3); 
      Key_Num_Read(&Key_8,(uint16_t)0x0001<<7,8,KEY_HOR4); 
            KEY_LON1=1;KEY_LON2=1;KEY_LON3=0;//KEY_LON4=1; 
      ScanCount++; 
    }break; 
    case 2: 
    { 
      KEY_LON1=1;KEY_LON2=1;KEY_LON3=0;//KEY_LON4=1; 
      Key_Num_Read(&Key_9 ,(uint16_t)0x0001<<8 , 9,KEY_HOR1); 
      Key_Num_Read(&Key_10,(uint16_t)0x0001<<9 ,10,KEY_HOR2); 
      Key_Num_Read(&Key_11,(uint16_t)0x0001<<10,11,KEY_HOR3); 
      Key_Num_Read(&Key_12,(uint16_t)0x0001<<11,12,KEY_HOR4); 
//            KEY_LON1=1;KEY_LON2=1;KEY_LON3=1;KEY_LON4=0; 
            KEY_LON1=0;KEY_LON2=1;KEY_LON3=1; 
//      ScanCount++; 
            ScanCount=0; 
    }break; 
//    case 3: 
//    { 
//      KEY_LON1=1;KEY_LON2=1;KEY_LON3=1;KEY_LON4=0; 
//      Key_Num_Read(&Key_13,(uint16_t)0x0001<<12,13,KEY_HOR1); 
//      Key_Num_Read(&Key_14,(uint16_t)0x0001<<13,14,KEY_HOR2); 
//      Key_Num_Read(&Key_15,(uint16_t)0x0001<<14,15,KEY_HOR3); 
//      Key_Num_Read(&Key_16,(uint16_t)0x0001<<15,16,KEY_HOR4); 
//            KEY_LON1=0;KEY_LON2=1;KEY_LON3=1;KEY_LON4=1; 
//      ScanCount=0; 
//    }break; 
    default: 
    { 
      ScanCount=0; 
    }break; 
  } 
} 
 
 
 
 |   
 
 
 
 |