caijinshu 发表于 2011-10-12 22:31:49

特权同学PS/2键盘解码疑问?!

module ps2scan(clk,rst_n,ps2k_clk,ps2k_data,ps2_byte,ps2_state);

input clk; //50M时钟信号
input rst_n;//复位信号
input ps2k_clk;   //PS2接口时钟信号
input ps2k_data;//PS2接口数据信号

output ps2_byte;    // 1byte键值,只做简单的按键扫描
output ps2_state;    //键盘当前状态,ps2_state=1表示有键被按下
//------------------------------------------
reg ps2k_clk_r0,ps2k_clk_r1,ps2k_clk_r2;//ps2k_clk状态寄存器

//wire pos_ps2k_clk;   // ps2k_clk上升沿标志位
wire neg_ps2k_clk;   // ps2k_clk下降沿标志位

always @ (posedge clk or negedge rst_n) begin
    if(!rst_n) begin
         ps2k_clk_r0 <= 1'b0;
         ps2k_clk_r1 <= 1'b0;
         ps2k_clk_r2 <= 1'b0;
       end
    else begin                         //锁存状态,进行滤波
         ps2k_clk_r0 <= ps2k_clk;
         ps2k_clk_r1 <= ps2k_clk_r0;
         ps2k_clk_r2 <= ps2k_clk_r1;
       end
end

assign neg_ps2k_clk = ~ps2k_clk_r1 & ps2k_clk_r2;    //下降沿
//------------------------------------------
reg ps2_byte_r;   //PC接收来自PS2的一个字节数据存储器
reg temp_data;//当前接收数据寄存器
reg num; //计数寄存器

always @ (posedge clk or negedge rst_n) begin
    if(!rst_n) begin
         num <= 4'd0;
         temp_data <= 8'd0;
       end
    else if(neg_ps2k_clk) begin //检测到ps2k_clk的下降沿
         case (num)
            4'd0:num <= num+1'b1;
            4'd1:begin
                         num <= num+1'b1;
                         temp_data <= ps2k_data;//bit0
                     end
            4'd2:begin
                         num <= num+1'b1;
                         temp_data <= ps2k_data;//bit1
                     end
            4'd3:begin
                        num <= num+1'b1;
                         temp_data <= ps2k_data;//bit2
                     end
            4'd4:begin
                         num <= num+1'b1;
                         temp_data <= ps2k_data;//bit3
                     end
            4'd5:begin
                         num <= num+1'b1;
                         temp_data <= ps2k_data;//bit4
                     end
            4'd6:begin
                         num <= num+1'b1;
                         temp_data <= ps2k_data;//bit5
                  end
            4'd7:begin
                         num <= num+1'b1;
                         temp_data <= ps2k_data;//bit6
                     end
            4'd8:begin
                         num <= num+1'b1;
                         temp_data <= ps2k_data;//bit7
                     end
            4'd9:begin
                         num <= num+1'b1;//奇偶校验位,不做处理
                     end
            4'd10: begin
                         num <= 4'd0;// num清零
                     end
            default: ;
            endcase
      end
end

reg key_f0;       //松键标志位,置1表示接收到数据8'hf0,再接收到下一个数据后清零
reg ps2_state_r;//键盘当前状态,ps2_state_r=1表示有键被按下

always @ (posedge clk or negedge rst_n) begin //接收数据的相应处理,这里只对1byte的键值进行处理
    if(!rst_n) begin
         key_f0 <= 1'b0;
         ps2_state_r <= 1'b0;
       end
    else if(num==4'd10) begin   //刚传送完一个字节数据
         if(temp_data == 8'hf0) key_f0 <= 1'b1;
         else begin
                  if(!key_f0) begin //说明有键按下
                         ps2_state_r <= 1'b1;
                         ps2_byte_r <= temp_data; //锁存当前键值
                     end
                  else begin
                         ps2_state_r <= 1'b0;
                         key_f0 <= 1'b0;
                     end
            end
       end
end

reg ps2_asci;   //接收数据的相应ASCII码

always @ (ps2_byte_r) begin
    case (ps2_byte_r)    //键值转换为ASCII码,这里做的比较简单,只处理字母
       8'h15: ps2_asci <= 8'h51;   //Q
             default: ;
       endcase
end

assign ps2_byte = ps2_asci;
assign ps2_state = ps2_state_r;

endmodule

caijinshu 发表于 2011-10-12 22:34:30

键值判断那里能否在键按下松开时产生一个电平而不是一个脉冲??

caijinshu 发表于 2011-10-13 21:32:52

忽略断码后部分值就可以了,就是不知为什么总会“死机”!

caijinshu 发表于 2011-10-14 15:32:21

自己又搞定了,因为50M时钟是我在板上面25M经过锁相环倍频得到的,直接接25M就不会出现“死机”的状况了,又不知为什么
页: [1]
查看完整版本: 特权同学PS/2键盘解码疑问?!