集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1349|回复: 0

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

[复制链接]
陌路沙砾 发表于 2010-10-18 21:17:32 | 显示全部楼层 |阅读模式
新手学FPGA  借鉴网上代码,编写了矩阵键盘控制小灯的代码,叫了特权的按键消抖以后 ,不好使了 (不加消抖好使),不知道什么原因,个人能力有限找不出来,在此向各位请教,请帮忙答疑解惑,谢谢了!!!

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


//--------计数寄存器---------------                                                 
reg[24:1] 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[4:1] 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[4:1] row_n_r;
always@(posedge clk, negedge reset)
begin
if(!reset) row_n_r<=4'b1111;
else row_n_r<=row_n;
end


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



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

reg[4:1] col_n;                   //存储键的键值状态
reg[3:1] state;                   //扫描状态
reg      key_flag;                      // 键的标志位

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

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

wire[4:1] 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)
                     begin  state<=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;
                                 else  begin state<=3'd2;col<=4'b1101;end     
                                 end
         3'd2:                  //扫描第二列
                                 begin  
                                 if(row_add!=4'b0000)  
                 //                if(row!=4'b1111)
                           state<=3'd5;
                                 else  begin state<=3'd3;col<=4'b1011;end                 
                                 end
         3'd3:                   //扫描第三列
                                 begin  
                                 if(row_add!=4'b0000)
                 //                if(row!=4'b1111)
                                 state<=3'd5;
                                 else  begin state<=3'd4;col<=4'b0111;end               
                                 end
         3'd4:                   //扫描第四列
                                 begin  
                           if(row_add!=4'b0000)
                 //          if(row!=4'b1111)
                           state <= 3'd5;
                                 else  state <= 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[8:1] 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
  else  led<=8'b00000000;
                                                   
endmodule
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|集成电路技术分享 ( 京ICP备20003123号-1 )

GMT+8, 2024-5-5 13:45 , Processed in 0.064447 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表