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所有,切勿用于商业! 若引用资料、代码、图片、文字等等请注明出处,谢谢!
每日推送不同科技解读,原创深耕解读当下科技,敬请关注微信公众号"科乎"。