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

yuxuanwlfei   2015-8-31 09:24 楼主
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

回复评论 (6)

没明白你的意思
是按下一个键  对应1234吗
生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙 =================================== 做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
点赞  2015-8-31 10:17
引用: chenzhufly 发表于 2015-8-31 10:17
没明白你的意思
是按下一个键  对应1234吗

不是的,是按下第一键“1”输出“1”,按下第二键“2”输出为“12”,按下第三个键“3”输出“123”,按下第四个键“4”输出“1234”
点赞  2015-8-31 10:25
引用: yuxuanwlfei 发表于 2015-8-31 10:25
不是的,是按下第一键“1”输出“1”,按下第二键“2”输出为“12”,按下第三个键“3”输出“123”,按 ...

其实现的功能就像计算器输入数据一样,可以连续输入。
点赞  2015-8-31 10:26
代码好多。。。看着头晕。。。。。。
分享铸就美好未来。。。
点赞  2015-8-31 18:26
代码比较长,没有细看,思路就是。读取当前按键,判断数字的个数,把每个数字送到对应的数码管就可以了。
点赞  2015-9-3 21:52
已功能键作为结束  怎么还没搞定?
生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙 =================================== 做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
点赞  2015-9-5 11:23
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复