4X4矩阵键盘(verilog)如何输入连续数字1234

2019-03-25 07:44发布

module key4x4
(
clk,
rst_n,
col,
row,                              
key_val              
);

input clk;
input rst_n;
input [3:0] row;                 // 矩阵键盘 行
output reg [3:0] col;            // 矩阵键盘 列
output reg [3:0] key_val;        // 键盘值  

//++++++++++++++++++++++++++++++++++++++
// 状态机部分 开始
//++++++++++++++++++++++++++++++++++++++
// 状态编码
parameter NO_KEY_PRESSED = 6'b000_001;  // 没有按键按下   
parameter SCAN_COL0      = 6'b000_010;  // 扫描第0列  
parameter SCAN_COL1      = 6'b000_100;  // 扫描第1列  
parameter SCAN_COL2      = 6'b001_000;  // 扫描第2列  
parameter SCAN_COL3      = 6'b010_000;  // 扫描第3列  
parameter KEY_PRESSED    = 6'b100_000;  // 有按键按下
reg [5:0] current_state, next_state;    // 现态、次态
reg  key_pressed_flag;              // 键盘按下标志
reg [3:0] col_reg, row_reg;             // 列值、行值
reg [11:0]cnt;
reg clk0;
always@(posedge clk or negedge rst_n)
begin
   if(!rst_n)
      current_state<=NO_KEY_PRESSED;
   else
      current_state<=next_state;  
end

always@(posedge clk)
begin
   if(cnt<4000)
       cnt=cnt+1;
   else
  begin
   cnt=0;
   clk0=~clk0;
  end
end

always@(posedge clk0)
begin
case(current_state)
  NO_KEY_PRESSED:
   if(row!=4'b1111)  
    next_state=SCAN_COL0;
         else
    begin
     next_state=NO_KEY_PRESSED;
    end
      SCAN_COL0:
         begin
            if(row!=4'b1111)
     next_state=KEY_PRESSED;
            else
     next_state=SCAN_COL1;               
         end
      SCAN_COL1:
         begin
            if(row!=4'b1111)
               next_state=KEY_PRESSED;
            else  
     next_state=SCAN_COL2;
         end
      SCAN_COL2:
         begin
    if(row!=4'b1111)
               next_state=KEY_PRESSED;
            else  
     next_state=SCAN_COL3;
         end
      SCAN_COL3:
         begin
            if(row!=4'b1111)
               next_state=KEY_PRESSED;
            else
     next_state=NO_KEY_PRESSED;
         end
      KEY_PRESSED:
         if(row!=4'b1111)
            next_state=KEY_PRESSED;
         else
    next_state=NO_KEY_PRESSED;
      default:
   next_state=NO_KEY_PRESSED;
endcase
end  
always@(posedge clk or negedge rst_n)
begin
   if(!rst_n)
  begin
   col<= 4'b0000;
   key_pressed_flag<=0;
  end
   else
  case(next_state)
   NO_KEY_PRESSED:
    begin
     col=4'b0000;
     key_pressed_flag=0;
    end   
   SCAN_COL0:  
    col=4'b1110;
   SCAN_COL1:  
    col=4'b1101;
   SCAN_COL2:  
    col=4'b1011;
   SCAN_COL3:  
    col=4'b0111;
   KEY_PRESSED:
    begin
     col_reg=col;
     row_reg=row;
     key_pressed_flag=1;
    end
     endcase  
end
always@(posedge clk0 or negedge rst_n)
begin
if(!rst_n)
  key_val<=4'h0;
   else if(key_pressed_flag)
  begin
   case({col_reg,row_reg})
    8'b1110_1110: key_val=4'h0; //显示"0"
    8'b1110_1101: key_val=4'h1; //显示"4"
    8'b1110_1011: key_val=4'h2; //显示"8"
    8'b1110_0111: key_val=4'h3; //显示"C"
   
    8'b1101_1110: key_val=4'h4; //显示"1"
    8'b1101_1101: key_val=4'h5; //显示"5"
    8'b1101_1011: key_val=4'h6; //显示"9"
    8'b1101_0111: key_val=4'h7; //显示"d"
   
    8'b1011_1110: key_val=4'h8; //显示"2"
    8'b1011_1101: key_val=4'h9; //显示"6"
    8'b1011_1011: key_val=4'hA; //显示"A"
    8'b1011_0111: key_val=4'hb; //显示"E"
   
    8'b0111_1110: key_val=4'hc; //显示"3"
    8'b0111_1101: key_val=4'hd; //显示"7"
    8'b0111_1011: key_val=4'he; //显示"b"
    8'b0111_0111: key_val=4'hF; //显示"F"
   
    default:    key_val=4'h0;
   endcase
  end
end      
endmodule


大家好,如上所示,此4x4矩阵键盘代码只能每次按下一个按键对应一个值,请问如何实现连续输入1234,此模块输出data=1234。
于是有以下更改,但无法实现目标,请问有何好的方法获例程提供,谢谢。


module key4x4
(
clk,
rst_n,
col,
row,                              
key_data              
);

input clk;
input rst_n;
input [3:0] row;                 // 矩阵键盘 行
output reg [3:0] col;            // 矩阵键盘 列
output reg [15:0] key_data;
reg [3:0] key_val;        // 键盘值  

//++++++++++++++++++++++++++++++++++++++
// 状态机部分 开始
//++++++++++++++++++++++++++++++++++++++
// 状态编码
parameter NO_KEY_PRESSED = 6'b000_001;  // 没有按键按下   
parameter SCAN_COL0      = 6'b000_010;  // 扫描第0列  
parameter SCAN_COL1      = 6'b000_100;  // 扫描第1列  
parameter SCAN_COL2      = 6'b001_000;  // 扫描第2列  
parameter SCAN_COL3      = 6'b010_000;  // 扫描第3列  
parameter KEY_PRESSED    = 6'b100_000;  // 有按键按下
reg [5:0] current_state, next_state;    // 现态、次态
reg  key_pressed_flag;              // 键盘按下标志
reg [3:0] col_reg, row_reg;             // 列值、行值
reg [11:0]cnt;
reg clk0;
reg key_val_flag;
always@(posedge clk or negedge rst_n)
begin
   if(!rst_n)
      current_state<=NO_KEY_PRESSED;
   else
      current_state<=next_state;  
end

always@(posedge clk)
begin
   if(cnt<4000)
       cnt=cnt+1;
   else
  begin
   cnt=0;
   clk0=~clk0;
  end
end

always@(posedge clk0)
begin
case(current_state)
  NO_KEY_PRESSED:
   if(row!=4'b1111)  
    next_state=SCAN_COL0;
         else
    begin
     next_state=NO_KEY_PRESSED;
    end
      SCAN_COL0:
         begin
            if(row!=4'b1111)
     next_state=KEY_PRESSED;
            else
     next_state=SCAN_COL1;               
         end
      SCAN_COL1:
         begin
            if(row!=4'b1111)
               next_state=KEY_PRESSED;
            else  
     next_state=SCAN_COL2;
         end
      SCAN_COL2:
         begin
    if(row!=4'b1111)
               next_state=KEY_PRESSED;
            else  
     next_state=SCAN_COL3;
         end
      SCAN_COL3:
         begin
            if(row!=4'b1111)
               next_state=KEY_PRESSED;
            else
     next_state=NO_KEY_PRESSED;
         end
      KEY_PRESSED:
         if(row!=4'b1111)
            next_state=KEY_PRESSED;
         else
    next_state=NO_KEY_PRESSED;
      default:
   next_state=NO_KEY_PRESSED;
endcase
end  
always@(posedge clk or negedge rst_n)
begin
   if(!rst_n)
  begin
   col<= 4'b0000;
   key_pressed_flag<=0;
  end
   else
  case(next_state)
   NO_KEY_PRESSED:
    begin
     col=4'b0000;
     key_pressed_flag=0;
    end   
   SCAN_COL0:  
    col=4'b1110;
   SCAN_COL1:  
    col=4'b1101;
   SCAN_COL2:  
    col=4'b1011;
   SCAN_COL3:  
    col=4'b0111;
   KEY_PRESSED:
    begin
     col_reg=col;
     row_reg=row;
     key_pressed_flag=1;
    end
     endcase  
end
always@(posedge clk0 or negedge rst_n)
begin
if(!rst_n)
  key_val<=4'h0;
   else if(key_pressed_flag)
  begin
   case({col_reg,row_reg})
    8'b1110_1110: begin key_val_flag=1; key_val=4'h0; end
    8'b1110_1101: begin key_val_flag=1; key_val=4'h1; end
    8'b1110_1011: begin key_val_flag=1; key_val=4'h2; end
    8'b1110_0111: begin key_val_flag=1; key_val=4'h3; end
   
    8'b1101_1110: begin key_val_flag=1; key_val=4'h4; end
    8'b1101_1101:  begin key_val_flag=1; key_val=4'h5; end
    8'b1101_1011:  begin key_val_flag=1; key_val=4'h6; end
    8'b1101_0111:  begin key_val_flag=1; key_val=4'h7; end
   
    8'b1011_1110:  begin key_val_flag=1; key_val=4'h8; end
    8'b1011_1101:  begin key_val_flag=1; key_val=4'h9; end
    8'b1011_1011:  begin key_val_flag=1; key_val=4'ha; end
    8'b1011_0111:  begin key_val_flag=1; key_val=4'hb; end
   
    8'b0111_1110:  begin key_val_flag=1; key_val=4'hc; end
    8'b0111_1101:  begin key_val_flag=1; key_val=4'hd; end
    8'b0111_1011: begin key_val_flag=1; key_val=4'he; end
    8'b0111_0111:  begin key_val_flag=1; key_val=4'hf; end
   
    default:    begin key_val_flag=0; key_val=4'h0; end
   endcase
  end
end  

reg [3:0] num;
always@(posedge clk0 or negedge rst_n)
begin
if(!rst_n)
  key_data=20'd0;
else if(key_val_flag)
  begin
   num=key_val;
   key_data=(key_data)*10+num;
   if(key_data>9999)      
    key_data=key_data%10;
  end
end
endmodule
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。