【FPGA】【Verilog】【基础模块】矩阵键盘

结构:用4条I/O线作为行线,4条I/O线作为列线组成的键盘。在行线和列线的每一个交叉点上,设置一个按键。


检测方法:【置列线,检测行线(行线包含上拉电阻)】依次将列线置为低电平,即在置某一根列线为低电平时,其它列线为高电平。同时再逐行检测各行线的电平状态 ;若某行为低,则该行线与置为低电平的列线交叉处的按键就是闭合的按键。

代码:

module Test_unit(clk,rst_n,keyin,keyscan,LED);

 input 			clk,rst_n;
 input 	[3:0]		keyin;
 output 	[3:0] 	keyscan;
 output	reg 	[15:0]	LED; 

 wire [4:0] real_number;
 
 	keyscan0 u2(
				.clk(clk),
				.rst_n(rst_n),
				.keyscan(keyscan),
				.keyin(keyin),
				.real_number(real_number)
				);

always @(*)
	case(real_number)
		5'd0:	LED	<=	16'b0_00000_00000_00001;
		5'd1:	LED	<=	16'b0_00000_00000_00010;
		5'd2:	LED	<=	16'b0_00000_00000_00100;
		5'd3:	LED	<=	16'b0_00000_00000_01000;
		5'd4:	LED	<=	16'b0_00000_00000_10000;
		5'd5:	LED	<=	16'b0_00000_00001_00000;
		5'd6:	LED	<=	16'b0_00000_00010_00000;
		5'd7:	LED	<=	16'b0_00000_00100_00000;
		5'd8:	LED	<=	16'b0_00000_01000_00000;
		5'd9:	LED	<=	16'b0_00000_10000_00000;
		5'd10:LED	<=	16'b0_00001_00000_00000;
		5'd11:LED	<=	16'b0_00010_00000_00000;
		5'd12:LED	<=	16'b0_00100_00000_00000;
		5'd13:LED	<=	16'b0_01000_00000_00000;
		5'd14:LED	<=	16'b0_10000_00000_00000;
		5'd15:LED	<=	16'b1_00000_00000_00000;
	default:	LED	<=~16'b1_11111_11111_11111;
	endcase 
endmodule 
		
 
`define OK 1'b1	//定义OK代表1
`define NO 1'b0	//定义NO代表0
`define NoKeyIsPressed 17	//定义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)  //always块1
 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)   //always块2  
 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) 	//always块3
  casex({scancode,keyin})
    8'b0111_1110: numberout <= 5'd1-1;
    8'b1011_1110: numberout <= 5'd5-1;  
    8'b1101_1110: numberout <= 5'd9-1;
    8'b1110_1110: numberout <= 5'd13-1; 
    
    8'b0111_1101: numberout <= 5'd2-1;
    8'b1011_1101: numberout <= 5'd6-1;  
    8'b1101_1101: numberout <= 5'd10-1;
    8'b1110_1101: numberout <= 5'd14-1; 
        
    8'b0111_1011: numberout <= 5'd3-1;
    8'b1011_1011: numberout <= 5'd7-1; 
    8'b1101_1011: numberout <= 5'd11-1;
    8'b1110_1011: numberout <= 5'd15-1; 
    
    8'b0111_0111: numberout <= 5'd4-1;
    8'b1011_0111: numberout <= 5'd8-1;  
    8'b1101_0111: numberout <= 5'd12-1;
    8'b1110_0111: numberout <= 5'd16-1;
    default: numberout <=`NoKeyIsPressed;
   endcase
   
always @(posedge clk) 	//always块4
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)  //always块5
 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
管脚分配【AX301】:

效果:按个键,亮个相应数字的灯。

  • 5
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的Verilog程序,用于确定四乘四矩阵键盘中一个按钮的状态: ``` module keyboard ( input wire clk, //时钟信号 input wire rst, //复位信号 input wire [3:0] row, //4个行引脚输入 output wire [3:0] col, //4个列引脚输出 output reg [15:0] key //16个键值状态输出 ); reg [3:0] row_d; //行输入延迟寄存器 reg [15:0] key_d; //键值延迟寄存器 always @(posedge clk or negedge rst) begin if (!rst) begin row_d <= 4'b0000; key_d <= 16'b0000000000000000; end else begin row_d <= {row_d[2:0], row}; //将新的行输入存储到延迟寄存器中 key_d <= key; //键值状态保持不变 end end assign col = ~key_d[15:12]; //根据键值状态计算列输出 always @(posedge clk or negedge rst) begin if (!rst) begin key <= 16'b0000000000000000; //复位时所有键值状态为0 end else begin case ({row_d[3], row_d[2], row_d[1], row_d[0]}) //根据行列位置计算当前按键的键值 4'b1110: key <= 16'b0000000000000001; 4'b1101: key <= 16'b0000000000000010; 4'b1011: key <= 16'b0000000000000100; 4'b0111: key <= 16'b0000000000001000; default: key <= 16'b0000000000000000; endcase end end endmodule ``` 这个Verilog程序实现了一个简单的四乘四矩阵键盘控制模块,其中包含一个按键状态寄存器和一个行输入延迟寄存器。在时钟信号的作用下,将新的行输入存储到延迟寄存器中,然后根据行列位置计算出当前按键的键值,并将键值状态存储到寄存器中。最后,根据键值状态计算列输出,作为下一次扫描的输入。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值