📄 ps2key.lst
字号:
C51 COMPILER V7.01 PS2KEY 03/05/2004 01:41:43 PAGE 1
C51 COMPILER V7.01, 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
5 SMC1602A(16*2)模拟口线接线方式
6 连接线图:
7 ---------------------------------------------------
8 |LCM-----51 | LCM-----51 | LCM------51 |
9 --------------------------------------------------|
10 |DB0-----P1.0 | DB4-----P1.4 | RW-------P2.0 |
11 |DB1-----P1.1 | DB5-----P1.5 | RS-------P2.1 |
12 |DB2-----P1.2 | DB6-----P1.6 | E--------P2.2 |
13 |DB3-----P1.3 | DB7-----P1.7 | VLCD接1K电阻到GND|
14 ---------------------------------------------------
15
16 Keyboard接线
17 PS/2--------51
18 1 DATA------P3.4
19 3 GND
20 4 VCC
21 5 CLK-------P3.3 接在51的外部中断,触发方式为低电平
22
23
24 [注:AT89S51使用12M或11.0592M晶振,实测使用11.0592M]
25 [Keil uV2 7.01编译运行通过 程序中没有做键盘数据的奇偶校验]
26
27 =============================================================*/
28 #include <at89x51.h>
29 #include "scancodes.h"
30
31 #define LCM_RW P2_0 //定义LCD引脚
32 #define LCM_RS P2_1
33 #define LCM_E P2_2
34 #define LCM_Data P1
35
36 #define Key_Data P3_4 //定义Keyboard引脚
37 #define Key_CLK P3_3
38
39 #define Busy 0x80 //用于检测LCM状态字中的Busy标识
40
41 void LCMInit(void);
42 void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
43 void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
44 void Delay5Ms(void);
45 void Delay400Ms(void);
46 void Decode(unsigned char ScanCode);
47 void WriteDataLCM(unsigned char WDLCM);
48 void WriteCommandLCM(unsigned char WCLCM,BuysC);
49
50 unsigned char ReadDataLCM(void);
51 unsigned char ReadStatusLCM(void);
52 unsigned char code cdle_net[] = {"--www.cdle.net--"};
53 unsigned char code email[] = {"pnzwzw@cdle.net"};
54 unsigned char code Cls[] = {" "};
55 static unsigned char IntNum = 0; //中断次数计数
C51 COMPILER V7.01 PS2KEY 03/05/2004 01:41:43 PAGE 2
56 static unsigned char KeyV; //键值
57 static unsigned char DisNum = 0; //显示用指针
58 static unsigned char Key_UP=0, Shift = 0;//Key_UP是键松开标识,Shift是Shift键按下标识
59 static unsigned char BF = 0; //标识是否有字符被收到
60
61 void main(void)
62 {
63 1 unsigned char TempCyc;
64 1
65 1 Delay400Ms(); //启动等待,等LCM讲入工作状态
66 1 LCMInit(); //LCM初始化
67 1 Delay5Ms(); //延时片刻(可不要)
68 1
69 1 DisplayListChar(0, 0, cdle_net);
70 1 DisplayListChar(0, 1, email);
71 1 ReadDataLCM();//测试用句无意义
72 1 for (TempCyc=0; TempCyc<10; TempCyc++)
73 1 Delay400Ms(); //延时
74 1 DisplayListChar(0, 1, Cls);
75 1
76 1 IT1 = 0; //设外部中断1为低电平触发
77 1 EA = 1;
78 1 EX1 = 1; //开中断
79 1
80 1 do
81 1 {
82 2 if (BF)
83 2 Decode(KeyV);
84 2 else
85 2 EA = 1; //开中断
86 2 }
87 1 while(1);
88 1 }
89
90 //写数据
91 void WriteDataLCM(unsigned char WDLCM)
92 {
93 1 ReadStatusLCM(); //检测忙
94 1 LCM_Data = WDLCM;
95 1 LCM_RS = 1;
96 1 LCM_RW = 0;
97 1 LCM_E = 0; //若晶振速度太高可以在这后加小的延时
98 1 LCM_E = 0; //延时
99 1 LCM_E = 1;
100 1 }
101
102 //写指令
103 void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
104 {
105 1 if (BuysC) ReadStatusLCM(); //根据需要检测忙
106 1 LCM_Data = WCLCM;
107 1 LCM_RS = 0;
108 1 LCM_RW = 0;
109 1 LCM_E = 0;
110 1 LCM_E = 0;
111 1 LCM_E = 1;
112 1 }
113
114 //读数据
115 unsigned char ReadDataLCM(void)
116 {
117 1 LCM_RS = 1;
C51 COMPILER V7.01 PS2KEY 03/05/2004 01:41:43 PAGE 3
118 1 LCM_RW = 1;
119 1 LCM_E = 0;
120 1 LCM_E = 0;
121 1 LCM_E = 1;
122 1 return(LCM_Data);
123 1 }
124
125 //读状态
126 unsigned char ReadStatusLCM(void)
127 {
128 1 LCM_Data = 0xFF;
129 1 LCM_RS = 0;
130 1 LCM_RW = 1;
131 1 LCM_E = 0;
132 1 LCM_E = 0;
133 1 LCM_E = 1;
134 1 while (LCM_Data & Busy); //检测忙信号
135 1 return(LCM_Data);
136 1 }
137
138 void LCMInit(void) //LCM初始化
139 {
140 1 LCM_Data = 0;
141 1 WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
142 1 Delay5Ms();
143 1 WriteCommandLCM(0x38,0);
144 1 Delay5Ms();
145 1 WriteCommandLCM(0x38,0);
146 1 Delay5Ms();
147 1
148 1 WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
149 1 WriteCommandLCM(0x08,1); //关闭显示
150 1 WriteCommandLCM(0x01,1); //显示清屏
151 1 WriteCommandLCM(0x06,1); // 显示光标移动设置
152 1 WriteCommandLCM(0x0F,1); // 显示开及光标设置
153 1 }
154
155 //按指定位置显示一个字符
156 void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
157 {
158 1 Y &= 0x1;
159 1 X &= 0xF; //限制X不能大于15,Y不能大于1
160 1 if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
161 1 X |= 0x80; //算出指令码
162 1 WriteCommandLCM(X, 1); //发命令字
163 1 WriteDataLCM(DData); //发数据
164 1 }
165
166 //按指定位置显示一串字符
167 void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
168 {
169 1 unsigned char ListLength;
170 1
171 1 ListLength = 0;
172 1 Y &= 0x1;
173 1 X &= 0xF; //限制X不能大于15,Y不能大于1
174 1 while (DData[ListLength]>0x19) //若到达字串尾则退出
175 1 {
176 2 if (X <= 0xF) //X坐标应小于0xF
177 2 {
178 3 DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
179 3 ListLength++;
C51 COMPILER V7.01 PS2KEY 03/05/2004 01:41:43 PAGE 4
180 3 X++;
181 3 }
182 2 }
183 1 }
184
185 //5ms延时
186 void Delay5Ms(void)
187 {
188 1 unsigned int TempCyc = 5552;
189 1 while(TempCyc--);
190 1 }
191
192 //400ms延时
193 void Delay400Ms(void)
194 {
195 1 unsigned char TempCycA = 5;
196 1 unsigned int TempCycB;
197 1 while(TempCycA--)
198 1 {
199 2 TempCycB=7269;
200 2 while(TempCycB--);
201 2 };
202 1 }
203
204 void Keyboard_out(void) interrupt 2
205 {
206 1 if ((IntNum > 0) && (IntNum < 9))
207 1 {
208 2 KeyV = KeyV >> 1; //因键盘数据是低>>高,结合上一句所以右移一位
209 2 if (Key_Data) KeyV = KeyV | 0x80; //当键盘数据线为1时为1到最高位
210 2 }
211 1 IntNum++;
212 1 while (!Key_CLK); //等待PS/2CLK拉高
213 1
214 1 if (IntNum > 10)
215 1 {
216 2 IntNum = 0; //当中断10次后表示一帧数据收完,清变量准备下一次接收
217 2 BF = 1; //标识有字符输入完了
218 2 EA = 0; //关中断等显示完后再开中断 (注:如这里不用BF和关中断直接调Decode()则所Decode中所调用的所有函数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -