PS2鼠标+LCD12864实验——终于OK 了

抱着“不气馁、不放弃、誓不罢休、搞不定你我还能搞其他玩意吗”的心态,调试许久的PS2鼠标实验,终于在今天被我搞定了。发几张图显摆一下,嘿嘿。。。

                                 左键按下+鼠标移动

                               右键按下+鼠标移动

                                中键按下+鼠标移动

一、程序框架:

大概情况:

1、先由控制模块启动发送模块,把指令0xff发送给鼠标,进入复位模式。

2、发送完后,通知控制模块启动接收模块,接收鼠标应答数据fa、aa、00。

3、接收完后,在次给鼠标发送0xf4,鼠标进入待发数据状态。

4、发送完后,启动接收模块,接收鼠标应答数据fa。

5、回复的数据都OK后,就让程序进入一直处于接收数据状态,每当鼠标按下一次或移动,鼠标都会发送三个字节的数据,提取数据进行解析让在LCD实时显示。

二、鼠标和键盘不管是向鼠标发送数据还是接收数据,都有特定的格式,每一组数据都是一个起始位、8位有效数据、一个校验位、一个停止位。

三、主机到设备时序图:这里注意停止位发送完后,鼠标会在产生一个时钟,并向主机发送一个应答位,在时钟为高时,数据线是从高到底变化的,有点像主机接收设备发送过来的起始信号,伪起始信号,如果这步没处理好,启动接收模块时就会认为此时是一个起始信号,结果接收到的数据把真正起始信号“0”给处理了,我当时就在这里犯错了。主机在发送数据时,是在时钟的下降沿改变数据。

 

发送模块流程:(ps2_clk 和ps2_data 都定义双向端口)

1、拉低时钟,至少要保持100us,程序中设置的是200us,这个时间不是越大约好,从主机拉低时钟到设备真正产生时钟时时间不能大于15MS。

2、200us后,拉低数据线,给鼠标发送请求状态。

3、释放时钟线,link_clk设置为0,让FPGA把该ps2_clk管脚置为高阻态,在高阻态时,该管脚可以接收高低电平,也就成了输入管脚。若设置为1,那么就成了输出管脚。
      assign ps2_clk = link_clk ? ps2_clk_out : 1'bz; 

4、在时钟的下降沿开始发送数据,8bit数据、一位校验位、一位停止位。

5、释放数据线,鼠标发送应答位,link_data设置为0,原理同link_clk。

     assign ps2_data = link_data ? ps2_data_out : 1'bz;

6、等到最后一个时钟产生完,发送完标志产生send_done_sig = 1'b1;

7、马上又进入send_done_sig清零状态,为了下次在送数据做好准备。

注意:释放时钟或释放数据一定要在准确位置释放。

四、设备到主机时序图:

时序比较简单,属于单向通信,设备发,主机只接收。程序中起始位、奇偶校验、停止位都不作处理。这个就不多讲。由于接收模块只作为接收,所以ps2_clk 和ps2_data 都定输入端口。

五、发送、接收和显示都处于待命状态后,由控制模块来协调工作,到这里,对整个控制流程应该很清楚了吧。

代码实现:(由于把所有接收到数据都显示到LCD上,所以有些地方代码写的比较繁琐,暂时先这样吧)

ps2_data_control.v

  1 module ps2_data_control(
  2                          //input 
  3                          sys_clk,
  4                          rst_n, 
  5                          send_done_sig,  //发送完标志
  6                          rx_done_sig,    //接收完标志
  7                          data_buf,        //接收到的数据
  8                          
  9                          //output
 10                          rx_en,            //接收使能
 11                          send_en,        //发送使能
 12                          send_cmd,        //要发送的命令
 13                          dis_data_low1,        //要显示的数据
 14                          dis_data_hig1,
 15                          
 16                          dis_data_low2,        //要显示的数据
 17                          dis_data_hig2,
 18                          
 19                          dis_data_low3,        //要显示的数据
 20                          dis_data_hig3,
 21                          
 22                          dis_data_low4,        //要显示的数据
 23                          dis_data_hig4,
 24                          
 25                          dis_x_low,
 26                          dis_x_hig,
 27                     
 28                          dis_y_low,
 29                          dis_y_hig,
 30                     
 31                          dis_data_btn
 32                          );
 33 input sys_clk;
 34 input rst_n;
 35 input send_done_sig;
 36 input rx_done_sig;
 37 input [7:0] data_buf;
 38 
 39 output rx_en;
 40 output send_en;
 41 output [7:0] send_cmd;
 42 output [7:0] dis_data_low1;
 43 output [7:0] dis_data_hig1;
 44 output [7:0] dis_data_low2;
 45 output [7:0] dis_data_hig2;
 46 output [7:0] dis_data_low3;
 47 output [7:0] dis_data_hig3;
 48 output [7:0] dis_data_low4;
 49 output [7:0] dis_data_hig4;
 50 output [7:0] dis_data_btn;
 51 output [7:0] dis_x_low;
 52 output [7:0] dis_x_hig;
 53 output [7:0] dis_y_low;
 54 output [7:0] dis_y_hig;
 55 /**********************************************************************/
 56 parameter   T100MS        = 23'd4_999_999;
 57 parameter   PS2_RST       = 8'hff;  //复位cmd
 58 parameter   PS2_EN        = 8'hf4;  //数据报告使能cmd
 59 parameter   IDLE          = 4'd0,
 60             SEND_PS2_RST  = 4'd1,
 61             RX_EN1        = 4'd2,
 62             RX_ANSWER_FA  = 4'd3,
 63             RX_ANSWER_AA  = 4'd4,
 64             RX_ANSWER_ID  = 4'd5,
 65             SEND_PS2_EN   = 4'd6,
 66             RX_EN2        = 4'd7,
 67             RX_ANSWER2    = 4'd8,
 68             RX_BYTE1      = 4'd9,
 69             RX_BYTE2      = 4'd10,
 70             RX_BYTE3      = 4'd11,
 71             DELAY         = 4'd12,
 72             STOP          = 4'd13;        
 73 /**********************************************************************/
 74 reg [22:0] cnt;
 75 always @(posedge sys_clk or negedge rst_n)
 76 if(!rst_n)
 77     cnt <= 23'd0;
 78 else if(!cnt_en || cnt == T100MS)
 79     cnt <= 23'd0;
 80 else 
 81     cnt <= cnt + 1'b1;
 82 /**********************************************************************/
 83 reg    send_en;
 84 reg rx_en;
 85 reg [7:0] data_answer;    //保存应答位
 86 reg [7:0] x_move;  //x的偏移量
 87 reg [7:0] y_move;  //y的偏移量
 88 reg [3:0] state;
 89 reg [7:0] dis_data_temp1;
 90 reg [7:0] dis_data_temp2;
 91 reg [7:0] dis_data_temp3;
 92 reg [7:0] dis_data_temp4;
 93 reg [7:0] dis_data_btn;
 94 reg cnt_en;
 95 reg [7:0] send_cmd;
 96 always @(posedge sys_clk or negedge rst_n)
 97 if(!rst_n) begin
 98     send_en <= 1'b0;
 99     rx_en <= 1'b0;
100     data_answer <= 8'h00;
101     state <= IDLE;
102     dis_data_temp1 <= 8'h00;
103     dis_data_temp2 <= 8'h00;
104     dis_data_temp3 <= 8'h00;
105     dis_data_temp4 <= 8'h00;
106     cnt_en <= 1'b0;
107     dis_data_btn <= "X";
108     send_cmd <= 8'h00;
109 end
110 else begin
111     case(state)
112         IDLE: 
113         begin
114             state <= SEND_PS2_RST;
115             cnt_en <= 1'b1;
116         end
117         
118         SEND_PS2_RST: //发送复位 0xff
119         if(cnt == T100MS) begin
120             cnt_en <= 1'b0;
121             send_en <= 1'b1; //启动发送
122             send_cmd <= PS2_RST;
123             state <= RX_EN1;//RX_EN1;
124         end
125         else
126             state <= SEND_PS2_RST;
127         
128         RX_EN1:
129         if(send_done_sig) begin
130             rx_en <= 1'b1;
131             send_en <= 1'b0;
132             state <= RX_ANSWER_FA;
133         end 
134         else
135             state <= RX_EN1;
136         
137         RX_ANSWER_FA:  //接收鼠标发回的应答数据0xfa
138         if(rx_done_sig) begin
139             dis_data_temp1 <= data_buf;
140             state <= RX_ANSWER_AA;//RX_BYTE1;
141         end
142         else
143             state <= RX_ANSWER_FA;
144         
145         RX_ANSWER_AA:  //接收鼠标发回的应答数据0xaa
146         if(rx_done_sig) begin
147             dis_data_temp2 <= data_buf;
148             state <= RX_ANSWER_ID;
149         end
150         else
151             state <= RX_ANSWER_AA;
152         
153         RX_ANSWER_ID:  //接收鼠标发回的应答数据0x00
154         if(rx_done_sig) begin
155             dis_data_temp3 <= data_buf;
156             cnt_en <= 1'b1;
157             rx_en <= 1'b0;
158             state <= SEND_PS2_EN;
159         end
160         else
161             state <= RX_ANSWER_ID;
162         
163         SEND_PS2_EN: //发送0xf4
164         if(cnt == T100MS)begin
165             cnt_en <= 1'b0;
166             send_en <= 1'b1; //启动发送
167             send_cmd <= PS2_EN;
168             state <= RX_EN2;
169         end
170         else
171             state <= SEND_PS2_EN;
172         
173         RX_EN2:
174         if(send_done_sig) begin
175             rx_en <= 1'b1; //启动接收
176             send_en <= 1'b0;
177             state <= RX_ANSWER2;
178         end 
179         else
180             state <= RX_EN2;
181         
182         RX_ANSWER2:  //第二次应答位
183         if(rx_done_sig) begin
184             dis_data_temp4 <= data_buf;
185             state <= RX_BYTE1;
186         end
187         else
188             state <= RX_ANSWER2;
189         
190         RX_BYTE1:
191         if(rx_done_sig) begin
192             if(data_buf[0] == 1'b1)//左键被按下
193                 dis_data_btn <= "L";  
194             else if(data_buf[1] == 1'b1) //右键被按下
195                 dis_data_btn <= "R";  
196             else if(data_buf[2] == 1'b1)  //中键被按下
197                 dis_data_btn <= "M";
198     
199             state <= RX_BYTE2;
200         end
201         else
202             state <= RX_BYTE1;
203         
204         RX_BYTE2:
205         if(rx_done_sig) begin //接收到第二个字节
206             x_move <= data_buf;
207             state <= RX_BYTE3;
208         end
209         else
210             state <= RX_BYTE2;
211         
212         RX_BYTE3:  //接收到第三个字节
213         if(rx_done_sig) begin
214             y_move <= data_buf;
215             state <= STOP;
216             cnt_en <= 1'b1;
217         end 
218         else
219             state <= RX_BYTE3;
220         
221         STOP:
222         if(cnt == T100MS) 
223         begin
224             cnt_en <= 1'b0;
225             state <= RX_BYTE1;
226         end
227         else
228             state <= STOP;
229             
230     endcase
231 end
232 
233 reg [7:0] dis_data_low1;
234 always @(dis_data_temp1[3:0])
235     case(dis_data_temp1[3:0])
236         4'h0: dis_data_low1 = "0";
237         4'h1: dis_data_low1 = "1";
238         4'h2: dis_data_low1 = "2";
239         4'h3: dis_data_low1 = "3";
240         4'h4: dis_data_low1 = "4";
241         4'h5: dis_data_low1 = "5";
242         4'h6: dis_data_low1 = "6";
243         4'h7: dis_data_low1 = "7";
244         4'h8: dis_data_low1 = "8";
245         4'h9: dis_data_low1 = "9";
246         4'ha: dis_data_low1 = "a";
247         4'hb: dis_data_low1 = "b";
248         4'hc: dis_data_low1 = "c";
249         4'hd: dis_data_low1 = "d";
250         4'he: dis_data_low1 = "e";
251         4'hf: dis_data_low1 = "f";
252     endcase
253 
254 reg [7:0] dis_data_hig1;
255 always @(dis_data_temp1[7:4])
256     case(dis_data_temp1[7:4])
257         4'h0: dis_data_hig1 = "0";
258         4'h1: dis_data_hig1 = "1";
259         4'h2: dis_data_hig1 = "2";
260         4'h3: dis_data_hig1 = "3";
261         4'h4: dis_data_hig1 = "4";
262         4'h5: dis_data_hig1 = "5";
263         4'h6: dis_data_hig1 = "6";
264         4'h7: dis_data_hig1 = "7";
265         4'h8: dis_data_hig1 = "8";
266         4'h9: dis_data_hig1 = "9";
267         4'ha: dis_data_hig1 = "a";
268         4'hb: dis_data_hig1 = "b";
269         4'hc: dis_data_hig1 = "c";
270         4'hd: dis_data_hig1 = "d";
271         4'he: dis_data_hig1 = "e";
272         4'hf: dis_data_hig1 = "f";
273     endcase
274     
275 reg [7:0] dis_data_low2;
276 always @(dis_data_temp2[3:0])
277     case(dis_data_temp2[3:0])
278         4'h0: dis_data_low2 = "0";
279         4'h1: dis_data_low2 = "1";
280         4'h2: dis_data_low2 = "2";
281         4'h3: dis_data_low2 = "3";
282         4'h4: dis_data_low2 = "4";
283         4'h5: dis_data_low2 = "5";
284         4'h6: dis_data_low2 = "6";
285         4'h7: dis_data_low2 = "7";
286         4'h8: dis_data_low2 = "8";
287         4'h9: dis_data_low2 = "9";
288         4'ha: dis_data_low2 = "a";
289         4'hb: dis_data_low2 = "b";
290         4'hc: dis_data_low2 = "c";
291         4'hd: dis_data_low2 = "d";
292         4'he: dis_data_low2 = "e";
293         4'hf: dis_data_low2 = "f";
294     endcase
295 
296 reg [7:0] dis_data_hig2;
297 always @(dis_data_temp2[7:4])
298     case(dis_data_temp2[7:4])
299         4'h0: dis_data_hig2 = "0";
300         4'h1: dis_data_hig2 = "1";
301         4'h2: dis_data_hig2 = "2";
302         4'h3: dis_data_hig2 = "3";
303         4'h4: dis_data_hig2 = "4";
304         4'h5: dis_data_hig2 = "5";
305         4'h6: dis_data_hig2 = "6";
306         4'h7: dis_data_hig2 = "7";
307         4'h8: dis_data_hig2 = "8";
308         4'h9: dis_data_hig2 = "9";
309         4'ha: dis_data_hig2 = "a";
310         4'hb: dis_data_hig2 = "b";
311         4'hc: dis_data_hig2 = "c";
312         4'hd: dis_data_hig2 = "d";
313         4'he: dis_data_hig2 = "e";
314         4'hf: dis_data_hig2 = "f";
315     endcase
316 
317 reg [7:0] dis_data_low3;
318 always @(dis_data_temp3[3:0])
319     case(dis_data_temp3[3:0])
320         4'h0: dis_data_low3 = "0";
321         4'h1: dis_data_low3 = "1";
322         4'h2: dis_data_low3 = "2";
323         4'h3: dis_data_low3 = "3";
324         4'h4: dis_data_low3 = "4";
325         4'h5: dis_data_low3 = "5";
326         4'h6: dis_data_low3 = "6";
327         4'h7: dis_data_low3 = "7";
328         4'h8: dis_data_low3 = "8";
329         4'h9: dis_data_low3 = "9";
330         4'ha: dis_data_low3 = "a";
331         4'hb: dis_data_low3 = "b";
332         4'hc: dis_data_low3 = "c";
333         4'hd: dis_data_low3 = "d";
334         4'he: dis_data_low3 = "e";
335         4'hf: dis_data_low3 = "f";
336     endcase
337 
338 reg [7:0] dis_data_hig3;
339 always @(dis_data_temp3[7:4])
340     case(dis_data_temp3[7:4])
341         4'h0: dis_data_hig3 = "0";
342         4'h1: dis_data_hig3 = "1";
343         4'h2: dis_data_hig3 = "2";
344         4'h3: dis_data_hig3 = "3";
345         4'h4: dis_data_hig3 = "4";
346         4'h5: dis_data_hig3 = "5";
347         4'h6: dis_data_hig3 = "6";
348         4'h7: dis_data_hig3 = "7";
349         4'h8: dis_data_hig3 = "8";
350         4'h9: dis_data_hig3 = "9";
351         4'ha: dis_data_hig3 = "a";
352         4'hb: dis_data_hig3 = "b";
353         4'hc: dis_data_hig3 = "c";
354         4'hd: dis_data_hig3 = "d";
355         4'he: dis_data_hig3 = "e";
356         4'hf: dis_data_hig3 = "f";
357     endcase
358     
359 reg [7:0] dis_data_low4;
360 always @(dis_data_temp4[3:0])
361     case(dis_data_temp4[3:0])
362         4'h0: dis_data_low4 = "0";
363         4'h1: dis_data_low4 = "1";
364         4'h2: dis_data_low4 = "2";
365         4'h3: dis_data_low4 = "3";
366         4'h4: dis_data_low4 = "4";
367         4'h5: dis_data_low4 = "5";
368         4'h6: dis_data_low4 = "6";
369         4'h7: dis_data_low4 = "7";
370         4'h8: dis_data_low4 = "8";
371         4'h9: dis_data_low4 = "9";
372         4'ha: dis_data_low4 = "a";
373         4'hb: dis_data_low4 = "b";
374         4'hc: dis_data_low4 = "c";
375         4'hd: dis_data_low4 = "d";
376         4'he: dis_data_low4 = "e";
377         4'hf: dis_data_low4 = "f";
378     endcase
379 
380 reg [7:0] dis_data_hig4;
381 always @(dis_data_temp4[7:4])
382     case(dis_data_temp4[7:4])
383         4'h0: dis_data_hig4 = "0";
384         4'h1: dis_data_hig4 = "1";
385         4'h2: dis_data_hig4 = "2";
386         4'h3: dis_data_hig4 = "3";
387         4'h4: dis_data_hig4 = "4";
388         4'h5: dis_data_hig4 = "5";
389         4'h6: dis_data_hig4 = "6";
390         4'h7: dis_data_hig4 = "7";
391         4'h8: dis_data_hig4 = "8";
392         4'h9: dis_data_hig4 = "9";
393         4'ha: dis_data_hig4 = "a";
394         4'hb: dis_data_hig4 = "b";
395         4'hc: dis_data_hig4 = "c";
396         4'hd: dis_data_hig4 = "d";
397         4'he: dis_data_hig4 = "e";
398         4'hf: dis_data_hig4 = "f";
399     endcase
400 //move x
401 reg [7:0] dis_x_low;
402 always @(x_move[3:0])
403     case(x_move[3:0])
404         4'h0: dis_x_low = "0";
405         4'h1: dis_x_low = "1";
406         4'h2: dis_x_low = "2";
407         4'h3: dis_x_low = "3";
408         4'h4: dis_x_low = "4";
409         4'h5: dis_x_low = "5";
410         4'h6: dis_x_low = "6";
411         4'h7: dis_x_low = "7";
412         4'h8: dis_x_low = "8";
413         4'h9: dis_x_low = "9";
414         4'ha: dis_x_low = "a";
415         4'hb: dis_x_low = "b";
416         4'hc: dis_x_low = "c";
417         4'hd: dis_x_low = "d";
418         4'he: dis_x_low = "e";
419         4'hf: dis_x_low = "f";
420     endcase
421 
422 reg [7:0] dis_x_hig;
423 always @(x_move[7:4])
424     case(x_move[7:4])
425         4'h0: dis_x_hig = "0";
426         4'h1: dis_x_hig = "1";
427         4'h2: dis_x_hig = "2";
428         4'h3: dis_x_hig = "3";
429         4'h4: dis_x_hig = "4";
430         4'h5: dis_x_hig = "5";
431         4'h6: dis_x_hig = "6";
432         4'h7: dis_x_hig = "7";
433         4'h8: dis_x_hig = "8";
434         4'h9: dis_x_hig = "9";
435         4'ha: dis_x_hig = "a";
436         4'hb: dis_x_hig = "b";
437         4'hc: dis_x_hig = "c";
438         4'hd: dis_x_hig = "d";
439         4'he: dis_x_hig = "e";
440         4'hf: dis_x_hig = "f";
441     endcase
442 //move y
443 reg [7:0] dis_y_low;
444 always @(y_move[3:0])
445     case(y_move[3:0])
446         4'h0: dis_y_low = "0";
447         4'h1: dis_y_low = "1";
448         4'h2: dis_y_low = "2";
449         4'h3: dis_y_low = "3";
450         4'h4: dis_y_low = "4";
451         4'h5: dis_y_low = "5";
452         4'h6: dis_y_low = "6";
453         4'h7: dis_y_low = "7";
454         4'h8: dis_y_low = "8";
455         4'h9: dis_y_low = "9";
456         4'ha: dis_y_low = "a";
457         4'hb: dis_y_low = "b";
458         4'hc: dis_y_low = "c";
459         4'hd: dis_y_low = "d";
460         4'he: dis_y_low = "e";
461         4'hf: dis_y_low = "f";
462     endcase
463 
464 reg [7:0] dis_y_hig;
465 always @(y_move[7:4])
466     case(y_move[7:4])
467         4'h0: dis_y_hig = "0";
468         4'h1: dis_y_hig = "1";
469         4'h2: dis_y_hig = "2";
470         4'h3: dis_y_hig = "3";
471         4'h4: dis_y_hig = "4";
472         4'h5: dis_y_hig = "5";
473         4'h6: dis_y_hig = "6";
474         4'h7: dis_y_hig = "7";
475         4'h8: dis_y_hig = "8";
476         4'h9: dis_y_hig = "9";
477         4'ha: dis_y_hig = "a";
478         4'hb: dis_y_hig = "b";
479         4'hc: dis_y_hig = "c";
480         4'hd: dis_y_hig = "d";
481         4'he: dis_y_hig = "e";
482         4'hf: dis_y_hig = "f";
483     endcase
484 endmodule 
485         
View Code

ps2_send_control.v

  1 module ps2_send_control(
  2                         //input 
  3                         sys_clk,
  4                         rst_n,
  5                         send_en,    //发送使能
  6                         send_cmd,  //要发送的数据 0xf4
  7                         
  8                         //output
  9                         send_done_sig,//发送完标志
 10                         
 11                         //inout
 12                         ps2_clk,  //鼠标时钟
 13                         ps2_data  //鼠标数据
 14                        );
 15                        
 16 input  sys_clk;
 17 input  rst_n;
 18 input  send_en;
 19 input  [7:0] send_cmd;
 20 
 21 output send_done_sig;
 22 
 23 inout  ps2_clk;
 24 inout  ps2_data;
 25 /**************************************************************/
 26 parameter T200US = 14'd9999;
 27 parameter IDLE = 3'd0,
 28           PS2_CLK_SET0  = 3'd1,  //时钟拉低
 29           PS2_DATA_SET0 = 3'd2,     //数据拉低
 30           PS2_CLK_SET1  = 3'd3,  //释放时钟,拉高
 31           SEND_DATA     = 3'd4,  //发送8bit数据和校验位
 32           ACK            = 3'd5,  //释放数据,拉高
 33           STOP          = 3'd6,
 34           CLEAR            = 3'd7;
 35 /**************************************************************/
 36 //如果send_data中有偶数个1,那么^send_data结果为0,否则为1,在取反即为奇校验位应设置的值
 37 wire odd_parity;
 38 assign odd_parity = ~(^send_cmd);  
 39 //上面这句,一位网友说是下面的操作方式
 40 //  ~(odd_parity ^send_cmd[0]) -> ~(~(odd_parity ^send_cmd[0]) ^send_cmd[1]) 
 41 //  -> ~(~(~(odd_parity ^send_cmd[0]) ^send_cmd[1]) ^send_cmd[2])... 一次类推
 42 /**************************************************************/
 43 //控制鼠标时钟和数据的方向
 44 //link_clk = 1,ps2_clk为output ,link_clk = 0,ps2_clk为input,FPGA内部得把该管脚设置为高阻态,以便接收时钟
 45 //link_data = 1,ps2_data为output ,link_data = 0,ps2_data为input,FPGA内部得把该管脚设置为高阻态,以便接受数据
 46 assign ps2_clk = link_clk ? ps2_clk_out : 1'bz;  
 47 assign ps2_data = link_data ? ps2_data_out : 1'bz;
 48 /**************************************************************/
 49 //200us计数器
 50 reg [13:0] cnt;
 51 always @(posedge sys_clk or negedge rst_n)
 52 if(!rst_n)
 53     cnt <= 14'd0;
 54 else if(!cnt_en || cnt == T200US)
 55     cnt <= 14'd0;
 56 else 
 57     cnt <= cnt + 1'b1;
 58 /**************************************************************/
 59 reg ps2_clk_n_1;
 60 reg ps2_clk_n_2;
 61 always @(posedge sys_clk or negedge rst_n)
 62 if(!rst_n) begin
 63     ps2_clk_n_1 <= 1'b1;
 64     ps2_clk_n_2 <= 1'b1;
 65 end
 66 else begin
 67     ps2_clk_n_1 <= ps2_clk;
 68     ps2_clk_n_2 <= ps2_clk_n_1;
 69 end
 70 
 71 wire ps2_clk_n;
 72 assign ps2_clk_n = ps2_clk_n_2 & (~ps2_clk_n_1);
 73 /**************************************************************/
 74 reg link_clk;
 75 reg link_data;
 76 reg cnt_en;
 77 reg ps2_clk_out;
 78 reg ps2_data_out;
 79 reg send_done_sig;
 80 reg [2:0] state;
 81 reg [3:0] i;
 82 reg [8:0] s_data;
 83 always @(posedge sys_clk or negedge rst_n)
 84 if(!rst_n) begin
 85     link_clk      <= 1'b0;
 86     link_data     <= 1'b0;
 87     cnt_en        <= 1'b0;
 88     ps2_clk_out   <= 1'b1;
 89     ps2_data_out  <= 1'b1;
 90     send_done_sig <= 1'b0;
 91     state         <= IDLE;
 92     i             <= 4'd0;
 93     s_data        <= 9'd0;
 94 end
 95 else if(send_en) begin
 96     case(state)
 97         IDLE: 
 98         begin
 99             state <= PS2_CLK_SET0;
100             s_data <= /*{1'b0,send_cmd}*/{odd_parity,send_cmd};
101         end
102         
103         PS2_CLK_SET0:
104         begin
105             link_clk <= 1'b1;  //输出状态
106             ps2_clk_out <= 1'b0;
107             cnt_en <= 1'b1;  //启动计数器
108             state <= PS2_DATA_SET0;
109         end
110         
111         PS2_DATA_SET0: 
112         if(cnt == T200US) begin  //200us后 拉低数据线
113             cnt_en <= 1'b0;
114             link_data <= 1'b1;
115             ps2_data_out <= 1'b0;    
116             state <= PS2_CLK_SET1;
117         end
118         else
119             state <= PS2_DATA_SET0;
120         
121         PS2_CLK_SET1:   //释放时钟线
122         begin
123             link_clk <= 1'b0;  //输入状态
124             ps2_clk_out <= 1'b1; 
125             state <= SEND_DATA;
126         end
127         
128         SEND_DATA:
129         if(ps2_clk_n) begin  //在时钟的下降沿设置数据
130             if(i == 4'd9) begin
131                 i <= 4'd0;
132                 link_data <= 1'b1;
133                 ps2_data_out <= 1'b1;  //发送一个停止位
134                 state <= ACK;
135             end
136             else begin
137                 link_data <= 1'b1;
138                 ps2_data_out <= s_data[i];
139                 i <= i + 1'b1;
140                 state <= SEND_DATA;
141             end
142         end
143         else
144             state <= SEND_DATA;
145         
146         ACK:  
147         begin
148             link_data <= 1'b0;  //鼠标应答        
149             state <= STOP;
150         end
151         
152         //鼠标产生数据应答位,同时还会产生最后一个时钟,时钟产生完后,主机发送数据-设备应答 才算完整的结束
153         //如这里不加if(ps2_clk_n)判断条件,接收模块会把真正的起始位采进去,为什么呢,仔细看设备发回的应答数据,
154         //是在时钟为高时,数据拉低,也是相当产生一个起始动作,这是一个伪起始位。
155         //导致后面发送ff命令后,收到的是f4 54 00,发送f4命令后,收到的是f4,按左键显示 R ,右键显示 M ,中键不变化
156         //这里我是通过上面显示数据推断才知道,接收模块会把真正的起始位采进去。
157         STOP:
158         if(ps2_clk_n) begin  
159             send_done_sig <= 1'b1;
160             state <= CLEAR;
161         end
162         else
163             state <= STOP;
164         
165         CLEAR:
166         begin
167             send_done_sig <= 1'b0;
168             state <= IDLE;
169         end
170     endcase 
171 end
172 
173 endmodule
View Code

ps2_rx_control.v

 1 module ps2_rx_control(
 2                             //input 
 3                             sys_clk,
 4                             rst_n,
 5                             ps2_clk_in,  //鼠标时钟
 6                             ps2_data_in, //鼠标数据
 7                             rx_en,       //接收模块使能信号
 8                             
 9                             //output
10                             rx_done_sig, //接收完标志信号
11                             data_buf     //保存接收到的数据
12                         );
13 input sys_clk;
14 input rst_n;
15 input ps2_clk_in;
16 input ps2_data_in;
17 input rx_en;
18 
19 output rx_done_sig;
20 output [7:0] data_buf;
21 /**************************************************************/
22 reg ps2_clk_in_1;
23 reg ps2_clk_in_2;
24 wire ps2_clk_in_n;
25 always @(posedge sys_clk or negedge rst_n)
26 if(!rst_n) begin
27     ps2_clk_in_1 <= 1'b1;
28     ps2_clk_in_2 <= 1'b1;
29 end
30 else begin
31     ps2_clk_in_1 <= ps2_clk_in;
32     ps2_clk_in_2 <= ps2_clk_in_1;
33 end
34 
35 assign ps2_clk_in_n = ps2_clk_in_2 & (~ps2_clk_in_1);
36 /**************************************************************/
37 reg [3:0] i;
38 reg [7:0] data_buf;
39 reg rx_done_sig;
40 always @(posedge sys_clk or negedge rst_n)
41 if(!rst_n) begin
42     i <= 4'd0;
43     data_buf <= 8'h00;
44     rx_done_sig <= 1'b0;
45 end
46 else if(rx_en) begin  //ps2_clk_in_n不能写在这个地方,rx_done_sig置1和置0没必要等到ps2_clk_in下降沿时设置,否则会出问题
47     case(i)
48         4'd0:
49         if(ps2_clk_in_n) begin
50             i <= i + 1'b1;
51         end
52         
53         4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd8: //接收8位数据
54         if(ps2_clk_in_n) begin
55             i <= i + 1'b1;
56             data_buf[i- 1] <= ps2_data_in;
57         end
58 
59         4'd9: 
60         if(ps2_clk_in_n)
61             i <= i + 1'b1;  //奇校验位不处理
62     
63         4'd10:
64         if(ps2_clk_in_n)
65             i <= i + 1'b1;    //停止位不处理
66         
67         4'd11: 
68         begin
69             rx_done_sig <= 1'b1;  //标志着一帧数据接收完
70             i <= i + 1'b1;
71         end
72         
73         4'd12:
74         begin
75             rx_done_sig <= 1'b0;  //置0,给下次接收做好准备
76             i <= 4'd0;
77         end
78     endcase
79 end
80 
81 endmodule
82 
83         
View Code

LCD12864.v

  1 module LCD12864(
  2                     //input 
  3                     sys_clk,
  4                     rst_n,
  5                     dis_data_low1,
  6                     dis_data_hig1,
  7 
  8                     dis_data_low2,
  9                     dis_data_hig2,
 10 
 11                     dis_data_low3,
 12                     dis_data_hig3,
 13                     
 14                     dis_data_low4,
 15                     dis_data_hig4,
 16                     
 17                     dis_data_btn,
 18                     
 19                     dis_x_low,
 20                     dis_x_hig,
 21                     
 22                     dis_y_low,
 23                     dis_y_hig,
 24                     
 25                     //output 
 26                     lcd_rs,
 27                     lcd_rw,
 28                     lcd_en,
 29                     lcd_data,
 30                     lcd_psb
 31                 );
 32 input sys_clk;// 50MHZ
 33 input rst_n;
 34 input [7:0] dis_data_low1;
 35 input [7:0] dis_data_hig1;
 36 input [7:0] dis_data_low2;
 37 input [7:0] dis_data_hig2;
 38 input [7:0] dis_data_low3;
 39 input [7:0] dis_data_hig3;
 40 input [7:0] dis_data_low4;
 41 input [7:0] dis_data_hig4;
 42 input [7:0] dis_x_low;
 43 input [7:0] dis_x_hig;
 44 input [7:0] dis_y_low;
 45 input [7:0] dis_y_hig;
 46 
 47 input [7:0] dis_data_btn;
 48 
 49 output lcd_rs;//H:data    L:command
 50 output lcd_rw;//H:read module    L:write module
 51 output lcd_en;//H active
 52 output [7:0] lcd_data;
 53 output lcd_psb;//H:parallel    module    L:SPI module
 54 
 55 /***************************************************/
 56 parameter T3MS = 18'd149_999;
 57 parameter    IDLE           = 5'd0,
 58             INIT_FUN_SET1 = 5'd1,
 59             INIT_FUN_SET2 = 5'd2,
 60             INIT_DISPLAY  = 5'd3,
 61             INIT_CLEAR       = 5'd4,
 62             INIT_DOT_SET  = 5'd5,
 63             SET_DDRAM      = 5'd6,
 64             WRITE_DATA0      = 5'd7,
 65             WRITE_DATA1   = 5'd8,
 66             WRITE_DATA2   = 5'd9,
 67             WRITE_BLANK1  = 5'd10,
 68             WRITE_DATA3   = 5'd11,
 69             WRITE_DATA4   = 5'd12,
 70             WRITE_BLANK2  = 5'd13,
 71             WRITE_DATA5   = 5'd14,
 72             WRITE_DATA6   = 5'd15,
 73             SET_DDRAM1    = 5'd16,
 74             WRITE_DATA7   = 5'd17,
 75             WRITE_DATA8   = 5'd18,
 76             WRITE_DATA9   = 5'd19,
 77             SET_DDRAM2    = 5'd20,
 78             WRITE_DATA10  = 5'd21,
 79             WRITE_DATA11  = 5'd22,
 80             WRITE_BLANK3  = 5'd23,
 81             VALUE_X_HIG   = 5'd24,
 82             VALUE_X_LOW   = 5'd25,
 83             WRITE_BLANK4  = 5'd26,
 84             VALUE_Y_HIG   = 5'd27,
 85             VALUE_Y_LOW   = 5'd28,
 86             WRITE_BLANK5  = 5'd29,
 87             WRITE_BLANK6  = 5'd30;
 88 
 89 /***************************************************/
 90 //产生周期为6MS的lcd_clk给LCD
 91 reg [17:0] cnt;
 92 reg lcd_clk;
 93 always @(posedge sys_clk or negedge rst_n)
 94 if(!rst_n) begin
 95     cnt <= 18'd0;
 96     lcd_clk <= 1'b0;
 97 end
 98 else if(cnt == T3MS)begin
 99     cnt <= 18'd0;
100     lcd_clk <= ~lcd_clk;
101 end
102 else
103     cnt <= cnt + 1'b1;
104 
105 /***************************************************/
106 reg lcd_rs;
107 always @(posedge lcd_clk or negedge rst_n)
108 if(!rst_n)
109     lcd_rs <= 1'b0;
110 else if(   (state == WRITE_DATA1)  || (state == WRITE_DATA2) 
111         || (state == WRITE_DATA3)  || (state == WRITE_DATA4)
112         || (state == WRITE_DATA5)  || (state == WRITE_DATA6)
113         || (state == WRITE_DATA7)  || (state == WRITE_DATA8)
114         || (state == WRITE_DATA9)  || (state == WRITE_DATA10)
115         || (state == WRITE_DATA11) || (state == WRITE_DATA0)
116         || (state == VALUE_X_HIG)  || (state == VALUE_X_LOW)
117         || (state == VALUE_Y_HIG) || (state == VALUE_Y_LOW)
118         ||(state == WRITE_BLANK1)  || (state == WRITE_BLANK2)
119         ||(state == WRITE_BLANK3)  || (state == WRITE_BLANK4)
120         ||(state == WRITE_BLANK5)  || (state == WRITE_BLANK6))
121     lcd_rs <= 1'b1;        //写数据模式
122 else
123     lcd_rs <= 1'b0;        //写命令模式
124 /***************************************************/
125 reg [4:0] state;
126 reg [7:0] lcd_data;
127 reg [6:0] num;
128 reg en;
129 reg line_flag;
130 always @(posedge lcd_clk or negedge rst_n)
131 if(!rst_n) begin
132     state <= IDLE;
133     lcd_data <= 8'h00;
134     en <= 1'b1;
135     num <= 6'd0;
136     line_flag <= 1'b0;
137 end    
138 else 
139     case(state)
140         IDLE: 
141         begin
142             state <= INIT_FUN_SET1;
143             lcd_data <= 8'hzz;
144             en <= 1'b1;
145         end
146         
147         INIT_FUN_SET1: 
148         begin
149             lcd_data <= 8'h30;    //功能设定
150             state <= INIT_FUN_SET2;
151         end 
152         
153         INIT_FUN_SET2:
154         begin
155             lcd_data <= 8'h30;    //功能设定
156             state <= INIT_DISPLAY;
157         end
158             
159         INIT_DISPLAY:
160         begin
161             lcd_data <= 8'h0c;    //显示设定
162             state <= INIT_CLEAR;
163         end
164             
165         INIT_CLEAR:
166         begin
167             lcd_data <= 8'h01;    //清屏
168             state <= INIT_DOT_SET;
169         end
170         
171         INIT_DOT_SET:
172         begin
173             lcd_data <= 8'h06;    //进入点设定
174             state <= SET_DDRAM;
175         end
176         
177         SET_DDRAM:
178         begin
179             if(!line_flag) begin
180                 lcd_data <= 8'h82;//1 line
181             end
182             else begin
183                 lcd_data <= 8'h90;//2 line
184                 line_flag <= 1'b0;
185             end
186             
187             state <= WRITE_DATA0;
188         end
189         
190         WRITE_DATA0:  ////ff应答::
191         begin
192             num <= num + 1'b1;
193             lcd_data <= dis_data;
194             if(num == 7'd9) begin
195                 line_flag <= 1'b1;
196                 state <= SET_DDRAM;
197             end
198             else if(num == 7'd16)
199                 state <= WRITE_DATA1;
200             else begin
201                 state <= WRITE_DATA0;  
202             end
203         end
204         
205         WRITE_DATA1: //回应的第一个数据高字节
206         begin
207             lcd_data <= dis_data_hig1;
208             state <= WRITE_DATA2;  
209         end
210         
211         WRITE_DATA2://回应的第一个数据低字节
212         begin
213             lcd_data <= dis_data_low1;
214             state <= WRITE_BLANK1;  
215         end
216         
217         WRITE_BLANK1:  //写一个空格
218         begin
219             lcd_data <= " ";
220             state <= WRITE_DATA3;  
221         end
222         
223         WRITE_DATA3: //回应的第二个数据高字节
224         begin
225             lcd_data <= dis_data_hig2;
226             state <= WRITE_DATA4;  
227         end
228         
229         WRITE_DATA4://回应的第二个数据低字节
230         begin
231             lcd_data <= dis_data_low2;
232             state <= WRITE_BLANK2;  
233         end
234         
235         WRITE_BLANK2:  //写一个空格
236         begin
237             lcd_data <= " ";
238             state <= WRITE_DATA5;  
239         end
240         
241         WRITE_DATA5: //回应的第三个数据高字节
242         begin
243             lcd_data <= dis_data_hig3;
244             state <= WRITE_DATA6;  
245         end
246         
247         WRITE_DATA6://回应的第三个数据低字节
248         begin
249             lcd_data <= dis_data_low3;
250             state <= SET_DDRAM1;  
251         end
252         
253         SET_DDRAM1:
254         begin
255             lcd_data <= 8'h88;//3 line            
256             state <= WRITE_DATA7;
257         end
258         
259         WRITE_DATA7:  //f4应答
260         begin
261             if(num == 7'd24) begin
262                 state <= WRITE_DATA8;
263             end
264             else begin
265                 num <= num + 1'b1;
266                 lcd_data <= dis_data;
267                 state <= WRITE_DATA7;  
268             end
269         end
270         
271         WRITE_DATA8: //第二次回应的高字节
272         begin
273             lcd_data <= dis_data_hig4;
274             state <= WRITE_DATA9;  
275         end
276         
277         WRITE_DATA9://第二次回应的低字节
278         begin
279             lcd_data <= dis_data_low4;
280             state <= SET_DDRAM2;  
281         end
282         
283         SET_DDRAM2:
284         begin
285             lcd_data <= 8'h98;//4 line            
286             state <= WRITE_DATA10;
287         end
288         
289         WRITE_DATA10:
290         begin
291             if(num == 7'd29) begin
292                 num <= 7'd0;
293                 state <= WRITE_DATA11;
294             end
295             else begin
296                 num <= num + 1'b1;
297                 lcd_data <= dis_data;
298                 state <= WRITE_DATA10;
299             end
300         end
301         
302         WRITE_DATA11:
303         begin
304             lcd_data <= dis_data_btn;
305             state <= WRITE_BLANK3;
306         end
307         
308         WRITE_BLANK3:
309         begin
310             lcd_data <= " ";
311             state <= WRITE_BLANK4;
312         end
313         
314         WRITE_BLANK4:
315         begin
316             lcd_data <= "(";
317             state <= VALUE_X_HIG;
318         end
319         
320         VALUE_X_HIG:
321         begin
322             lcd_data <= dis_x_hig;
323             state <= VALUE_X_LOW;
324         end
325         
326         VALUE_X_LOW:
327         begin
328             lcd_data <= dis_x_low;
329             state <= WRITE_BLANK5;
330         end
331         
332         WRITE_BLANK5:
333         begin
334             lcd_data <= " ";
335             state <= VALUE_Y_HIG;
336         end
337         
338         VALUE_Y_HIG:
339         begin
340             lcd_data <= dis_y_hig;
341             state <= VALUE_Y_LOW;
342         end
343         
344         VALUE_Y_LOW:
345         begin
346             lcd_data <= dis_y_low;
347             state <= WRITE_BLANK6;
348         end
349         
350         WRITE_BLANK6:
351         begin
352             lcd_data <= ")";
353             state <= SET_DDRAM;
354         end
355 /*        STOP: 
356         begin
357             en <= 1'b0;//显示完了,lcd_e就一直拉为低
358             state <= STOP;
359         end   */
360         
361         default: state <= IDLE;
362     endcase
363 
364 reg [7:0] dis_data;
365 always @(posedge sys_clk or negedge rst_n)
366 if(!rst_n)
367     dis_data <= 8'hzz;
368 else
369     case(num)
370     //ps2 Mouse
371     7'd0   :    dis_data <= "P";
372     7'd1   :    dis_data <= "S";
373     7'd2   :    dis_data <= "2";
374     7'd3   :    dis_data <= " ";
375     7'd4   :    dis_data <= "M";
376     7'd5   :    dis_data <= "o";
377     7'd6   :    dis_data <= "u";
378     7'd7   :    dis_data <= "s";
379     7'd8   :    dis_data <= "e";
380     7'd9   :    dis_data <= " ";
381     //ff应答:
382     7'd10  :    dis_data <= "f";//8'h66; 
383     7'd11  :    dis_data <= "f";//8'h66; 
384     7'd12  :    dis_data <= 8'hd3; 
385     7'd13  :    dis_data <= 8'ha6; 
386     7'd14  :    dis_data <= 8'hb4;
387     7'd15  :    dis_data <= 8'hf0;
388     7'd16  :    dis_data <= " ";
389     //f4应答:
390     7'd17  :    dis_data <= "f";
391     7'd18  :    dis_data <= "4";
392     7'd19  :    dis_data <= 8'hd3;
393     7'd20  :    dis_data <= 8'ha6;
394     7'd21  :    dis_data <= 8'hb4;
395     7'd22  :    dis_data <= 8'hf0;
396     7'd23  :    dis_data <= " ";
397     //按键:
398     7'd24  :    dis_data <= 8'hb0; 
399     7'd25  :    dis_data <= 8'hb4; 
400     7'd26  :    dis_data <= 8'hbc; 
401     7'd27  :    dis_data <= 8'hfc;
402     7'd28  :    dis_data <= " ";
403     default:    dis_data <= 8'h00;
404     endcase
405 /***************************************************/
406 assign lcd_rw = 1'b0;//只有写模式
407 assign lcd_psb = 1'b1;//并口模式
408 assign lcd_en = en ?  lcd_clk : 1'b0;
409 /***************************************************/
410 endmodule
View Code

ps2_mouse_top.v

  1 module  ps2_mouse_top(
  2                         //input 
  3                         sys_clk,
  4                         rst_n,
  5                         
  6                         //inout
  7                         ps2_clk,
  8                         ps2_data,
  9                         
 10                         //output
 11                         lcd_rs,
 12                         lcd_rw,
 13                         lcd_en,
 14                         lcd_data,
 15 //                        lcd_psb
 16                      );
 17 
 18                      
 19 input  sys_clk;
 20 input  rst_n;        
 21             
 22 inout  ps2_clk;
 23 inout  ps2_data;
 24 
 25 output lcd_rs;//H:data    L:command
 26 output lcd_rw;//H:read module    L:write module
 27 output lcd_en;//H active
 28 output [7:0] lcd_data;
 29 //output lcd_psb;//H:parallel    module    L:SPI module
 30 
 31 wire send_done_sig;
 32 wire rx_done_sig;
 33 wire [7:0] data_buf;
 34 wire rx_en;
 35 wire send_en;
 36 wire [7:0] send_cmd;
 37 wire [7:0] dis_data_low1;
 38 wire [7:0] dis_data_hig1;
 39 wire [7:0] dis_data_low2;
 40 wire [7:0] dis_data_hig2;
 41 wire [7:0] dis_data_low3;
 42 wire [7:0] dis_data_hig3;
 43 wire [7:0] dis_data_low4;
 44 wire [7:0] dis_data_hig4;
 45 wire [7:0] dis_data_btn;
 46 wire [7:0] dis_x_low;
 47 wire [7:0] dis_x_hig;                
 48 wire [7:0] dis_y_low;
 49 wire [7:0] dis_y_hig;
 50 //控制模块例化
 51 ps2_data_control     u1_control(
 52                          //input 
 53                          .sys_clk(sys_clk),
 54                          .rst_n(rst_n), 
 55                          .send_done_sig(send_done_sig),  //发送完标志
 56                          .rx_done_sig(rx_done_sig),    //接收完标志
 57                          .data_buf(data_buf),        //接收到的数据
 58                          
 59                          //output
 60                          .rx_en(rx_en),            //接收使能
 61                          .send_en(send_en),        //发送使能
 62                          .send_cmd(send_cmd),        //要发送的命令
 63                          .dis_data_low1(dis_data_low1),        //要显示的数据
 64                          .dis_data_hig1(dis_data_hig1),
 65                          
 66                          .dis_data_low2(dis_data_low2),        //要显示的数据
 67                          .dis_data_hig2(dis_data_hig2),
 68                          
 69                          .dis_data_low3(dis_data_low3),        //要显示的数据
 70                          .dis_data_hig3(dis_data_hig3),
 71                          
 72                          .dis_data_low4(dis_data_low4),        //要显示的数据
 73                          .dis_data_hig4(dis_data_hig4),
 74                          
 75                          .dis_x_low(dis_x_low),
 76                          .dis_x_hig(dis_x_hig),
 77                          
 78                          .dis_y_low(dis_y_low),
 79                          .dis_y_hig(dis_y_hig),
 80                          
 81                          .dis_data_btn(dis_data_btn)
 82                          );
 83 //显示模块例化
 84 LCD12864    u2_lcd(
 85                     //input 
 86                     .sys_clk(sys_clk),
 87                     .rst_n(rst_n),
 88                     .dis_data_low1(dis_data_low1),        //要显示的数据
 89                     .dis_data_hig1(dis_data_hig1),
 90                     
 91                     .dis_data_low2(dis_data_low2),        //要显示的数据
 92                     .dis_data_hig2(dis_data_hig2),
 93                     
 94                     .dis_data_low3(dis_data_low3),        //要显示的数据
 95                     .dis_data_hig3(dis_data_hig3),
 96                     
 97                     .dis_data_low4(dis_data_low4),        //要显示的数据
 98                     .dis_data_hig4(dis_data_hig4),
 99                         
100                     .dis_x_low(dis_x_low),
101                     .dis_x_hig(dis_x_hig),
102                     
103                     .dis_y_low(dis_y_low),
104                     .dis_y_hig(dis_y_hig),
105                     
106                     .dis_data_btn(dis_data_btn),
107                     
108                     //output 
109                     .lcd_rs(lcd_rs),
110                     .lcd_rw(lcd_rw),
111                     .lcd_en(lcd_en),
112                     .lcd_data(lcd_data),
113 //                    .lcd_psb(lcd_psb)
114                 );
115 //发送模块例化                         
116 ps2_send_control     u3_send(
117                         //input 
118                         .sys_clk(sys_clk),
119                         .rst_n(rst_n),
120                         .send_en(send_en),    //发送使能
121                         .send_cmd(send_cmd),  //要发送的命令 0xf4
122                         
123                         //output
124                         .send_done_sig(send_done_sig),//发送完标志
125                         
126                         //inout
127                         .ps2_clk(ps2_clk),  //鼠标时钟
128                         .ps2_data(ps2_data) //鼠标数据
129                        );
130 //接收模块例化                       
131 ps2_rx_control    u4_rx(
132                             //input 
133                             .sys_clk(sys_clk),
134                             .rst_n(rst_n),
135                             .ps2_clk_in(ps2_clk),  //鼠标时钟
136                             .ps2_data_in(ps2_data), //鼠标数据
137                             .rx_en(rx_en),       //接收模块使能信号
138                             
139                             //output
140                             .rx_done_sig(rx_done_sig), //接收完标志信号
141                             .data_buf(data_buf)     //保存接收到的数据
142                         );
143 endmodule
View Code

总结:

1、上个试验“PS2鼠标+LCD12864实验(调试未成功)”,为什么没有调试成功呢,主要还是细节没注意,要彻底弄清楚每个时钟节拍会做什么动作,尤其是到了一组数据发送完后,一些应答位停止位可以不关心,但一定得知道到它何时产生,在哪变化,只有清楚了每一个细节后,成功才会向你招手。

2、遇到困难时,不要气馁,但反复检查代码时就是没有发现问题,此时应该好好休息一下,因为大脑已经陷入了僵局状态,很难找到问题,且耽误时间,打击自个的信心。

>>>>在ps2_send_control.v中,奇偶校验理解的不对,详细介绍见奇偶校验位产生器

转载于:https://www.cnblogs.com/wen2376/p/3389512.html

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值