11_基于FPGA的按键计数器

11_基于FPGA的按键计数器

实验原理

按键计数器顾名思义,就是对按键按下进行次数,然后将计数的结果显示在数码管上。因此,首先必须对按键进行消抖,由于FPGA开发板的时钟为50MHz,并且FPGA为硬件设计,所以对毛刺十分敏感,在该工程中采用状态机消抖对按键进行消抖,消抖后对按键进行计数,最后将计数结构显示在数码管上。

设计原理流程图如下:

 

硬件原理图

实验代码

/********************************版权声明**************************************

** 大西瓜团队

**

**----------------------------文件信息--------------------------

** 文件名称: key_counter.v

** 创建日期:

** 功能描述:按键计数,将结构显示于数码管

** 硬件平台:大西瓜第三代开发板,http://daxiguafpga.taobao.com

** 版权声明:本代码属个人知识产权,本代码仅供交流学习.

**---------------------------修改文件的相关信息----------------

** 修改人:

** 修改日期:    

** 修改内容:

*******************************************************************************/

module key_counter(clk,key,reset,seg_duan,seg_wei);

input clk,key,reset;

output [7:0] seg_duan;

output [2:0] seg_wei;

 

wire clk,key,reset;

reg [7:0] seg_duan;//数码管段选

reg [2:0] seg_wei;//数码管位选

 

reg key_out;

parameter s0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11;

reg [1:0] state;

reg [3:0] key_counter_ge;//按键计数个位

reg [3:0] key_counter_shi;//按键计数十位

reg [3:0] key_counter_bai;//按键计数百位

reg [9:0] div_count;//数码管扫描时钟分频计数

reg clk_scan;//位选时钟

reg [1:0] wei_select;//位选信号

/****************************按键消抖**********************************/

always @(posedge clk)

begin

case (state)

s0:

begin

key_out<=1'b1;

if(key==1'b0)

state<=s1;

else

state<=s0;

end

s1:

begin

if(key==1'b0)

state<=s2;

else

state<=s0;

end

s2:

begin

if(key==1'b0)

state<=s3;

else

state<=s0;

end

s3:

begin

if(key==1'b0)

begin

key_out<=1'b0;

state<=s3;

end

else

begin

key_out<=1'b1;

state<=s0;

end

end

default:

state<=s0;

endcase

end

/****************************按键计数**********************************/

always @(negedge key_out or negedge reset)

begin

if(!reset)

begin

key_counter_ge <=4'd0;

key_counter_shi<=4'd0;

key_counter_bai<=4'd0;

end

else

begin

if(!key_out)//判断按键是否按下

begin

key_counter_ge<=key_counter_ge+1'b1;//按键计数个位加一

if(key_counter_ge==4'd9)

begin

key_counter_ge<=4'd0;//个位清零

key_counter_shi<=key_counter_shi+1'b1;//按键计数十位加一

if(key_counter_shi==4'd9)

begin

key_counter_shi<=4'd0;//十位清零

key_counter_bai<=key_counter_bai+1'b1;//按键计数百位加一

if(key_counter_bai==4'd9)

key_counter_bai<=4'd0;//百位清零

end

end

end

end

end

/****************************数码管扫描时钟*********************************/

always @(posedge clk)//产生位选时钟

begin

if(div_count==10'd1000)

begin

div_count<=10'd0;

clk_scan<=~clk_scan;

end

else

div_count<=div_count+10'd1;

end

 

always @(posedge clk_scan)//产生位选信号

begin

if(wei_select==2'b11)

wei_select<=2'b00;

else

wei_select<=wei_select+1'b1;

end

/****************************数码管显示*********************************/

always @(key_counter_ge or key_counter_shi or key_counter_bai or wei_select)

begin

if(wei_select==2'b00)

begin

seg_wei<=3'b110;

case(key_counter_ge)

4'b0000:begin seg_duan<=8'b1100_0000;end//0

4'b0001:begin seg_duan<=8'b1111_1001;end//1

4'b0010:begin seg_duan<=8'b1010_0100;end//2

4'b0011:begin seg_duan<=8'b1011_0000;end//3

4'b0100:begin seg_duan<=8'b1001_1001;end//4

4'b0101:begin seg_duan<=8'b1001_0010;end//5

4'b0110:begin seg_duan<=8'b1000_0010;end//6

4'b0111:begin seg_duan<=8'b1111_1000;end//7

4'b1000:begin seg_duan<=8'b1000_0000;end//8

4'b1001:begin seg_duan<=8'b1001_0000;end//9

default seg_duan<=8'bx;

endcase

end

else

begin

if(wei_select==2'b01)

begin

seg_wei<=3'b101;

         case(key_counter_shi)

         4'b0000:begin seg_duan<=8'b1100_0000;end//0

         4'b0001:begin seg_duan<=8'b1111_1001;end//1

         4'b0010:begin seg_duan<=8'b1010_0100;end//2

         4'b0011:begin seg_duan<=8'b1011_0000;end//3

         4'b0100:begin seg_duan<=8'b1001_1001;end//4

         4'b0101:begin seg_duan<=8'b1001_0010;end//5

         4'b0110:begin seg_duan<=8'b1000_0010;end//6

         4'b0111:begin seg_duan<=8'b1111_1000;end//7

         4'b1000:begin seg_duan<=8'b1000_0000;end//8

         4'b1001:begin seg_duan<=8'b1001_0000;end//9

         default seg_duan<=8'bx;

         endcase

end

else

begin

seg_wei<=3'b011;

         case(key_counter_bai)

         4'b0000:begin seg_duan<=8'b1100_0000;end//0

         4'b0001:begin seg_duan<=8'b1111_1001;end//1

         4'b0010:begin seg_duan<=8'b1010_0100;end//2

         4'b0011:begin seg_duan<=8'b1011_0000;end//3

         4'b0100:begin seg_duan<=8'b1001_1001;end//4

         4'b0101:begin seg_duan<=8'b1001_0010;end//5

         4'b0110:begin seg_duan<=8'b1000_0010;end//6

         4'b0111:begin seg_duan<=8'b1111_1000;end//7

         4'b1000:begin seg_duan<=8'b1000_0000;end//8

         4'b1001:begin seg_duan<=8'b1001_0000;end//9

         default seg_duan<=8'bx;

         endcase

end

end

end

endmodule

 

实验操作

实验效果

 

 

大西瓜FPGA-->https://daxiguafpga.taobao.com

配套开发板:https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-24211932856.3.489d7241aCjspB&id=633897209972

博客资料、代码、图片、文字等属大西瓜FPGA所有,切勿用于商业! 若引用资料、代码、图片、文字等等请注明出处,谢谢!

   

每日推送不同科技解读,原创深耕解读当下科技,敬请关注微信公众号"科乎"。

posted @ 2022-02-20 17:17  logic3  阅读(1244)  评论(0编辑  收藏  举报