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

📄 ps2key.lst

📁 用C51加1602实现键盘测试
💻 LST
字号:
C51 COMPILER V6.12  PS2KEY                                                                 03/01/2007 12:10:18 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 DEBUG OBJECTEXTEND

stmt level    source

*** WARNING C500 IN LINE 1 OF .\PS2KEY.C: MISSING DEVICE (SECURITY KEY NOT FOUND)
   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-----P2.0 |	DB4-----P2.4 |	RW-------P3.7   |
  13                 |DB1-----P2.1 |	DB5-----P2.5 |	RS-------P3.2    |
  14                 |DB2-----P2.2 |	DB6-----P2.6 |	E--------P3.6    |
  15                 |DB3-----P2.3 |	DB7-----P2.7 |	VLCD接1K电阻到GND|
  16                 ---------------------------------------------------
  17          
  18          Keyboard接线
  19                PS/2--------51
  20                1 DATA------P3.3
  21                3 GND
  22                4 VCC
  23                5 CLK-------P0.7 接在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  P3_7//定义LCD引脚
  35          #define LCM_RS  P3_2
  36          #define LCM_E   P3_6
  37          #define LCM_Data  P2
  38          
  39          #define Key_Data P3_3//定义Keyboard引脚
  40          #define Key_CLK  P3_4
  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[] = {"ShangHaiFUNDWELL"};
C51 COMPILER V6.12  PS2KEY                                                                 03/01/2007 12:10:18 PAGE 2   

  55          unsigned char code email[] = {"www.fwsh.com.cn"};
  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          //读数据
C51 COMPILER V6.12  PS2KEY                                                                 03/01/2007 12:10:18 PAGE 3   

 117          unsigned char ReadDataLCM(void)
 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
C51 COMPILER V6.12  PS2KEY                                                                 03/01/2007 12:10:18 PAGE 4   

 179   2      				{
 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 + -