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

📄 ps2key.lst

📁 51单片机控制 1602液晶显示 读取PS2键盘程序 按键会在1602上显示所按键
💻 LST
字号:
C51 COMPILER V8.02   PS2KEY                                                                07/17/2008 21:01:34 PAGE 1   


C51 COMPILER V8.02, COMPILATION OF MODULE PS2KEY
OBJECT MODULE PLACED IN PS2Key.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE PS2Key.c BROWSE DEBUG OBJECTEXTEND

line level    source

   1          /*============================================================
   2                  使用1602液晶显示和PS/2键盘的示例  
   3                  -------------------------------------------------
   4                     
   5          ==============================================================
   6          
   7          SMC1602A(16*2)模拟口线接线方式
   8          连接线图:       
   9                 ---------------------------------------------------
  10                 |LCM-----51   |  LCM-----51   |  LCM------51      |
  11                 --------------------------------------------------|
  12                 |DB0-----P0.0 |  DB4-----P0.4 |  RW-------P1.3    |
  13                 |DB1-----P0.1 |  DB5-----P0.5 |  RS-------P1.4    |
  14                 |DB2-----P0.2 |  DB6-----P0.6 |  E--------P1.2    |
  15                 |DB3-----P0.3 |  DB7-----P0.7 |  VLCD接1K电阻到GND|
  16                 ---------------------------------------------------
  17          
  18          Keyboard接线
  19                PS/2--------51
  20                1 DATA------P3.4
  21                3 GND
  22                4 VCC
  23                5 CLK-------P3.3 接在51的外部中断,触发方式为低电平
  24          
  25          
  26          [注:AT89x51使用12M或11.0592M晶振,实测使用11.059M
  27          [Keil uV2 7.01编译运行通过 程序中没有做键盘数据的奇偶校验]
  28          
  29          =============================================================*/
  30          #include <at89x51.h>
  31          #include "scancodes.h"
  32          
  33          #define LCM_RW  P1_3 //定义LCD引脚
  34          #define LCM_RS  P1_4
  35          #define LCM_E   P1_2
  36          #define LCM_Data  P0
  37          
  38          #define Key_Data P3_4 //定义Keyboard引脚
  39          #define Key_CLK  P3_3
  40          
  41          #define Busy    0x80 //用于检测LCM状态字中的Busy标识
  42          
  43          void LCMInit(void);
  44          void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
  45          void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
  46          void Delay5Ms(void);
  47          void Delay400Ms(void);
  48          void Decode(unsigned char ScanCode);
  49          void WriteDataLCM(unsigned char WDLCM);
  50          void WriteCommandLCM(unsigned char WCLCM,BuysC);
  51          
  52          unsigned char ReadDataLCM(void);
  53          unsigned char ReadStatusLCM(void);
  54          unsigned char code cdle_net[] = {"  www.pp51.com  "};
  55          unsigned char code email[] = {"pp51com@163.com"};
C51 COMPILER V8.02   PS2KEY                                                                07/17/2008 21:01:34 PAGE 2   

  56          unsigned char code Cls[] = {"                "};
  57          static unsigned char IntNum = 0; //中断次数计数
  58          static unsigned char KeyV; //键值
  59          static unsigned char DisNum = 0; //显示用指针
  60          static unsigned char Key_UP=0, Shift = 0;//Key_UP是键松开标识,Shift是Shift键按下标识
  61          static unsigned char BF = 0; //标识是否有字符被收到
  62          
  63          void main(void)
  64          {
  65   1              unsigned char TempCyc;
  66   1      
  67   1              Delay400Ms(); //启动等待,等LCM讲入工作状态
  68   1              LCMInit(); //LCM初始化
  69   1              Delay5Ms(); //延时片刻(可不要)
  70   1      
  71   1              DisplayListChar(0, 0, cdle_net);
  72   1              DisplayListChar(0, 1, email);
  73   1              ReadDataLCM();//测试用句无意义
  74   1              for (TempCyc=0; TempCyc<10; TempCyc++)
  75   1                              Delay400Ms(); //延时
  76   1              DisplayListChar(0, 1, Cls);     
  77   1              
  78   1              IT1 = 0; //设外部中断1为低电平触发
  79   1              EA = 1;
  80   1              EX1 = 1; //开中断
  81   1      
  82   1              do
  83   1                      {
  84   2                              if (BF)
  85   2                                      Decode(KeyV);
  86   2                              else
  87   2                                      EA = 1; //开中断
  88   2                      }
  89   1              while(1);
  90   1      }
  91          
  92          //写数据
  93          void WriteDataLCM(unsigned char WDLCM) 
  94          {
  95   1              ReadStatusLCM(); //检测忙
  96   1              LCM_Data = WDLCM;
  97   1              LCM_RS = 1;
  98   1              LCM_RW = 0;
  99   1              LCM_E = 0; //若晶振速度太高可以在这后加小的延时
 100   1              LCM_E = 0; //延时
 101   1              LCM_E = 1;
 102   1      }
 103          
 104          //写指令
 105          void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
 106          {
 107   1              if (BuysC) ReadStatusLCM(); //根据需要检测忙
 108   1              LCM_Data = WCLCM;
 109   1              LCM_RS = 0;
 110   1              LCM_RW = 0;     
 111   1              LCM_E = 0;
 112   1              LCM_E = 0;
 113   1              LCM_E = 1;      
 114   1      }
 115          
 116          //读数据
 117          unsigned char ReadDataLCM(void)
C51 COMPILER V8.02   PS2KEY                                                                07/17/2008 21:01:34 PAGE 3   

 118          {
 119   1              LCM_RS = 1; 
 120   1              LCM_RW = 1;
 121   1              LCM_E = 0;
 122   1              LCM_E = 0;
 123   1              LCM_E = 1;
 124   1              return(LCM_Data);
 125   1      }
 126          
 127          //读状态
 128          unsigned char ReadStatusLCM(void)
 129          {
 130   1              LCM_Data = 0xFF; 
 131   1              LCM_RS = 0;
 132   1              LCM_RW = 1;
 133   1              LCM_E = 0;
 134   1              LCM_E = 0;
 135   1              LCM_E = 1;
 136   1              while (LCM_Data & Busy); //检测忙信号
 137   1              return(LCM_Data);
 138   1      }
 139          
 140          void LCMInit(void) //LCM初始化
 141          {
 142   1              LCM_Data = 0;
 143   1              WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
 144   1              Delay5Ms(); 
 145   1              WriteCommandLCM(0x38,0);
 146   1              Delay5Ms(); 
 147   1              WriteCommandLCM(0x38,0);
 148   1              Delay5Ms(); 
 149   1      
 150   1              WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
 151   1              WriteCommandLCM(0x08,1); //关闭显示
 152   1              WriteCommandLCM(0x01,1); //显示清屏
 153   1              WriteCommandLCM(0x06,1); // 显示光标移动设置
 154   1              WriteCommandLCM(0x0F,1); // 显示开及光标设置
 155   1      }
 156          
 157          //按指定位置显示一个字符
 158          void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
 159          {
 160   1              Y &= 0x1;
 161   1              X &= 0xF; //限制X不能大于15,Y不能大于1
 162   1              if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
 163   1              X |= 0x80; //算出指令码
 164   1              WriteCommandLCM(X, 1); //发命令字
 165   1              WriteDataLCM(DData); //发数据
 166   1      }
 167          
 168          //按指定位置显示一串字符
 169          void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
 170          {
 171   1              unsigned char ListLength;
 172   1      
 173   1        ListLength = 0;
 174   1              Y &= 0x1;
 175   1              X &= 0xF; //限制X不能大于15,Y不能大于1
 176   1              while (DData[ListLength]>0x19) //若到达字串尾则退出
 177   1                      {
 178   2                              if (X <= 0xF) //X坐标应小于0xF
 179   2                                      {
C51 COMPILER V8.02   PS2KEY                                                                07/17/2008 21:01:34 PAGE 4   

 180   3                                              DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
 181   3                                              ListLength++;
 182   3                                              X++;
 183   3                                      }
 184   2                      }
 185   1      }
 186          
 187          //5ms延时
 188          void Delay5Ms(void)
 189          {
 190   1              unsigned int TempCyc = 5552;
 191   1              while(TempCyc--);
 192   1      }
 193          
 194          //400ms延时
 195          void Delay400Ms(void)
 196          {
 197   1              unsigned char TempCycA = 5;
 198   1              unsigned int TempCycB;
 199   1              while(TempCycA--)
 200   1                      {
 201   2                              TempCycB=7269;
 202   2                              while(TempCycB--);
 203   2                      };
 204   1      }
 205          
 206          void Keyboard_out(void) interrupt 2
 207          {
 208   1              if ((IntNum > 0) && (IntNum < 9))
 209   1                      {                       
 210   2                              KeyV = KeyV >> 1; //因键盘数据是低>>高,结合上一句所以右移一位
 211   2                              if (Key_Data) KeyV = KeyV | 0x80; //当键盘数据线为1时为1到最高位
 212   2                      }
 213   1              IntNum++;
 214   1              while (!Key_CLK); //等待PS/2CLK拉高
 215   1      
 216   1              if (IntNum > 10)
 217   1                      {
 218   2                              IntNum = 0; //当中断11次后表示一帧数据收完,清变量准备下一次接收
 219   2                              BF = 1; //标识有字符输入完了
 220   2                              EA = 0; //关中断等显示完后再开中断 (注:如这里不用BF和关中断直接调Decode()则所Decode中所调用的所有函数

⌨️ 快捷键说明

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