陌路沙砾 发表于 2010-10-18 21:17:32

请教关于FPGA矩阵键盘的问题

新手学FPGA借鉴网上代码,编写了矩阵键盘控制小灯的代码,叫了特权的按键消抖以后 ,不好使了 (不加消抖好使),不知道什么原因,个人能力有限找不出来,在此向各位请教,请帮忙答疑解惑,谢谢了!!!

// 模块功能:用矩阵键盘控制小灯亮灭
module key16(input row,                  //四行
                        input clk,reset,               //时钟,复位
                        output reg col,             //四列
                        output reg led);            //八路灯
       
reg key_n;
always@(posedge clk,negedge reset)
                begin
                        if(!reset) key_n<=4'hf;                //异步复位
                        else key_n<=row;                     //每次时钟上升沿到来时,记录一次key的值
                end       
               
reg key_n_r;
always@(posedge clk,negedge reset)
       begin
               if(!reset) key_n_r<=4'hf;                //异步复位
               else key_n_r<=key_n;                   //时钟上升沿到来的时候,记录一次kye_n的值
       end
               
wire key_an=key_n_r&(~key_n);         //当有键按下的瞬间即key由1变0瞬间,key_an变高


//--------计数寄存器---------------                                               
reg cnt;                           
always@(posedge clk,negedge reset)
begin                                                            
if(!reset) cnt<=24'd0;
else if(key_an) cnt<=24'd0;
else cnt<=cnt+1'b1;               
end                       
                               
//-------------行按键----------
reg row_n;
always@(posedge clk,negedge reset)
begin
if(!reset)         row_n <= 4'b1111;
else if(cnt == 24'hfff_fff) row_n <= row;
end

reg row_n_r;
always@(posedge clk, negedge reset)
begin
if(!reset) row_n_r<=4'b1111;
else row_n_r<=row_n;
end


wire row_add = row_n_r&(~row_n);            //当20ms后确实有按键按下时,row_add变高



//-----------------------------------

reg col_n;                   //存储键的键值状态
reg state;                   //扫描状态
reg      key_flag;                      // 键的标志位

/*
//-------------列按键-------------
reg col_n;
always@(posedge clk,negedge reset)
if(!reset)         col_n<=4'b1111;
else if(cnt==24'hfff_fff) col_n<=col;

reg col_n_r;
always@(posedge clk, negedge reset)
if(!reset) col_n_r<=4'b1111;
else col_n_r<=col_n;

wire col_add=col_n_r&(~col_n);            //当确实有按键按下时,col_add变高
*/

//--------------------
always@(posedge clk,negedge reset)
begin
if(!reset) begin col<=4'b0000; state<=3'd0;end
else case(state)
       3'd0:
                               begin
                 col<=4'b0000;
                 key_flag<=1'b0;
                 if(row_add!=4'b0000)
       //    if(row!=4'b1111)
                 beginstate<=3'd1;col<=4'b1110;end
                 else begin state<=3'd0;end
                 end
       3'd1:                   //扫描第一列
                               begin
                               if(row_add!=4'b0000)
                       //        if(row!=4'b1111)
                         state<=3'd5;
                               elsebegin state<=3'd2;col<=4'b1101;end   
                               end
       3'd2:                  //扫描第二列
                               begin
                               if(row_add!=4'b0000)
               //                if(row!=4'b1111)
                         state<=3'd5;
                               elsebegin state<=3'd3;col<=4'b1011;end               
                               end
       3'd3:                   //扫描第三列
                               begin
                               if(row_add!=4'b0000)
               //                if(row!=4'b1111)
                               state<=3'd5;
                               elsebegin state<=3'd4;col<=4'b0111;end               
                               end
       3'd4:                   //扫描第四列
                               begin
                         if(row_add!=4'b0000)
               //          if(row!=4'b1111)
                         state <= 3'd5;
                               elsestate <= 3'd0;   
                               end
       3'd5:
                               begin
                             if(row_add!=4'b0000)
               //                   if(row!=4'b1111)
                                  begin
                                               //                key_value <= {row_add,col};
                                                       col_n<=col;
                                                               key_flag <= 1'b1;
                                                               state <= 3'd5;
                                         end
                                 else state <= 3'd0;   
                         end
   default:   state <= 3'd0;
   endcase
end


wire key_value = {row_add,col_n};

always@(posedge clk,negedge reset)
if(!reset) led<=8'b1111_0000;
else if(key_flag)   
   case(key_value)
   8'b0001_1110:led<=8'b1111_1110;
   8'b0001_1101:led<=8'b1111_1101;
   8'b0001_1011:led<=8'b1111_1011;
   8'b0001_0111:led<=8'b1111_0111;
                     
   8'b0010_1110:led<=8'b1110_1111;
   8'b0010_1101:led<=8'b1101_1111;
   8'b0010_1011:led<=8'b1011_1111;
   8'b0010_0111:led<=8'b0111_1111;

   8'b0100_1110:led<=8'b1111_1100;
   8'b0100_1101:led<=8'b1111_0011;
   8'b0100_1011:led<=8'b1100_1111;
   8'b0100_0111:led<=8'b0011_1111;

   8'b1000_1110:led<=8'b1111_0000;
   8'b1000_1101:led<=8'b0000_1111;
   8'b1000_1011:led<=8'b0000_0000;
   8'b1000_0111:led<=8'b1111_1111;
/*
           8'b1110_1110:led<=8'b1111_1110;
   8'b1110_1101:led<=8'b1111_1101;
   8'b1110_1011:led<=8'b1111_1011;
   8'b1110_0111:led<=8'b1111_0111;
                     
   8'b1101_1110:led<=8'b1110_1111;
   8'b1101_1101:led<=8'b1101_1111;
   8'b1101_1011:led<=8'b1011_1111;
   8'b1101_0111:led<=8'b0111_1111;

   8'b1011_1110:led<=8'b1111_1100;
   8'b1011_1101:led<=8'b1111_0011;
   8'b1011_1011:led<=8'b1100_1111;
   8'b1011_0111:led<=8'b0011_1111;

   8'b0111_1110:led<=8'b1111_0000;
   8'b0111_1101:led<=8'b0000_1111;
   8'b0111_1011:led<=8'b0000_0000;
   8'b0111_0111:led<=8'b1111_1111;
      */
               default:led<=led;
               endcase
elseled<=8'b00000000;
                                                   
endmodule
页: [1]
查看完整版本: 请教关于FPGA矩阵键盘的问题