FPGA-50秒倒计时的实现(特权XILINX spartan-6开发板)

网友投稿 1017 2022-11-16

FPGA-50秒倒计时的实现(特权XILINX spartan-6开发板)

FPGA-50秒倒计时的实现(特权XILINX  spartan-6开发板)

工具 ISE14.7

通过时间分频在4位7段数码管中显示2个数字,给人眼一个错觉是同时显示出两个数字。

实验原理是轮流向各位数码管送出字形码和相应的位选信号,利用数码管闪烁的余晖和人眼视觉的暂留作用,使人感觉像各位管同时在显示

就像单片机数码管的思想一样:这里也要做相同的事情。

单片机步骤如下:

动态显示:

1)位选数码管;  2)段选数码管; 3)延时

dula=1;//段选 P0=table[i]; dula=0; P0=0xff; wela=1;//位选 P0=a; wela=0; delayms(500);//延时

这样的代码实现流水显示,如果延时时间够短肉眼难以分辨;则可以实现几位数据的同时显示;

同理到FPGA中也是这样,不过要考虑用不同的模块实现这个功能

EG 两位数码管显示:

单片机中延时用个delay就可以实现,但是这里的延时要用一个计数器来模拟延时的状态

1.0)段选选择数码管显示的数值

1.1)因为这里我代码中值用了4个位来显示当前的数据(数据位宽为4)所以要在不同的时间选择当前显示的值

2)位选选择数码管的位数

3)延时(保证动态显示肉眼分辨不出)

代码如下:

module seg(clk,ext_rst_n,TimeH,TimeL,dtube_cs_n,dtube_data ); input clk; //时钟信号25MHz input ext_rst_n; //复位信号 input [3:0]TimeH; //两位输入高位 input [3:0]TimeL; //两位输入低位 output reg[1:0] dtube_cs_n; //段选数据位 output reg[6:0] dtube_data;//位选数据位 reg[3:0] display_num; //当前显示数据 reg[15:0] div_cnt; //延时计数器计数位initial div_cnt = 0;//赋初值为0//延时计数器模块 always@ (posedge clk or negedge ext_rst_n) begin if(!ext_rst_n) div_cnt <= 8'd0; else if(div_cnt==16'd50000) div_cnt <= 8'd0; else div_cnt <= div_cnt+1'b1; end //显示当前的数据模块 always @(posedge clk or negedge ext_rst_n) begin if(!ext_rst_n) display_num <= 4'h0; else if(div_cnt < 25000) display_num <= TimeH; else display_num <= TimeL; end //段选数据译码模块(共阴数码管) always @(posedge clk or negedge ext_rst_n) begin if(!ext_rst_n) dtube_data <= 8'h00; else begin case(display_num) 4'h0: dtube_data <= 8'h3f; 4'h1: dtube_data <= 8'h06; 4'h2: dtube_data <= 8'h5b; 4'h3: dtube_data <= 8'h4f; 4'h4: dtube_data <= 8'h66; 4'h5: dtube_data <= 8'h6d; 4'h6: dtube_data <= 8'h7d; 4'h7: dtube_data <= 8'h07; 4'h8: dtube_data <= 8'h7f; 4'h9: dtube_data <= 8'h6f; default:dtube_data <= 8'h00; endcase end end//位选选译模块 always @(posedge clk or negedge ext_rst_n) begin if(!ext_rst_n) dtube_cs_n <= 2'b11; else if(div_cnt < 20000) dtube_cs_n <= 2'b01; else dtube_cs_n <= 2'b10; endendmodule

数码管显示模块定义好了就要想如何实现倒计时的完成

这里的设计思路是

顶层设计模块

分频器模块  -->      计数器模块 ----->     数码管显示模块

输入复位信号 和系统时钟

1)分频器输入25MHz输出1Hz

2)IHz时钟信号传给计数器模块用于计数

3)计数的值在数码管显示

输出数码管的段选和位选

和蜂鸣器(计时完成标志位)

代码如下:

1,.TOP.v

module top(ext_clk_25m,ext_rst_n,beep,dtube_cs_n,dtube_data );//顶层控制模块 input ext_clk_25m; //时钟信号25MHz input ext_rst_n; //复位信号 output [1:0] dtube_cs_n; //段选数据位 output [6:0] dtube_data;//位选数据位 output beep; //计时完成标志位 wire clk;//中间变量 wire [3:0] TimeL; wire [3:0] TimeH; //分频25MHZ变为1HZ div d1( .ext_clk_25m(ext_clk_25m), .ext_rst_n(ext_rst_n), .mclk(clk) ); //倒计时计数模块 counter c1( .mclk(clk), .ext_rst_n(ext_rst_n), .TimeH(TimeH), .TimeL(TimeL), .beep(beep) ); //数码管显示模块 seg s1( .clk(ext_clk_25m), .ext_rst_n(ext_rst_n), .TimeH(TimeH), .TimeL(TimeL), .dtube_cs_n(dtube_cs_n), .dtube_data(dtube_data) );endmodule

2.div.v

module div(ext_clk_25m,ext_rst_n,mclk ); input ext_clk_25m;//输入时钟 input ext_rst_n; //复位端口 output reg mclk;//输出1Hz reg [23:0] cnt;//存放计数器的值initial cnt = 0; parameter TIME=24'd1250_0000;//时钟25MHz//分频模块//使得输入时钟为25MHz输出时钟为1Hz always@(posedge ext_clk_25m or negedge ext_rst_n) begin if(!ext_rst_n) begin mclk <=1'b0; cnt <=25'd0; end else if(cnt ==TIME-1'b1) begin mclk <=~mclk; cnt <=1'b0; end else cnt <=cnt + 1'b1; endendmodule

3.counter.v

module counter(mclk,ext_rst_n,TimeH,TimeL,beep ); input mclk;//时钟信号 input ext_rst_n;//复位信号 output reg [3:0]TimeH;//两位数码管显示高位 output reg [3:0]TimeL;//两位数码管显示低位 output beep; //计数完成位 assign beep =({TimeH,TimeL}==8'h00);//当计数为0时,蜂鸣器响initial {TimeH,TimeL} = 8'h50; //计数器赋初值//计数器模块 always@(posedge mclk or negedge ext_rst_n) begin if(!ext_rst_n) {TimeH,TimeL} <= 8'h50; else if({TimeH,TimeL}==8'h00) {TimeH,TimeL} <={TimeH,TimeL}; else if(TimeL==4'h0) begin TimeH <=TimeH-1'b1; TimeL <=4'h9; end else begin TimeH <=TimeH; TimeL <=TimeL-1'b1; end endendmodule

4.数码管.v

上文已经贴出

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:微信小程序flex容器属性详解
下一篇:给新来的同事讲where 1=1是什么意思
相关文章

 发表评论

暂时没有评论,来抢沙发吧~