📄 key.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 + -