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

📄 keyboard.c

📁 单片机开发资料光盘-双龙-686M.zip
💻 C
字号:
/******************************************/
/*           广州天河双龙电子公司         */
/*           http://www.sl.com.cn         */
/*              PS2键盘驱动程序           */
/*            作者:lpf@sl.com.cn         */
/*               2003年8月28日            */
/*  目标MCU:MEGA16   晶振:外部(EXT) 8MHZ   */
/******************************************/
#include<iom16v.h>
#include<macros.h>
#define PIN_DIR DDRD
#define PIN_KB PIND
#define PORT_KB PORTD
#define CLOCK 3
#define DATAPIN 2
#define BUFF_SIZE 64
#define fosc 8000000
 //晶振8MHZ
#define baud 19200	
 //波特率
#pragma data:code
//设置数据区为程序存储器
//没有按下shift键的PC机键盘扫描码
const unsigned char unshifted[][2] = {
0x0d,9,0x0e,'`',0x15,'q',0x16,'1',0x1a,'z',0x1b,'s',0x1c,'a',0x1d,'w',0x1e,'2',
0x21,'c',0x22,'x',0x23,'d',0x24,'e',0x25,'4',0x26,'3',0x29,' ',0x2a,'v',0x2b,'f',0x2c,'t',0x2d,'r',0x2e,'5',
0x31,'n',0x32,'b',0x33,'h',0x34,'g',0x35,'y',0x36,'6',0x39,',',0x3a,'m',0x3b,'j',0x3c,'u',0x3d,'7',0x3e,'8',
0x41,',',0x42,'k',0x43,'i',0x44,'o',0x45,'0',0x46,'9',0x49,'.',0x4a,'/',0x4b,'l',0x4c,';',0x4d,'p',0x4e,'-',
0x52,0x27,0x54,'[',0x55,'=',0x5a,13, 0x5b,']',0x5d,0x5c,0x61,'<',0x66,8,0x69,'1',0x6b,'4',0x6c,'7',
0x70,'0',0x71,',',0x72,'2',0x73,'5',0x74,'6',0x75,'8',0x79,'+',0x7a,'3',0x7b,'-',0x7c,'*',0x7d,'9',0,0
             };
//按下shift键的PC机键盘扫描码
const unsigned char shifted[][2] = {
0x0d,9,0x0e,'~',0x15,'Q',0x16,'!',0x1a,'Z',0x1b,'S',0x1c,'A',0x1d,'W',0x1e,'@',
0x21,'C',0x22,'X',0x23,'D',0x24,'E',0x25,'$',0x26,'#',0x29,' ',0x2a,'V',0x2b,'F',0x2c,'T',0x2d,'R',0x2e,'%',
0x31,'N',0x32,'B',0x33,'H',0x34,'G',0x35,'Y',0x36,'^',0x39,'L',0x3a,'M',0x3b,'J',0x3c,'U',0x3d,'&',0x3e,'*',
0x41,'<',0x42,'K',0x43,'I',0x44,'O',0x45,')',0x46,'(',0x49,'>',0x4a,'?',0x4b,'L',0x4c,':',0x4d,'P',0x4e,'_',
0x52,'"',0x54,'{',0x55,'+',0x5a,13, 0x5b,'}',0x5d,'|',0x61,'>',0x66,8,0x69,'1',0x6b,'4',0x6c,'7',
0x70,'0',0x71,',',0x72,'2',0x73,'5',0x74,'6',0x75,'8',0x79,'+',0x7a,'3',0x7b,'-',0x7c,'*',0x7d,'9',0,0
};
#pragma data:data
//设置数据区回到数据存储器
unsigned char bitcount;                      //pc键盘数据长度计数
unsigned char kb_buffer[BUFF_SIZE];          //键盘缓冲区
unsigned char input=0;                       //缓冲区读指针
unsigned char output=0;                      //缓冲区写指针
//键盘缓冲区使用软件模拟FIFO
void put_kbbuff(unsigned char c)             //送键盘按键ASCII码到键盘缓冲区
  {
  kb_buffer[input]=c;
  if (input<(BUFF_SIZE-1))
       input++;
  else
       input=0;
  }
unsigned char get_char(void)                //从键盘缓冲区读取按键的ASCII码
  {
  unsigned char temp;
  if (output==input)
         return 0;
  else
         {
         temp=kb_buffer[output];
         if (output<(BUFF_SIZE-1))
              output++;
         else
              output=0;
              return temp;
         }
  }
void uart_init(void)
{
 UCSRB=(1<<RXEN)|(1<<TXEN);                 //允许发送和接收
 UBRRL=(fosc/16/(baud+1))%256;
 UBRRH=(fosc/16/(baud+1))/256;              //波特率19200
 UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);    //8位数据+1位STOP位
}
void putchar(unsigned char c)
	{	 
     while (!(UCSRA&(1<<UDRE)));
	 UDR=c;    
	}
int puts(char *s)
	{
	while (*s)
		{
		putchar(*s);
		s++;
		}	
    putchar(0x0a);                          //回车换行
	putchar(0x0d);
	return 1;
	}
void init_kb(void)
    {
	 PIN_DIR&=~((1<<CLOCK)|(1<<DATAPIN));
	 PORT_KB|=(1<<CLOCK)|(1<<DATAPIN);
	 MCUCR = 0x08; 	
     GICR  = 0x80;
     SEI();
     bitcount = 11;
    }


void decode(unsigned char sc)              //对PC键盘的扫描码进行解码
    {
      static unsigned char shift,up,shiftup;
	  unsigned char i;
	  if (sc==0xf0)                        //按键释放
	      {
		   up=1;
		   return;
		  }
	  if (up==1)                           //SHIFT键开关
	  	  {
		   up=0;
		   if ((sc==0x12)|(sc==0x59)) shift=0;
		   return;
		  }	 
	  switch (sc)                          //检测左SHIFT键
	    {
		 case 0x12:{
					shift=1;		
					shiftup=1;
		           }		           
		 case 0x59:{                        //检测右SHIFT键
				    shift=1;	
					shiftup=1;
		           }		           
		 default:{
		          if (shift==0)
					 {
					 for(i = 0;unshifted[i][0]!=sc && unshifted[i][0]; i++);
                     if (unshifted[i][0] == sc)
						  put_kbbuff(unshifted[i][1]);	 
					 }
				  else
				     {
					 for(i = 0;shifted[i][0]!=sc && shifted[i][0]; i++);
                     if (shifted[i][0] == sc)
                         {
						  put_kbbuff(shifted[i][1]);						  
						 }	 	 						 
					 } 
		         }		         
		} 		
    }
#pragma interrupt_handler int1_isr:iv_INT1    
//键盘数据读取中断程序
void int1_isr(void)
   {
    static unsigned char data;   	
    switch (bitcount)
	  {
	   case 11:{
	            if ((PIN_KB&(1<<DATAPIN))!=0)
				     return;
			    else		 
	   			    bitcount--;
	    		break;}
	   case 2:{
	   			bitcount--;	   		   
			    break;}
	   case 1:{
	   			bitcount--;	 
				if ((PIN_KB&(1<<DATAPIN))==0)
				    {
					 bitcount=11;
					 return;
					}
				else
				   {
				    bitcount=11;
		            decode(data);
				   }	  
	   	        break;}
	   default:{
	   	        data = (data >> 1);
                if((PIN_KB&(1<<DATAPIN))!=0)
                    data|=0x80;
				bitcount--;
	            }		
	  }		 		 	  	
    } 
//PC键盘演示程序,SHIFT键和按键同时按下时为大写
  void main()
  {
  unsigned char key;
  
  uart_init();
  init_kb();
  puts("双龙电子PC键盘演示程序:");
  putchar(0x0d);
  putchar(0x0d);
  while(1)
       {
	  
       key=get_char();
       if (key!=0)
            {
            if (key==0x0d)
                {
                putchar('\n');
                putchar(key);
                }
            else
                putchar(key);
            }
         }
  }

⌨️ 快捷键说明

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