⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 key.c

📁 STC51系列的源码
💻 C
字号:
/********************************************************************************/
/* filename : KEY.c                                                             */
/* created  : xillinx                                                           */
/* descript : 处理与键盘扫描相关的函数                                          */
/********************************************************************************/
#include "../CPU/CPU.h"
#include "../CFG/CFG.h"
#include "../UART/UART.h"
#include "../KEY/KEY.h"

key_put_on_hook  key_put_on_proc=c51_key_put_on_null;
key_off_hook     key_off_proc=c51_key_off_null;

/********************************************************************************/
/* fun_name : c51_key_put_on_null()                                             */
/* version  : v1.00                                                             */
/* created  : xillinx                                                           */
/********************************************************************************/
void c51_key_put_on_null(unsigned char key_val) 
{   key_val=key_val;
} 

/********************************************************************************/
/* fun_name : c51_key_off_null()                                                */
/* version  : v1.00                                                             */
/* created  : xillinx                                                           */
/********************************************************************************/
void c51_key_off_null(void) 
{   ;
} 

/********************************************************************************/
/* 键盘是4X4的行列扫描,键盘扫描的输出是U7<74HC573>的低四位,输入端是U12<74HC245> */
/* 的低四位,所以建立一个表                                                      */
/********************************************************************************/
volatile unsigned char KEY_scan_timer=0x0;

/********************************************************************************/
/* 键值查找表 */
/********************************************************************************/
unsigned char code key_table[KEY_LINE_MAX][KEY_ROW_MAX]=
{   { '1', '2', '3', 'A'},
    { '4', '4', '6', 'B'},
    { '7', '8', '9', 'C'},
    { '*', '0', '#', 'D'}
};

unsigned char code key_line_table[]={0xE,0xD,0xB,0x7};  //* 对应的行数据

/********************************************************************************/
/* fun_name : c51_key_write()                                                   */
/* version  : v1.00                                                             */
/* created  : hw-chen                                                           */
/* descript : 向KEY的锁存器里面写入低四位控制KEY的扫描                          */
/********************************************************************************/
void c51_key_write(unsigned char mdata)
{   c51_U07_latch&=0xF0;
    c51_U07_latch|=(mdata&0xF);
    c51_hc138_cs_keyw[0x0]=c51_U07_latch;
}

/********************************************************************************/
/* fun_name : c51_key_read_lo()                                                 */
/* version  : v1.00                                                             */
/* created  : hw-chen                                                           */
/* descript : 出KEY的缓冲区读出KEY的低四位作为键盘扫描                          */
/********************************************************************************/
unsigned char c51_key_read_lo(void)
{   return (c51_hc138_cs_keyr[0x0]&0x0F);
}


/********************************************************************************/
/* fun_name : c51_key_read_hi()                                                 */
/* version  : v1.00                                                             */
/* created  : hw-chen                                                           */
/* descript : 出KEY的缓冲区读出KEY的高四位作为键盘扫描                          */
/********************************************************************************/
unsigned char c51_key_read_hi(void)
{   return (c51_hc138_cs_keyr[0x0]&0xF0);
}

/********************************************************************************/
/* fun_name : c51_key_scan_operate()                                            */
/* version  : v1.00                                                             */
/* created  : hw-chen                                                           */
/* descript : 键盘扫描操作,先把写的行变成低电平,如果有键按下,那么读取的列就会   */
/*  变成低电平                                                                  */
/********************************************************************************/
unsigned char c51_key_scan_operate(void)
{   unsigned char mdata,find=0x0;
    unsigned char i,j;
    unsigned char pos;
    
    /****************************************************************************/
    /* 先把所有的行输出都变成低电平,检查是否有按键按下,如果有就检查是那一行的   */
    /* 那一列按下的,否则直接返回                                                */
    /****************************************************************************/
    c51_key_write(0x0);
    mdata=c51_key_read_lo();
    if (mdata==0xF) //* 没有任何按键按下
    {   return 0x0;
    }
    
    /****************************************************************************/
    /* 先让行输出低电平,然后读取列数据,如果列数据不为0xF<四列>,就有一列键被按下 */
    /* 根据前面的行编号和现在的列编号就可以确定被按下的键                       */
    /****************************************************************************/
    for(i=0x0;i<KEY_LINE_MAX;i++)
    {   c51_key_write(key_line_table[i]);   //* 每一行扫描
        mdata=c51_key_read_lo();
        if( mdata==0xF)
        {   continue;
        }
        pos=0x1;
        for(j=0x0;j<KEY_ROW_MAX;j++)
        {   if((mdata&pos)==0x0)
            {   break;
            }
            pos<<=0x1;
        }
        if(j>=KEY_ROW_MAX)
        {   return 0x0; //* 这儿不可能发生
        }
        else
        {   find=0x1;
            break;
        }
    }
    if( find==0x0)
    {   return 0x0;
    }
    else
    {   return key_table[i][j];
    }
}

/********************************************************************************/
/* fun_name : c51_key_scan_process_jitter()                                     */
/* version  : v1.00                                                             */
/* created  : xillinx                                                           */
/* descript : 键盘扫描到按键按下后需要去抖操作,这个函数处理去抖                 */
/********************************************************************************/
unsigned char c51_key_cur_value=0x0;
unsigned char c51_key_jitter=0x0;
unsigned char c51_key_record=0x0;
unsigned char c51_key_scan_process_jitter(void)
{   unsigned char c51_key_read_lo=0x0;
    c51_key_read_lo=c51_key_scan_operate();
    if( c51_key_cur_value!=c51_key_read_lo) //* 如果这次扫描的数据与上次不一致
    {   c51_key_cur_value=c51_key_read_lo;
        c51_key_jitter=0x0;
        c51_key_record=0x0;
    }
    else
    {   c51_key_jitter++;
    }
    if( c51_key_cur_value==0x0) //* 没有按键按下,不需要统计扫描次数
    {   c51_key_jitter=0x0;
        //key_off_proc();
    }
    if( c51_key_jitter<0x6)     //* 如果没有连续三次扫描到相同的按键,继续扫描
    {   return 0x0;
    }
    if( c51_key_record==0x1)    //* 如果是已经处理的按键还没有释放,一直按着,不处理
    {   return 0x0;
    }
    else
    {   c51_key_record=0x1;     //* 处理新检测的按键
        key_put_on_proc(c51_key_cur_value);
    }
    return c51_key_cur_value;
}


/********************************************************************************/
/* fun_name : c51_key_scan_hi_process()                                         */
/* version  : v1.00                                                             */
/* created  : xillinx                                                           */
/* descript : 扫描独立的四个按键                                                */
/********************************************************************************/
unsigned char key_hi_cur=0x0;
unsigned char key_hi_jit=0x0;
unsigned char key_hi_rec=0x0;
unsigned char key_val=0x0;
unsigned char c51_key_scan_hi_process(void)
{   unsigned char key_read=0x0;
    key_read=c51_key_read_hi();
    if( key_hi_cur!=key_read)       //* 如果这次扫描的数据与上次不一致
    {   key_hi_cur=key_read;
        key_hi_jit=0x0;
        key_hi_rec=0x0;
    }
    else
    {   key_hi_jit++;
    }
    if( key_hi_cur==0xF0)           //* 没有按键按下,不需要统计扫描次数
    {   key_hi_jit=0x0;
        //key_off_proc();
    }
    if( key_hi_jit<0x3)             //* 如果没有连续三次扫描到相同的按键,继续扫描
    {   return 0x0;
    }
    
    if( key_hi_rec==0x1)            //* 如果是已经处理的按键还没有释放,一直按着,不处理
    {   return 0x0;
    }
    if((key_hi_cur&0xF0)==0xE0)     //* 第一个按键按下
    {   key_val = 0x1;
    }
    else if((key_hi_cur&0xF0)==0xD0)//* 第二个按键按下
    {   key_val = 0x2;
    }
    else if((key_hi_cur&0xF0)==0xB0)//* 第三个按键按下
    {   key_val = 0x3;
    }
    else                            //* 第四个按键按下
    {   key_val = 0x4;
    }
    key_hi_rec=0x1;             //* 处理新检测的按键
    key_put_on_proc(key_val);
    
    return key_val;
}

/********************************************************************************/
/* fun_name : c51_key_scan()                                                    */
/* version  : v1.00                                                             */
/* created  : xillinx                                                           */
/* descript : 这个函数需要在定时器里面调用                                      */
/********************************************************************************/
void c51_key_scan(void)
{   unsigned char key_val; 
    if(  KEY_scan_timer==0x0) //* 定时器没有到
    {    return;
    }
    KEY_scan_timer=0x0;
    key_val=c51_key_scan_process_jitter(); //* 8x3=24MS定时器,扫描键盘
    if(  key_val!=0x0)
    {    UART_printf("push key: %c.\r\n",key_val);
    }
    key_val=c51_key_scan_hi_process();
    switch(key_val)
    {
    case 0x1:
         UART_printf("push key: F1.\r\n");
         break;
    case 0x2:
         UART_printf("push key: F2.\r\n");
         break;
    case 0x3:
         UART_printf("push key: F3.\r\n");
         break;
    case 0x4:
         UART_printf("push key: F4.\r\n");
         break;
    default:
         break;
    }
    return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -