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

📄 main_t.c

📁 利用89S51将6*6键盘转换成PS/2协议
💻 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 + -