📄 main_t.c
字号:
#include <head.c>
bit scan_on,last_f;
unsigned char data last_key;
extern unsigned char data delay_count,send_delay;
unsigned char bdata clu;
sbit clu0=clu^0;
unsigned char scankb(unsigned char row)
/*
键盘扫描函数,P2.7-P2.3为5条行扫描线,P2.2-P2.0为3条列输出线。每次扫描一行,该行的扫描线为0,其余为1,
返回列输出线的值
*/
{
unsigned char data c;
switch(row)
{
case 0://P0=8'b11111110;
P0=0xFE;
break;
case 1://P0=8'b11111101;
P0=0xFD;
break;
case 2://P0=8'b11111011;
P0=0xFB;
break;
case 3://P0=8'b11110111;
P0=0xF7;
break;
case 4://P0=8'b11101111;
P0=0xEF;
break;
case 5://P0=8'b11101111;
P0=0xDF;
break;
default:
P0=0xff;
break;
}
c=P2&0x3f;//取P2.5-P2.0的列值
P0=0xff;
return c;
}
void scan(void)
/*
函数功能:扫描键状态,将被按键的位置号存入缓冲区中;
连续扫描5行,如果列扫描线输出全为1,表明当前行没有按键按下,继续扫描下一行,否则将记下当前的列输出值,然后延时一段时间(该值可以设定),
再次扫描该行,如果列输出值跟第一次的不一样,则将其判为抖动,不予处理,如果相同则表明当前按键被按下,进行下一步处理。
从列输出线的最低位P2.0开始判断列输出线的该位是否为0,如果为1则表明其对应按键未被按下,不予处理,如果为0则表明当前对应
按键被按下,计算按键对应的位置号并在缓冲区中搜索,判断其是否已在缓冲区中存在。如果缓冲区中没有该按键位置号,则将其加入
缓冲区中,并将位置号写入last_key中,将last_f置1,表明last_key被按下,将发送延时清零。如果缓冲区中已经存在该位置号,则
只需将其按键表示置1,表明其被按下即可。
*/
{
unsigned char data dire,kb_code,clu_temp;
unsigned char data i=0,j=0;
bit l_bit;
// KBSHIFT=1;
for(i=0;i<5;i++) //
{
clu_temp=scankb(i);//返回第一次扫描值
if(clu_temp==0x3F)continue;//消抖处理
set_timer1();
while(delay_count<90)//10ms
{
if(command_s())
{
close_timer1();
return ;//receive_process();
}
}
close_timer1();
clu=scankb(i);
if(clu==0x3F||clu!=clu_temp) continue;
//延时10ms,如果跟第一次采样值不一样,则认为第一次为抖动
for(j=0;j<6;j++) //指示输出列值
{
l_bit=clu0;
clu=clu>>1;
if(l_bit==1) continue;
if(KBSHIFT)
kb_code=i*6+j; //键盘编码自定义0--35//0x23
else
kb_code=i*6+j+36;//0x
dire=exist(kb_code); //检查是不是第一次按下
if(dire==255) //第一次按下
{
last_key=kb_code;
last_f=1;
send_delay=0;
insert(kb_code,1);
}
else
{
set_flag(dire);//将缓冲区中dire所对应的的缓冲单元标识设为1
}
clu=0x3F;
clu_temp=0x3F;
return; //在扫描到按键被按下后将推出,这样每次扫描将只有一个按键被识别,其它被按下的按键将忽略
//这是与普通PC键盘不同的地方,这种做法将不支持组合按键,适合于按键情况比较简单的应用
//这样对缓冲区来说每次只会有一个按键序号被保存,不会出现缓冲区中存在多个按键序号的情况
}
}
}
void main()
{
IP=0;
IE=0x0a;
EA=1;//开中断
if(bat())//自检失败
send(0xfc);
else send(0xaa);
set_default();//设置默认参数
ini_timer1();//计数器1初始化
ini_timer0();
scan_on=1; //允许键盘扫描
while(1)
{
if(command_s())//PC发送命令数据给键盘
receive_process();//处理PC命令
if(scan_on)
scan();
send_buf();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -