📄 key205121.lst
字号:
C51 COMPILER V7.50 KEY205121 12/08/2006 16:53:40 PAGE 1
C51 COMPILER V7.50, COMPILATION OF MODULE KEY205121
OBJECT MODULE PLACED IN key205121.OBJ
COMPILER INVOKED BY: C:\Keil For C51\C51\BIN\C51.EXE key205121.c BROWSE DEBUG OBJECTEXTEND
line level source
1 /*****************************************************************************************
2
3 Version2.1
4 电自院 校松华
5 2005.04.07
6
7 此程序是用AT89C2051来实现键盘电路,用其两个口P34、P35来模仿SPI总线,这样此键盘电路的接线就比较简单
8 这里借鉴两个MCU串行通信的思想,用电平判断来实现握手协议,
9 当键盘电路检测到有按键按下,CLK发一个下降沿去触发主机的中断,然后再发键值:
10 等待主机的回答,主机通过查询方式查询CLK位
11 是否为0,当查到为0是,就将DAT位置0,以示收到。
12 然后下位机就在CLK位的“护送”下,将键值通过DAT位送到主机。
13 主机也是通过CLK位的状态,将键值接受下来的
14 此版本是通过中断方式来实现按键功能的!
15
16 ******************************************************************************************/
17 /******************************************************************************************
18 **版本号:Version3.0
19 **修改人:申红明
20 **日期:2006年12月8日10:28
21 **-----------------------------------------------------------------------------------------
22 **修改内容:(1)3*4键盘通过2051的P1.0~P1.7模拟SPI通信方式,从P3.4(CLK)、P3.5(DAT)口将数据送到
23 EASYARM2100板的P0.13(CLK)和P0.11(DAT)。起初,2051的发送和ARM的接受一直无法实现同
24 步,当本程序全速运行后,一直停在"while(DAT)"处,查看上位机ARM的程序发现问题:
25 在上位机中有如下一段程序:
26 IO0DIR = (IO0DIR&~CLK) | DAT; // DAT is output ,CLK is input
27 IO0CLR = DAT;
28 IO0DIR = IO0DIR & ~DAT; // DAT is input
29 问题出在第二句,在执行完第一句后,DAT变为了output,也许在此句之前,DAT是输入状态
30 的高电平,那么等到执行第三句的时候,DAT又变成了高电平,也就是说,在输出口线上出现
31 低电平的时间极短,下位机很难检测到。修改的方法是在上位机的ARM程序中,将第三句放到
32 时钟脉冲的高电平后执行,也就是说,当CLK信号准备好的时候才开始采样DAT信号,将DAT
33 信号由输出置为输入;
34 (2)当本程的senddata()函数执行结束的时候,CLK变为了低电平,而上位机就是通过查询
35 CLK是否为低电平来判断有没有键按下,所以必须在发送键值函数senddate()执行结束后将CLK
36 拉高,所以在主程序的末尾加上了"CLK=1;DAT=1"这两句,成功实现了上下位机的同步数据传输。
37 *******************************************************************************************/
38 #include <reg51.h>
39 #include <stdio.h>
40 #define uchar unsigned char
41 #define uint unsigned int
42 #define CLK p34
43 #define DAT p35
44
45 sbit p30=P3^0;
46 sbit p31=P3^1;
47 sbit p32=P3^2;
48 sbit p33=P3^3;
49 sbit p34=P3^4;
50 sbit p35=P3^5;
51 sbit p36=P3^6;
52 sbit p37=P3^7;
53 sbit p20=P2^0;
54 sbit p21=P2^1;
55 sbit p22=P2^2;
C51 COMPILER V7.50 KEY205121 12/08/2006 16:53:40 PAGE 2
56 sbit p23=P2^3;
57 sbit p24=P2^4;
58 sbit p25=P2^5;
59 sbit p26=P2^6;
60 sbit p27=P2^7;
61
62 uchar code keycode[12]={0x91,0xa1,0xc1, //1,2,3
63 0x92,0xa2,0xc2, //4,5,6
64 0x94,0xa4,0xc4, //7,8,9
65 0x98,0xa8,0xc8}; //*,0,#
66
67 void delay(uint);
68 uchar scankey(void);
69 void senddata(uchar);
70
71 void main(void)
72 {
73 1 uchar key;
74 1 uchar keyvalue=0;
75 1 while(1)
76 1 { while((key=scankey())==0);
77 2 if(key==keycode[0]) keyvalue=1; //把键码转变为键值,注意‘*’,‘#’的键值!!!
78 2 if(key==keycode[1]) keyvalue=2;
79 2 if(key==keycode[2]) keyvalue=3;
80 2 if(key==keycode[3]) keyvalue=4;
81 2 if(key==keycode[4]) keyvalue=5;
82 2 if(key==keycode[5]) keyvalue=6;
83 2 if(key==keycode[6]) keyvalue=7;
84 2 if(key==keycode[7]) keyvalue=8;
85 2 if(key==keycode[8]) keyvalue=9;
86 2 if(key==keycode[9]) keyvalue=0x0a; //'*'键按下
87 2 if(key==keycode[10]) keyvalue=0; //'0'键按下
88 2 if(key==keycode[11]) keyvalue=0x0b; //'#'键按下
89 2 senddata(keyvalue); //向上位机发送键值
90 2 // CLK=1; //发送完毕,置位时钟信号
91 2 // DAT=1;
92 2 }
93 1 }
94 void delay(uint i)
95 {
96 1 for(i;i>0;i--){;} //这个地方用i-而不用i++,看一下它的汇编就知道它的妙处!!!
97 1 }
98 uchar scankey(void)
99 {
100 1 uchar sccode,recode;
101 1 P1=0xf0;
102 1 if((P1&0xf0)!=0xf0) //有键被按下吗?
103 1 { delay(5000); //有则延时10MS
104 2 if((P1&0xf0)!=0xf0) //键是真的被按下了吗?
105 2 { sccode=0xfe; //是则扫描键码。
106 3 while((sccode&0x10)!=0)
107 3 { P1=sccode;
108 4 if((P1&0xf0)!=0xf0)
109 4 { recode=(P1&0xf0)|0x0f;
110 5 delay(5000);
111 5 while((P1&0xf0)!=0xf0);
112 5 return((~sccode)+(~recode));
113 5 }
114 4 else
115 4 sccode=(sccode<<1)|0x01;
116 4 }
117 3 }
C51 COMPILER V7.50 KEY205121 12/08/2006 16:53:40 PAGE 3
118 2 delay(5000);
119 2 while((P1&0xf0)!=0xf0); //键被放开了吗?没有则等待!!!
120 2 }
121 1 return (0);
122 1 }
123
124 void senddata(uchar i)
125 {
126 1 uchar j;
127 1 CLK=1; //发一个下降沿去触发主机的中断
128 1 delay(2);
129 1 CLK=0;
130 1 delay(2);
131 1
132 1 DAT=1; //先发一个信号给ARM,告知有键被按下,并且开始发键值
133 1 while(DAT); //等待ARM的应答信号!!!
134 1 for(j=0;j<8;j++)
135 1 {
136 2 if((bit)(i&0x80)) DAT=1;
137 2
138 2 else DAT=0;
139 2
140 2 i<<=1;
141 2 CLK=1;
142 2 delay(50);
143 2 CLK=0;
144 2 delay(50);
145 2 }
146 1 CLK=1; //发送完毕,置位时钟信号
147 1 DAT=1;
148 1 }
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 324 ----
CONSTANT SIZE = 12 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = ---- 1
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -