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

📄 ps2_m16.c

📁 用单片机ATMEGA16写的PS2键盘驱动程序
💻 C
字号:
#include "PS2_M16.h"

unsigned char cKeyIn;              /* 键值 */
unsigned char cDisNum = 0;         /* 显示用指针 */
unsigned char iBitCount = 0;       /* 中断次数计数 */
unsigned char flg_AllKeyIN = 0;    /* 已收到整个字符标志 */

unsigned char flg_AllKeyIN;        /* 已收到整个字符标志 */
unsigned char flg_KeyDown=0;       /* 键按下标识,1-->按下 */
unsigned char flg_Shift = 0;       /* Shift键按下标识 */
unsigned char cCaps =0;            /* CapsLock状态 */

/* 没有按下{shift}的键值表 */
unsigned char UnShifted[PS2KEYROWMAX][PS2KEYCOLMAX] = {
0x1C, 'a',
0x32, 'b',
0x21, 'c',
0x23, 'd',
0x24, 'e',
0x2B, 'f',
0x34, 'g',
0x33, 'h',
0x43, 'i',
0x3B, 'j',
0x42, 'k',
0x4B, 'l',
0x3A, 'm',
0x31, 'n',
0x44, 'o',
0x4D, 'p',
0x15, 'q',
0x2D, 'r',
0x1B, 's',
0x2C, 't',
0x3C, 'u',
0x2A, 'v',
0x1D, 'w',
0x22, 'x',
0x35, 'y',
0x1A, 'z',
0x45, '0',
0x16, '1',
0x1E, '2',
0x26, '3',
0x25, '4',
0x2E, '5',
0x36, '6',
0x3D, '7',
0x3E, '8',
0x46, '9',
0x0E, '`',
0x4E, '-',
0x55, '=',
0x5D, '\\',
0x29, ' ',
0x54, '[',
0x5B, ']',
0x4C, ';',
0x52, '\'',
0x41, ',',
0x49, '.',
0x4A, '/',
0x71, '.',
0x70, '0',
0x69, '1',
0x72, '2',
0x7A, '3',
0x6B, '4',
0x73, '5',
0x74, '6',
0x6C, '7',
0x75, '8',
0x7D, '9'
};

/* 按下{shift}的键值表 */
unsigned char Shifted[PS2KEYROWMAX][PS2KEYCOLMAX] = {
0x1C, 'A',
0x32, 'B',
0x21, 'C',
0x23, 'D',
0x24, 'E',
0x2B, 'F',
0x34, 'G',
0x33, 'H',
0x43, 'I',
0x3B, 'J',
0x42, 'K',
0x4B, 'L',
0x3A, 'M',
0x31, 'N',
0x44, 'O',
0x4D, 'P',
0x15, 'Q',
0x2D, 'R',
0x1B, 'S',
0x2C, 'T',
0x3C, 'U',
0x2A, 'V',
0x1D, 'W',
0x22, 'X',
0x35, 'Y',
0x1A, 'Z',
0x45, '0',
0x16, '1',
0x1E, '2',
0x26, '3',
0x25, '4',
0x2E, '5',
0x36, '6',
0x3D, '7',
0x3E, '8',
0x46, '9',
0x0E, '~',
0x4E, '_',
0x55, '+',
0x5D, '|',
0x29, ' ',
0x54, '{',
0x5B, '}',
0x4C, ':',
0x52, '"',
0x41, '<',
0x49, '>',
0x4A, '?',
0x71, '.',
0x70, '0',
0x69, '1',
0x72, '2',
0x7A, '3',
0x6B, '4',
0x73, '5',
0x74, '6',
0x6C, '7',
0x75, '8',
0x7D, '9'
};

/*-------------------------------------------------------------------- 
 函数功能:PS2端口初始化
 输    入:无 
 输    出:无 
 调    用: 
 修改日期: 2007.12.28
 作    者:TOM
 备    注:
--------------------------------------------------------------------*/
void   PS2Port_Ini(void)
{
   SFIOR&=~BIT(2);             /* 允许上拉电阻 */    
   PS2CLKDDR&=~(1<<PS2_CLK);   /* CLK I/O输入 */
   PS2DATADDR&=~(1<<PS2_DATA); /* DATA I/O输入 */   
   PS2CLKPORT|=(1<<PS2_CLK);   /* CLK I/O拉高 */   
   
   DDRC&=0x0f;                 /* C高4位 -- 输入 (这里C端口拉高是为了跟3x4键盘兼容) */
   PORTC|=0xf0;
   Delay_nms(50);              /* 延时 */
}

/*-------------------------------------------------------------------- 
 函数功能:中断1初始化
 输    入:无 
 输    出:无 
 调    用: 
 修改日期: 2007.12.28
 作    者:TOM
 备    注:
--------------------------------------------------------------------*/
void Int1_Ini(void)
{
   //GIFR|= (1<<6);  
   GICR|= (1<<7);      /* 使能 Int1 */
    
   MCUCR&= ~(1<<0);    /* Mod Set --低电平方式 */
   MCUCR&= ~(1<<1);   
}

/*-------------------------------------------------------------------- 
 函数功能:中断1中断入口函数
 输    入:无 
 输    出:无 
 调    用: 
 修改日期: 2007.12.28
 作    者:TOM
 备    注:
--------------------------------------------------------------------*/
#pragma interrupt_handler Int1_ISR:iv_INT1
void Int1_ISR(void)
{
   if ((iBitCount > 0) && (iBitCount < 9))
   {			
      cKeyIn = cKeyIn >> 1;                                          /* 因键盘数据是低>>高,结合上一句所以右移一位 */
      if ( PS2DATAPORT_PIN & (1<<PS2_DATA) ) cKeyIn = cKeyIn | 0x80; /* 当键盘数据线为1时,最高位置1 */
   }
   iBitCount++;
	
   while(!(PS2CLKPIN & (1<<PS2_CLK) ));   
   if (iBitCount > 10) 
   {
      iBitCount = 0;      /* 当中断11次后表示一帧数据收完,清变量准备下一次接收 */
      flg_AllKeyIN = 1;   /* 标识有字符输入完了 */
      GICR&= ~(1<<7);     /* 关中断,等显示完后再开中断 (注:如这里不关中断直接调PS2_Decode()则所PS2_Decode中所调用的所有函数要声明为再入函数) */
      //CLI();            /* 因本程序只有这一个中断,所以这句可以注释掉 */
   }  
}

//取得PS2键盘的键值
void PS2_Decode(unsigned char ScanCode) 
{
   unsigned char ckeyNo;   

   if (!flg_KeyDown)            /* 当键盘松开时 flg_KeyDown=0时 */
   {
      switch (ScanCode)
      {
         case 0xF0 :            /*  当收到0xF0,flg_KeyDown置1表示断码开始 */
            flg_KeyDown = 1;
            break;

         case 0x12 :            /*  左 SHIFT */
            flg_Shift = 1;
            break;

         case 0x59 :            /* 右 SHIFT */
            flg_Shift = 1;
            break;
				  
         case 0x58 :            /* CapsLock */
            cCaps = 0x01 & ~(cCaps);
            break;

         default:                  
            if (cDisNum > 17)   /* 从第一行从新开始显示 */
            {
               LCD_Clear(); 	
               cDisNum = 0; 
            }

            if(!flg_Shift)      /* 如果SHIFT没按下 */
            {
               for (ckeyNo = 0;(UnShifted[ckeyNo][0]!=ScanCode)&&(ckeyNo<PS2KEYROWMAX); ckeyNo++);  /* 查表显示 */
               {
                  if (UnShifted[ckeyNo][0] == ScanCode) 
                     if (cCaps==1)		
	                    if (UnShifted[ckeyNo][1]>0x60 && UnShifted[ckeyNo][1]<0x7b)		
                           LCD_WriteData(Shifted[ckeyNo][1]);
                        else
                           LCD_WriteData(UnShifted[ckeyNo][1]);

                     else
                        LCD_WriteData(UnShifted[ckeyNo][1]);
								  
                  cDisNum++;
               }
            } 

            else  /* 按下SHIFT */
            {
               for(ckeyNo = 0; (Shifted[ckeyNo][0]!=ScanCode)&&(ckeyNo<PS2KEYROWMAX); ckeyNo++); /* 查表显示 */
               { 
                  if (Shifted[ckeyNo][0] == ScanCode) 
                     if (cCaps==1)		
                        if (Shifted[ckeyNo][1]>0x40 && Shifted[ckeyNo][1]<0x5b)		
                           LCD_WriteData(UnShifted[ckeyNo][1]);
                        else
                           LCD_WriteData(Shifted[ckeyNo][1]);
								     
                     else
                        LCD_WriteData(Shifted[ckeyNo][1]);
									 
                  cDisNum++;
               }
            }
            break;
      }
   }

   else
   {   
      flg_KeyDown = 0;
      switch (ScanCode)       /* 当键松开时不处理判码,如G 34H F0H 34H 那么第二个34H不会被处理 */
      {
         case 0x12 :          /* 左 SHIFT */
            flg_Shift = 0;
            break;

         case 0x59 :          /* 右 SHIFT */
            flg_Shift = 0;
            break;
      }
   }

   flg_AllKeyIN = 0;         /* 标识字符处理完了 */
} 

⌨️ 快捷键说明

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