• 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中,奇偶校验理解的不对,详细介绍见奇偶校验位产生器

  • 相关阅读:
    可遇不可求的Question之无法加载 DLL
    可遇不可求的Question之mysql odbc 5.1 driver 指定驱动程序无法加载
    可遇不可求的Question之Got error 127 from table handler
    可遇不可求的Question之Odbc与MYSQLCLIENT转码机制探讨
    【转】Task Scheduler Managed Wrapper: 由程式來排程工作
    可遇不可求的Question之update from 语法
    【转】Long Time Operations in ASP.NET
    可遇不可求的Question之System.TypeLoadException错误
    浅谈Asp.Net中涉及到的四个TimeOut属性
    4月2号
  • 原文地址:https://www.cnblogs.com/wen2376/p/3389512.html
Copyright © 2020-2023  润新知