📄 protocol.lst
字号:
C51 COMPILER V7.06 PROTOCOL 08/18/2008 14:23:14 PAGE 1
C51 COMPILER V7.06, COMPILATION OF MODULE PROTOCOL
OBJECT MODULE PLACED IN protocol.OBJ
COMPILER INVOKED BY: D:\Program Files\Keil\C51\BIN\C51.EXE protocol.c BROWSE DEBUG OBJECTEXTEND
stmt level source
1 //接收子函数
2 #include <head.c>
3 #include <math.h>
4 volatile unsigned char bdata s_buf,r_buf; //发送缓冲区、接收缓冲区
5 volatile unsigned char data last_s; //上次发送字节
6 extern bit scan_on; //扫描状态,main_t.c中定义
7 sbit s_buf0=s_buf^0;
8 sbit r_buf7=r_buf^7;
9 //新添加的变量
10 unsigned char data send_delay,delay_count;
11 volatile unsigned char bdata parity_buf;
12 sbit parity_buf0=parity_buf^0;
13 volatile unsigned char data first_delay,old_delay;//拍发速率、延迟时间
14 volatile unsigned char bdata scan_v,temp1,temp2;
15 sbit c0=scan_v^5;
16 sbit c1=scan_v^6;
17 sbit a0=scan_v^0;
18 sbit a1=scan_v^1;
19 sbit a2=scan_v^2;
20 sbit b0=scan_v^3;
21 sbit b1=scan_v^4;
22 sbit temp1_0=temp1^0;
23 sbit temp1_1=temp1^1;
24 sbit temp1_2=temp1^2;
25 sbit temp2_0=temp2^0;
26 sbit temp2_1=temp2^1;
27
28 void set_scan_v(unsigned char vv)//设置扫描速度(拍发速率、延迟时间)
29 //根据PS2协议,通过vv得到延缓时间first_delay和拍发速率old_delay的值
30 //系统缺省设置:拍发速率=10个/s±20%,延时=500ms±20%
31 //根据默认值是SCAN_V_DEFAULT 0x2c 00101100 first_delay=220,old_delay=44
32 /*每计数220个对应延时500ms,每1/440 s计数一次,如果系统频率为11MHz,也就是计数器每计到25000,
33 增加一次计数值send_delay*/
34 {
35 1 scan_v=vv;
36 1 temp1=0;
37 1 temp1_0=c0;
38 1 temp1_1=c1;
39 1 first_delay=(1+temp1)*60;
40 1 first_delay=first_delay/6*Frequence;
41 1 temp1=0;
42 1 temp2=0;
43 1 temp1_0=a0;
44 1 temp1_1=a1;
45 1 temp1_2=a2;
46 1 temp2_0=b0;
47 1 temp2_1=b1;
48 1 old_delay=(8+temp1)*(1<<temp2);
49 1 old_delay=old_delay/6*Frequence;
50 1 /* unsigned char i,j;
51 1 double cps;
52 1 float code repeat_rate[32]={2.0,2.1,2.3,2.5,2.7,3.0,3.3,3.7,4.0,4.3,4.6,5.0,5.5,6.0,6.7,7.5,
53 1 8.0,8.6,9.2,10.0,10.9,12.0,13.3,15.0,16.0,17.1,18.5,20.0,21.8,24.0,26.7,30.0};
54 1 i=(vv>>5)&0x03;
55 1 j=vv&0x1f;
C51 COMPILER V7.06 PROTOCOL 08/18/2008 14:23:14 PAGE 2
56 1 first_delay=(unsigned char)((4/(i+1))*(Frequence/(12*TIMER_COUNT)));
57 1 cps = 1 /((8 + (vv & 0x07)) * exp(log(2) * ((vv >> 3) & 0x03)) * 0.00417);
58 1 // old_delay=(unsigned char)(((repeat_rate[j]))*(Frequence/(12*TIMER_COUNT)));
59 1 */
60 1 }
61
62 void set_default()//设置缺省值
63 {
64 1 KBCLK=1;
65 1 KBDATA=1;
66 1 clr_buf();
67 1 set_scan_v(SCAN_V_DEFAULT);//SCAN_V_DEFAULT==0X2C,在head.c中定义
68 1 }
69
70 bit parity()//计算parity_buf中一个字节的奇偶校验值
71 {
72 1 bit PARITY=1;
73 1 unsigned char data c;
74 1 for(c=0;c<8;c++)
75 1 {
76 2 PARITY^=parity_buf0;
77 2 parity_buf=parity_buf>>1;
78 2 }
79 1 return PARITY;
80 1 }
81
82 void delay()//reentrant //延时24us
83 {
84 1 unsigned char data t=DELAY;
85 1 for(;--t;);
86 1 }
87
88 void sleep() //延时16us
89 {
90 1 unsigned char data t=SLEEP;
91 1 for(;--t;);
92 1 }
93
94 unsigned char receive(void) //接收子函数
95 //返回接收到的字节,接收错误则返回0
96 {
97 1 unsigned char data i;
98 1 bit PARITY;
99 1 ET1=0; //定时器开
100 1 r_buf=0;//清空接收缓存
101 1 while(!KBCLK);//等待KBCLK变高
102 1 delay();
103 1 if(KBDATA) //KBDATA应该为低,表示接收到起始位,如果此时KBDATA为高,
104 1 //则退出并发送错误状态字0xfe
105 1 { send(0xfe);
106 2 return 0;}
107 1 delay();
108 1 sleep();
109 1 KBCLK=0; //KBCLK由键盘控制,产生时钟信号
110 1 for(i=0;i<8;i++)//将KBDATA上的数据在KBCLK的上升沿存入接收缓冲区r_buf7中
111 1 {
112 2 delay();
113 2 sleep();
114 2 KBCLK=1;
115 2 sleep();
116 2 if(!KBCLK) return 0; //如果KBCLK被拉低,表明主机取消发送
117 2 r_buf7=KBDATA;
C51 COMPILER V7.06 PROTOCOL 08/18/2008 14:23:14 PAGE 3
118 2 if(i!=7)
119 2 r_buf=r_buf>>1;
120 2 delay();
121 2 KBCLK=0;
122 2 }
123 1 delay();
124 1 sleep();
125 1 KBCLK=1;
126 1 sleep();
127 1 if(!KBCLK) return 0; //如果KBCLK被拉低,表明主机取消发送
128 1 PARITY=KBDATA; //接收奇偶校验位
129 1 delay();
130 1 KBCLK=0;
131 1 delay();
132 1 sleep();
133 1 KBCLK=1;
134 1 //停止位
135 1 delay();
136 1 if(!KBDATA) {send(0xfe);return 0;}//接收停止位,此时KBDATA应该为高,否则发送0xfe报错
137 1 KBDATA=0;//发送应答位,表明已经收到主机数据
138 1 sleep();
139 1 KBCLK=0;
140 1 sleep();
141 1 delay();
142 1 KBCLK=1;
143 1 sleep();
144 1 KBDATA=1;//将KBCLK和KBDATA置高
145 1 sleep();
146 1 ET1=1; //开中断
147 1 parity_buf=r_buf;
148 1 if(PARITY==parity())
149 1 return r_buf;
150 1 else {send(0xfe);return 0;}//判断奇偶校验位是否正确
151 1 //缺错误处理 *
152 1 //给主机时间抑制下次的通信
153 1 sleep();
154 1 delay();
155 1 }
156
157 bit send(unsigned char c) //发送子函数
158 //返回1表示发送成功,返回0表示发送失败
159 /*当时钟线和数据线均为高电平时,允许键盘发送数据,系统将接收数据;
160 当时钟线被拉为低电平时,表明系统禁止数据传输。发送时序包含1个低
161 电平触发的起始位、8位数据位、1个奇校验位和1个高电平的结束位*/
162 {
163 1 unsigned char data i;
164 1 bit PARITY;
165 1 KBCLK=1;
166 1 if(!KBCLK)//主机禁止键盘发送数据
167 1 return 0;
168 1 ET1=0; //关闭中断
169 1 parity_buf=c;
170 1 PARITY=parity();//计算c的奇偶校验值
171 1 last_s=c; //保存上一次发送字节
172 1 s_buf=c; //发送数据缓冲
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -