此试验我一人调试许久都未成功,但发送ff时,读出来的数据确是对的,一开始让我窃喜,但发送f4时,读出来的数据确是错的,哎让苦恼啊,能力有限,只能先暂时就这样吧,那位什么还要贴出来呢,有两个原因:
1、等自己能力达到一定时,在回过头来,把这个问题解决掉,我相信,一定能实现的。
2、晒出来就是希望能得到各位网友能帮忙指点哪个地方容易出问题。在此先拜谢了!
>>PS2鼠标实验是一个双向通信实验,那就得知道PS2鼠标传输协议,本人觉得自己对PS2传输协议有所掌握(也许理解的还不够到位)。具体传输协议就不多描述,还是看专业的“PS/2 技术参考”。
>>在写代码之前,我参考网上一个例子,链接“http://www.360doc.com/content/13/0612/20/2260882_292421295.shtml”,这位网友例化时,看起来有点累,思路基本能看懂,自己稍微整理了一下,整体框架如下图。
步骤:
1、先由控制模块启动发送模块,把指令“0XF4”发送给鼠标。
2、发送模块发送完后,产生一个发送完标志,传给控制模块,在由控制模块启动接收模块。
3、接收模块接收完数据,产生一个接收完标志,传给控制模块,模块在进行相应的数据处理。
4、数据处理完后,传给显示模块进行显示。
代码实现:
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_data_btn 26 ); 27 input sys_clk; 28 input rst_n; 29 input send_done_sig; 30 input rx_done_sig; 31 input [7:0] data_buf; 32 33 output rx_en; 34 output send_en; 35 output [7:0] send_cmd; 36 output [7:0] dis_data_low1; 37 output [7:0] dis_data_hig1; 38 output [7:0] dis_data_low2; 39 output [7:0] dis_data_hig2; 40 output [7:0] dis_data_low3; 41 output [7:0] dis_data_hig3; 42 output [7:0] dis_data_low4; 43 output [7:0] dis_data_hig4; 44 output [7:0] dis_data_btn; 45 /**********************************************************************/ 46 parameter T100MS = 23'd4_999_999; 47 parameter T500MS = 25'd24_999_999; 48 parameter T100US = 13'd4_999; 49 parameter PS2_RST = 8'hf4; //复位cmd 50 parameter PS2_EN = 8'hf4; //数据报告使能cmd 51 parameter IDLE = 4'd0, 52 SEND_PS2_RST = 4'd1, 53 RX_EN1 = 4'd2, 54 RX_ANSWER_FA = 4'd3, 55 RX_ANSWER_AA = 4'd4, 56 RX_ANSWER_ID = 4'd5, 57 SEND_PS2_EN = 4'd6, 58 RX_EN2 = 4'd7, 59 RX_ANSWER2 = 4'd8, 60 RX_BYTE1 = 4'd9, 61 RX_BYTE2 = 4'd10, 62 RX_BYTE3 = 4'd11, 63 DELAY = 4'd12, 64 STOP = 4'd13; 65 /**********************************************************************/ 66 //assign send_cmd = STREAM; 67 /**********************************************************************/ 68 //200us计数器 69 reg [24:0] cnt; 70 always @(posedge sys_clk or negedge rst_n) 71 if(!rst_n) 72 cnt <= 25'd0; 73 else if(!cnt_en || cnt == T500MS) 74 cnt <= 25'd0; 75 else 76 cnt <= cnt + 1'b1; 77 /**********************************************************************/ 78 reg send_en; 79 reg rx_en; 80 reg [7:0] data_answer; //保存应答位 81 reg x_sign; //x的符号位 82 reg y_sign; //y的符号位 83 reg [7:0] x_move; //x的偏移量 84 reg [7:0] y_move; //y的偏移量 85 reg [3:0] state; 86 reg [7:0] dis_data_temp1; 87 reg [7:0] dis_data_temp2; 88 reg [7:0] dis_data_temp3; 89 reg [7:0] dis_data_temp4; 90 reg [7:0] dis_data_btn; 91 reg cnt_en; 92 reg [7:0] send_cmd; 93 always @(posedge sys_clk or negedge rst_n) 94 if(!rst_n) begin 95 send_en <= 1'b0; 96 rx_en <= 1'b0; 97 data_answer <= 8'h00; 98 x_sign <= 1'b0; 99 y_sign <= 1'b0; 100 state <= IDLE; 101 dis_data_temp1 <= 8'h00; 102 dis_data_temp2 <= 8'h00; 103 dis_data_temp3 <= 8'h00; 104 dis_data_temp4 <= 8'h00; 105 cnt_en <= 1'b0; 106 dis_data_btn <= "X"; 107 send_cmd <= 8'h00; 108 end 109 else begin 110 case(state) 111 IDLE: 112 begin 113 state <= SEND_PS2_RST; 114 cnt_en <= 1'b1; 115 end 116 117 SEND_PS2_RST: //发送复位 0xff 118 if(cnt == T100MS) begin 119 cnt_en <= 1'b0; 120 send_en <= 1'b1; //启动发送 121 send_cmd <= PS2_RST; 122 state <= RX_EN1; 123 end 124 125 RX_EN1: 126 if(send_done_sig) begin 127 rx_en <= 1'b1; 128 send_en <= 1'b0; 129 state <= RX_ANSWER_FA; 130 end 131 132 RX_ANSWER_FA: //接收鼠标发回的应答数据0xfa 133 if(rx_done_sig) begin 134 dis_data_temp1 <= data_buf; 135 state <= RX_ANSWER_AA;//RX_BYTE1; 136 end 137 138 RX_ANSWER_AA: //接收鼠标发回的应答数据0xaa 139 if(rx_done_sig) begin 140 dis_data_temp2 <= data_buf; 141 state <= RX_ANSWER_ID; 142 end 143 144 RX_ANSWER_ID: //接收鼠标发回的应答数据0x00 145 if(rx_done_sig) begin 146 dis_data_temp3 <= data_buf; 147 cnt_en <= 1'b1; 148 state <= SEND_PS2_RST; 149 end 150 151 SEND_PS2_EN: //发送0xf4 152 if(cnt == T100MS)begin 153 rx_en <= 1'b0; 154 cnt_en <= 1'b0; 155 send_en <= 1'b1; //启动发送 156 send_cmd <= PS2_EN; 157 state <= RX_EN2; 158 end 159 160 RX_EN2: 161 if(send_done_sig) begin 162 rx_en <= 1'b1; //启动接收 163 send_en <= 1'b0; 164 state <= RX_ANSWER2; 165 end 166 167 RX_ANSWER2: //第二次应答位 168 if(rx_done_sig) begin 169 dis_data_temp4 <= data_buf; 170 state <= RX_BYTE1; 171 end 172 173 RX_BYTE1: 174 if(rx_done_sig) begin 175 if(data_buf[0] == 1'b1)//左键被按下 176 dis_data_btn <= "L"; 177 else if(data_buf[1] == 1'b1) //右键被按下 178 dis_data_btn <= "R"; 179 else if(data_buf[2] == 1'b1) //中键被按下 180 dis_data_btn <= "M"; 181 182 x_sign <= data_buf[4]; 183 y_sign <= data_buf[5]; 184 185 state <= RX_BYTE2; 186 end 187 188 RX_BYTE2: 189 if(rx_done_sig) begin //接收到第二个字节 190 x_move <= data_buf; 191 state <= RX_BYTE3; 192 end 193 194 RX_BYTE3: //接收到第三个字节 195 if(rx_done_sig) begin 196 y_move <= data_buf; 197 state <= STOP; 198 cnt_en <= 1'b1; 199 end 200 201 STOP: 202 if(cnt == T100MS) begin 203 cnt_en <= 1'b0; 204 state <= RX_BYTE1; 205 end 206 endcase 207 end 208 209 reg [7:0] dis_data_low1; 210 always @(dis_data_temp1[3:0]) 211 case(dis_data_temp1[3:0]) 212 4'h0: dis_data_low1 = "0"; 213 4'h1: dis_data_low1 = "1"; 214 4'h2: dis_data_low1 = "2"; 215 4'h3: dis_data_low1 = "3"; 216 4'h4: dis_data_low1 = "4"; 217 4'h5: dis_data_low1 = "5"; 218 4'h6: dis_data_low1 = "6"; 219 4'h7: dis_data_low1 = "7"; 220 4'h8: dis_data_low1 = "8"; 221 4'h9: dis_data_low1 = "9"; 222 4'ha: dis_data_low1 = "a"; 223 4'hb: dis_data_low1 = "b"; 224 4'hc: dis_data_low1 = "c"; 225 4'hd: dis_data_low1 = "d"; 226 4'he: dis_data_low1 = "e"; 227 4'hf: dis_data_low1 = "f"; 228 endcase 229 230 reg [7:0] dis_data_hig1; 231 always @(dis_data_temp1[7:4]) 232 case(dis_data_temp1[7:4]) 233 4'h0: dis_data_hig1 = "0"; 234 4'h1: dis_data_hig1 = "1"; 235 4'h2: dis_data_hig1 = "2"; 236 4'h3: dis_data_hig1 = "3"; 237 4'h4: dis_data_hig1 = "4"; 238 4'h5: dis_data_hig1 = "5"; 239 4'h6: dis_data_hig1 = "6"; 240 4'h7: dis_data_hig1 = "7"; 241 4'h8: dis_data_hig1 = "8"; 242 4'h9: dis_data_hig1 = "9"; 243 4'ha: dis_data_hig1 = "a"; 244 4'hb: dis_data_hig1 = "b"; 245 4'hc: dis_data_hig1 = "c"; 246 4'hd: dis_data_hig1 = "d"; 247 4'he: dis_data_hig1 = "e"; 248 4'hf: dis_data_hig1 = "f"; 249 endcase 250 251 reg [7:0] dis_data_low2; 252 always @(dis_data_temp2[3:0]) 253 case(dis_data_temp2[3:0]) 254 4'h0: dis_data_low2 = "0"; 255 4'h1: dis_data_low2 = "1"; 256 4'h2: dis_data_low2 = "2"; 257 4'h3: dis_data_low2 = "3"; 258 4'h4: dis_data_low2 = "4"; 259 4'h5: dis_data_low2 = "5"; 260 4'h6: dis_data_low2 = "6"; 261 4'h7: dis_data_low2 = "7"; 262 4'h8: dis_data_low2 = "8"; 263 4'h9: dis_data_low2 = "9"; 264 4'ha: dis_data_low2 = "a"; 265 4'hb: dis_data_low2 = "b"; 266 4'hc: dis_data_low2 = "c"; 267 4'hd: dis_data_low2 = "d"; 268 4'he: dis_data_low2 = "e"; 269 4'hf: dis_data_low2 = "f"; 270 endcase 271 272 reg [7:0] dis_data_hig2; 273 always @(dis_data_temp2[7:4]) 274 case(dis_data_temp2[7:4]) 275 4'h0: dis_data_hig2 = "0"; 276 4'h1: dis_data_hig2 = "1"; 277 4'h2: dis_data_hig2 = "2"; 278 4'h3: dis_data_hig2 = "3"; 279 4'h4: dis_data_hig2 = "4"; 280 4'h5: dis_data_hig2 = "5"; 281 4'h6: dis_data_hig2 = "6"; 282 4'h7: dis_data_hig2 = "7"; 283 4'h8: dis_data_hig2 = "8"; 284 4'h9: dis_data_hig2 = "9"; 285 4'ha: dis_data_hig2 = "a"; 286 4'hb: dis_data_hig2 = "b"; 287 4'hc: dis_data_hig2 = "c"; 288 4'hd: dis_data_hig2 = "d"; 289 4'he: dis_data_hig2 = "e"; 290 4'hf: dis_data_hig2 = "f"; 291 endcase 292 293 reg [7:0] dis_data_low3; 294 always @(dis_data_temp3[3:0]) 295 case(dis_data_temp3[3:0]) 296 4'h0: dis_data_low3 = "0"; 297 4'h1: dis_data_low3 = "1"; 298 4'h2: dis_data_low3 = "2"; 299 4'h3: dis_data_low3 = "3"; 300 4'h4: dis_data_low3 = "4"; 301 4'h5: dis_data_low3 = "5"; 302 4'h6: dis_data_low3 = "6"; 303 4'h7: dis_data_low3 = "7"; 304 4'h8: dis_data_low3 = "8"; 305 4'h9: dis_data_low3 = "9"; 306 4'ha: dis_data_low3 = "a"; 307 4'hb: dis_data_low3 = "b"; 308 4'hc: dis_data_low3 = "c"; 309 4'hd: dis_data_low3 = "d"; 310 4'he: dis_data_low3 = "e"; 311 4'hf: dis_data_low3 = "f"; 312 endcase 313 314 reg [7:0] dis_data_hig3; 315 always @(dis_data_temp3[7:4]) 316 case(dis_data_temp3[7:4]) 317 4'h0: dis_data_hig3 = "0"; 318 4'h1: dis_data_hig3 = "1"; 319 4'h2: dis_data_hig3 = "2"; 320 4'h3: dis_data_hig3 = "3"; 321 4'h4: dis_data_hig3 = "4"; 322 4'h5: dis_data_hig3 = "5"; 323 4'h6: dis_data_hig3 = "6"; 324 4'h7: dis_data_hig3 = "7"; 325 4'h8: dis_data_hig3 = "8"; 326 4'h9: dis_data_hig3 = "9"; 327 4'ha: dis_data_hig3 = "a"; 328 4'hb: dis_data_hig3 = "b"; 329 4'hc: dis_data_hig3 = "c"; 330 4'hd: dis_data_hig3 = "d"; 331 4'he: dis_data_hig3 = "e"; 332 4'hf: dis_data_hig3 = "f"; 333 endcase 334 335 reg [7:0] dis_data_low4; 336 always @(dis_data_temp4[3:0]) 337 case(dis_data_temp4[3:0]) 338 4'h0: dis_data_low4 = "0"; 339 4'h1: dis_data_low4 = "1"; 340 4'h2: dis_data_low4 = "2"; 341 4'h3: dis_data_low4 = "3"; 342 4'h4: dis_data_low4 = "4"; 343 4'h5: dis_data_low4 = "5"; 344 4'h6: dis_data_low4 = "6"; 345 4'h7: dis_data_low4 = "7"; 346 4'h8: dis_data_low4 = "8"; 347 4'h9: dis_data_low4 = "9"; 348 4'ha: dis_data_low4 = "a"; 349 4'hb: dis_data_low4 = "b"; 350 4'hc: dis_data_low4 = "c"; 351 4'hd: dis_data_low4 = "d"; 352 4'he: dis_data_low4 = "e"; 353 4'hf: dis_data_low4 = "f"; 354 endcase 355 356 reg [7:0] dis_data_hig4; 357 always @(dis_data_temp4[7:4]) 358 case(dis_data_temp4[7:4]) 359 4'h0: dis_data_hig4 = "0"; 360 4'h1: dis_data_hig4 = "1"; 361 4'h2: dis_data_hig4 = "2"; 362 4'h3: dis_data_hig4 = "3"; 363 4'h4: dis_data_hig4 = "4"; 364 4'h5: dis_data_hig4 = "5"; 365 4'h6: dis_data_hig4 = "6"; 366 4'h7: dis_data_hig4 = "7"; 367 4'h8: dis_data_hig4 = "8"; 368 4'h9: dis_data_hig4 = "9"; 369 4'ha: dis_data_hig4 = "a"; 370 4'hb: dis_data_hig4 = "b"; 371 4'hc: dis_data_hig4 = "c"; 372 4'hd: dis_data_hig4 = "d"; 373 4'he: dis_data_hig4 = "e"; 374 4'hf: dis_data_hig4 = "f"; 375 endcase 376 endmodule 377