#FPGA(矩阵键盘—数码管)

1.IDE:Quartus II


2.设备:Cyclone II  EP2C8Q208C8N  


3.实验:数码管显示矩阵键盘按下的数字


4.时序图:


5.步骤:(1)行raw扫描

           (2)行raw作为输出,列col作为输入

           (3)20ms扫描一行

           (4)特别要注意输入端口引脚的初始化电平,这个问题让我花了很久时间才发现。特别是                      我所使用的开发板上面没有上拉或者下拉。

           (5)矩阵键盘引脚分配

                     5280820a1bcc403a92374c675dcadf43.jpeg

            (6)原理图

  f5878a6c5eb14c529773903c62266cdd.jpeg 

             (7) 运行效果

FPGA矩阵键盘运行效果

 

              


6.代码:

marix_keypad.v

/*
 *col默认为输入高电平!!!
 */
module marix_keypad(
input   wire         sys_clk    ,
input   wire         sys_rst_n  ,
input   wire  [3:0]  col        ,

output  reg   [3:0]  row        ,
output  reg   [3:0]  char      
);

reg     wait_filter ;
reg   [19:0]    cnt ;
parameter row_scan_period  =   20'd1000_000;                 //20ms扫描一次


parameter first_row        = 4'b1110;
parameter second_row       = 4'b1101;
parameter third_row        = 4'b1011;
parameter fourth_row       = 4'b0111;

parameter first_col        = 4'b1110;
parameter second_col       = 4'b1101;
parameter third_col        = 4'b1011;
parameter fourth_col       = 4'b0111;


/*
 *row扫描控制
 */
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n == 1'b0)  
	     row <= first_row;
	 else if(cnt == row_scan_period && wait_filter == 1'b0)             //循环扫描
		  row <= {row[2:0],row[3]};
	 else
	     row <= row;
end
/*
 *char 字符赋值
 */
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n == 1'b0) begin
        char <= 4'd0;
        wait_filter <= 1'b0;	 
	 end
	 
	 else if(row == first_row) begin            //第一row扫描
	     case(col)
		      first_col  : begin   char <= 4'd0;  wait_filter <= 1'b1; end
				second_col : begin   char <= 4'd1;  wait_filter <= 1'b1; end
				third_col  : begin   char <= 4'd2;  wait_filter <= 1'b1; end
				fourth_col : begin   char <= 4'd3;  wait_filter <= 1'b1; end
	         default    : begin   char <= char;  wait_filter <= 1'b0; end
		  endcase
	 end
	 
	 else if(row == second_row) begin            //第二row扫描
	     case(col)
		      first_col  : begin  char <= 4'd4; wait_filter <= 1'b1; end
				second_col : begin  char <= 4'd5; wait_filter <= 1'b1; end
				third_col  : begin  char <= 4'd6; wait_filter <= 1'b1; end
				fourth_col : begin  char <= 4'd7; wait_filter <= 1'b1; end
				default    : begin  char <= char; wait_filter <= 1'b0; end
	     endcase
	 end
	 
	 else if(row == third_row) begin            //第三row扫描
	     case(col)
		      first_col  : begin   char <= 4'd8;   wait_filter <= 1'b1; end
				second_col : begin   char <= 4'd9;   wait_filter <= 1'b1; end
				third_col  : begin   char <= 4'd10;  wait_filter <= 1'b1; end
				fourth_col : begin   char <= 4'd11;  wait_filter <= 1'b1; end
				default    : begin   char <= char;   wait_filter <= 1'b0; end 
	     endcase
	 end
	 
	 else if(row == fourth_row) begin            //第四row扫描
	     case(col)
		      first_col  : begin  char <= 4'd12;   wait_filter <= 1'b1; end
				second_col : begin  char <= 4'd13;   wait_filter <= 1'b1; end
				third_col  : begin  char <= 4'd14;   wait_filter <= 1'b1; end
				fourth_col : begin  char <= 4'd15;   wait_filter <= 1'b1; end
				default    : begin  char <= char;    wait_filter <= 1'b0; end
	     endcase
	 end
	 
	 else begin
	         char <= char;
	 end
			
end

/*
 *扫描计数器控制(2ms)
 */
always @ (posedge sys_clk or negedge sys_rst_n) begin
       if(sys_rst_n == 1'b0)
		    cnt <= 20'd0;
		 else if(cnt == row_scan_period)
		    cnt <= 20'd0;
		 else
		    cnt <= cnt + 1'b1;
end

endmodule

顶层代码

module keypad_smg(
input              sys_clk       , 
input              sys_rst_n     ,
input   wire  [3:0]  col         ,
output  wire  [3:0]  row         ,

output  wire  qw                  ,
output  wire  bw                  ,
output  wire  sw                  ,
output  wire  gw                  ,
output  wire  [7:0]   smg 
);

wire       [3:0]    char         ;

/*
 *实例化矩阵键盘
 */
marix_keypad marix_keypad_inst(
.sys_clk             (sys_clk  )       ,
.sys_rst_n           (sys_rst_n)       ,
.col                 (col      )       ,
                             
.row                 (row      )       ,
.char                (char     )      
);

/*
 *实例化数码管
 */
smg smg_inst
(
.     clk                    (sys_clk         ),
.     rst_n                  (sys_rst_n       ),
.     data                   (char            ),

.     qw                     (qw              ),
.     bw                     (bw              ),
.     sw                     (sw              ),
.     gw                     (gw              ),
.     smg                    (smg             )
);

endmodule

 


 

 

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值