TA的每日心情 | 慵懒 2014-11-28 09:29 |
---|
签到天数: 3 天 连续签到: 1 天 [LV.2]偶尔看看I
|
简单介绍下矩阵键盘的原理:
矩阵键盘4个输入端口ROW[3:0] 接收由FPGA产生的键盘扫描输入信号,而4个输出COL[3:0] 将按键操作的信息变化输入到FPGA扫描分析电路,进而得到按键的操作码。
输入端口分别接了4个上拉电阻,当4个输入端口输入若都为1时,则有无论按哪个按键,输出都为1,所以 若刚开始的时候对四个输入端口赋0,则只要按下任何一个按键,键盘上的4个输出则肯定有1变为0,而且能够判断到是哪一列,但是并不知道是哪一行,所以此时就要用到键盘扫描,何为键盘扫描,就是只要让输入端口的一行为0,其余三行全为1,轮流扫描一遍,便可以方便的确定按键按下的准确值。
又因为实际运用的时候按键按下会有抖动现象,所以要对其进行消抖处理,消抖模块可以有很多种方法,例如状态机的消抖方法以及打拍延时,然后相或,因为这个是键值输入,若要用到打拍延时的方法进行消抖处理的话,需要对其进行一些改动,相或改为两两相等并相与 以增加时钟时间。
以下给出矩阵键盘实现的两种代码,其中一种参照赵然的书籍中提到的夏宇闻老师提供的代码。 这里用到了状态机模块进行消抖。- define OK 1'b1
- define NO 1'b0
- define NoKeyIsPressed 17
-
- module keyscan0(clk,rst_n,keyscan,keyin,real_number);
- input clk,rst_n;
- input [3:0]keyin;
- output [3:0] keyscan;
- output [4:0] real_number;
- reg [3:0] state;
- reg [3:0] four_state;
- reg [3:0] scancode,scan_state;
- reg [4:0] numberout,number_reg,number_reg1,number_reg2, real_number;
- reg AnyKeyPressed;
-
- assign keyscan = scancode;
-
- always @(posedge clk or negedge rst_n)
- if (!rst_n)
- begin
- scancode <=4'b0000;
- scan_state<= 4'b0000;
- end
- else
- if(AnyKeyPressed)
- case (scan_state)
- 4'b0000: begin scancode<=4'b1110; scan_state<= 4'b0001; end
- 4'b0001: begin scancode <= {scancode[0],scancode[3:1]}; end
- endcase
- else
- begin
- scancode <=4'b0000;
- scan_state<= 4'b0000;
- end
- always @(posedge clk )
- if( !(&keyin))
- begin
- AnyKeyPressed <= `OK ;
- four_state <= 4'b0000;
- end
- else
- if(AnyKeyPressed)
- case(four_state)
- 4'b0000: begin AnyKeyPressed <= `OK ; four_state<=4'b0001; end
- 4'b0001: begin AnyKeyPressed <= `OK ; four_state<=4'b0010; end
- 4'b0010: begin AnyKeyPressed <= `OK ; four_state<=4'b0100; end
- 4'b0100: begin AnyKeyPressed <= `OK ; four_state<=4'b1000; end
- 4'b1000: begin AnyKeyPressed <= `NO ; end
- default: AnyKeyPressed <= `NO ;
- endcase
- else
- four_state <= 4'b0000;
-
- always @(posedge clk or negedge rst_n)
- if(!rst_n)
- numberout<=`NoKeyIsPressed;
- else
- casex({scancode,keyin})
- 8'b0111_1110: numberout <= 5'd10;
- 8'b1011_1110: numberout <= 5'd3;
- 8'b1101_1110: numberout <= 5'd2;
- 8'b1110_1110: numberout <= 5'd1;
-
- 8'b0111_1101: numberout <= 5'd11;
- 8'b1011_1101: numberout <= 5'd6;
- 8'b1101_1101: numberout <= 5'd5;
- 8'b1110_1101: numberout <= 5'd4;
-
- 8'b0111_1011: numberout <= 5'd12;
- 8'b1011_1011: numberout <= 5'd9;
- 8'b1101_1011: numberout <= 5'd8;
- 8'b1110_1011: numberout <= 5'd7;
-
- 8'b0111_0111: numberout <= 5'd13;
- 8'b1011_0111: numberout <= 5'd15;
- 8'b1101_0111: numberout <= 5'd14;
- 8'b1110_0111: numberout <= 5'd0;
- default: numberout <=`NoKeyIsPressed;
- endcase
-
- always @(posedge clk or negedge rst_n)
- begin
- if (!rst_n)
- begin
- number_reg <= 0;
- end
- else
- if( numberout<=5'd15 && numberout>=5'd0)
- begin
- number_reg <= numberout;
- end
- else
- begin
- if(AnyKeyPressed == `NO)
- number_reg <= `NoKeyIsPressed;
- end
-
- end
-
- always @(posedge clk or negedge rst_n)
- if (!rst_n)
- state <= 4'b0000;
- else
- case (state)
- 4'd0: begin
- number_reg1 <= number_reg;
- state <=4'd1;
- end
- 4'd1: begin
- if(number_reg == number_reg1)
- state <= 4'd2;
- else
- state <= 4'd0;
- end
- 4'd2: begin
- if (number_reg == number_reg1)
- state <= 4'd3;
- else
- state <= 4'd0;
- end
- 4'd3: begin
- if (number_reg == number_reg1)
- state <= 4'd4;
- else
- state <= 4'd0;
- end
- 4'd4: begin
- if(number_reg == number_reg1)
- state <=4'd5;
- else
- state <= 4'd0;
- end
- 4'd5: begin
- if(number_reg == number_reg1)
- state <= 4'd6;
- else
- state <= 4'd0;
- end
- 4'd6: begin
- if (number_reg == number_reg1)
- state <= 4'd7;
- else
- state <= 4'd0;
- end
- 4'd7: begin
- if (number_reg == number_reg1)
- state <= 4'd8;
- else
- state <= 4'd0;
- end
- 4'd8: begin
- if (number_reg == number_reg1)
- state <=4'd9;
- else
- state <= 4'd0;
- end
- 4'd9: begin
- if(number_reg == number_reg1)
- state <= 4'd10;
- else
- state <= 4'd0;
- end
- 4'd10: begin
- if (number_reg == number_reg1)
- state <= 4'd11;
- else
- state <= 4'd0;
- end
- 4'd11: begin
- if (number_reg == number_reg1)
- state <= 4'd12;
- else
- state <= 4'd0;
- end
- 4'd12: begin
- if(number_reg == number_reg1)
- state <= 4'd13;
- else
- state <= 4'd0;
- end
- 4'd13: begin
- if (number_reg == number_reg1)
- state <= 4'd14;
- else
- state <= 4'd0;
- end
- 4'd14: begin
- if (number_reg == number_reg1)
- state <= 4'd15;
- else
- state <= 4'd0;
- end
- 4'd15: begin
- if (number_reg == number_reg1 )
- begin
- state <= 4'd0;
- real_number <=number_reg;
- end
- else
- state <= 4'b0000;
- end
- default: state <= 4'b0000;
- endcase
- endmodule
复制代码 另一种:
- module key_bd(
- input CLK_1K,
- input RSTN,
- input [3:0]ROW,
- output reg[3:0]COL,
- output [3:0]real_num,
- output flag_pos
- //output reg[3:0]key_value,
- //output reg[23:0]num_out
- );
- reg [3:0]state;
- reg [3:0]four_state;
- reg [3:0]key_value;
- reg flag;
- parameter NO = 6'b000_001;
- parameter S0 = 6'b000_010;
- parameter S1 = 6'b000_100;
- parameter S2 = 6'b001_000;
- parameter S3 = 6'b010_000;
- parameter YES= 6'b100_000;
- reg [5:0]CS,NS;
- always@(posedge CLK_1K or negedge RSTN)
- begin
- if(~RSTN)
- CS <= NO;
- else
- CS <= NS;
- end
- always@(*)
- case(CS)
- NO:if(ROW != 4'hF)
- NS <= S0;
- else
- NS <= NO;
- S0:if(ROW != 4'hF)
- NS <= YES;
- else
- NS <= S1;
- S1:if(ROW != 4'hF)
- NS <= YES;
- else
- NS <= S2;
- S2:if(ROW != 4'hF)
- NS <= YES;
- else
- NS <= S3;
- S3:if(ROW != 4'hF)
- NS <= YES;
- else
- NS <= NO;
- YES:if(ROW != 4'hF)
- NS <= YES;
- else
- NS <= NO;
- endcase
- reg [3:0]ROW_val,COL_val;
- always@(posedge CLK_1K or negedge RSTN)
- begin
- if(!RSTN)
- begin
- COL <= 0;
- flag <= 0;
- end
- else
- case(NS)
- NO:begin
- COL <= 0;
- flag <= 0;
- end
- S0:begin
- COL <= 4'b1110;
- end
- S1:begin
- COL <= 4'b1101;
- end
- S2:begin
- COL <= 4'b1011;
- end
- S3:begin
- COL <= 4'b0111;
- end
- YES:begin
- COL_val <= COL;
- ROW_val <= ROW;
- flag <= 1;
- end
- endcase
- end
- /////////////////////////////////////////////////////////
- reg flag_pre;
- always@(posedge CLK_1K or negedge RSTN)
- begin
- if(~RSTN)
- flag_pre <= 0;
- else
- flag_pre <= flag;
- end
- //assign flag_pos = (~flag_pre)&flag;
- assign flag_pos = flag_pre & (~flag);
- /////////////////////////////////////////////////////////
- always@(posedge CLK_1K or negedge RSTN)
- begin
- if(~RSTN)
- key_value <= 0;
- else
- if(flag)
- case({ROW_val,COL_val})
- 8'b1110_1110: key_value <= 4'h1;
- 8'b1110_1101: key_value <= 4'h2;
- 8'b1110_1011: key_value <= 4'h3;
- 8'b1110_0111: key_value <= 4'ha;
-
- 8'b1101_1110: key_value <= 4'h4;
- 8'b1101_1101: key_value <= 4'h5;
- 8'b1101_1011: key_value <= 4'h6;
- 8'b1101_0111: key_value <= 4'hb;
-
- 8'b1011_1110: key_value <= 4'h7;
- 8'b1011_1101: key_value <= 4'h8;
- 8'b1011_1011: key_value <= 4'h9;
- 8'b1011_0111: key_value <= 4'hc;
-
- 8'b0111_1110: key_value <= 4'h0;
- 8'b0111_1101: key_value <= 4'he;
- 8'b0111_1011: key_value <= 4'hf;
- 8'b0111_0111: key_value <= 4'hd;
- endcase
- end
- key_esk #(4) K1(
- .CLK_1K(CLK_1K),
- .key_in(key_value),
- .key_out(real_num)
- );
- endmodule
复制代码 |
|