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

📄 ps2key.lst

📁 使用1602液晶显示和PS2键盘的示例,单片机接收PS2键盘键号显示到LCD上
💻 LST
字号:
C51 COMPILER V6.12  PS2KEY                                                                 04/12/2006 14:55:23 PAGE 1   


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

stmt level    source

   1          /*============================================================
   2                  使用1602液晶显示和PS/2键盘的示例     明浩  2004/2
   3                  -------------------------------------------------
   4                     http://www.cdle.net  http://bbs.cdle.net
   5          ==============================================================
   6          
   7          SMC1602A(16*2)模拟口线接线方式
   8          连接线图:	
   9                 ---------------------------------------------------
  10                 |LCM-----51   |	LCM-----51   |	LCM------51      |
  11                 --------------------------------------------------|
  12                 |DB0-----P1.0 |	DB4-----P1.4 |	RW-------P2.0    |
  13                 |DB1-----P1.1 |	DB5-----P1.5 |	RS-------P2.1    |
  14                 |DB2-----P1.2 |	DB6-----P1.6 |	E--------P2.2    |
  15                 |DB3-----P1.3 |	DB7-----P1.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          
  27          [注:AT89x51使用12M或11.0592M晶振,实测使用11.0592M]
  28          [Keil uV2 7.01编译运行通过 程序中没有做键盘数据的奇偶校验]
  29          
  30          =============================================================*/
  31          #include <at89x51.h>
  32          #include "scancodes.h"
  33          
  34          #define LCM_RW  P2_0 //定义LCD引脚
  35          #define LCM_RS  P2_1
  36          #define LCM_E   P2_2
  37          #define LCM_Data  P1
  38          
  39          #define Key_Data P3_4 //定义Keyboard引脚
  40          #define Key_CLK  P3_3
  41          
  42          #define Busy    0x80 //用于检测LCM状态字中的Busy标识
  43          
  44          void LCMInit(void);
  45          void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
  46          void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
  47          void Delay5Ms(void);
  48          void Delay400Ms(void);
  49          void Decode(unsigned char ScanCode);
  50          void WriteDataLCM(unsigned char WDLCM);
  51          void WriteCommandLCM(unsigned char WCLCM,BuysC);
  52          
  53          unsigned char ReadDataLCM(void);
  54          unsigned char ReadStatusLCM(void);
  55          unsigned char code cdle_net[] = {"--www.cdle.net--"};
C51 COMPILER V6.12  PS2KEY                                                                 04/12/2006 14:55:23 PAGE 2   

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

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

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

⌨️ 快捷键说明

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