基于安路SparkRoad开发板的模60计数器设计与实现

        本设计目的是在FPGA中设计一个模60计数器,并通过数码管动态显示出来。

一. 整体模块化设计

  该工程包含顶层模块counter60以及底层模块accum和Data_show。

       accum模块实现分频器以及计数器的功能;Data_show模块实现数据的数码管的动态显示。

       整体工程模块图如下:

二.数码管硬件部分电路

  通过原理图可知,位选信号由AN0,AN1,AN2,AN3控制,段选信号由CG,CC,CH,CD,CE,CA,CF,CB控制,由此可知为八段数码管。

  由下图可知,数码管段选信号以及位选信号皆为低电平有效。

以下为四位位选控制信号和八段段选控制信号对应的FPGA引脚:

  实现数码管的动态显示,四位数码管的段选信号同时控制,轮流点亮位选信号。

  由于余晖效应,加上人眼的视觉暂留效果,我们看四位数码管时四个数码管是同时亮的。

  动态显示的优点是节省IO资源。

三.分析设计代码实现

1.顶层模块counter60

  在其中实现对底层模块accum和Data_show的例化。

module counter60(

		input   wire 	clk_24m	,
		input 	wire 	rst_n	,
		
		output  wire  [7:0] seg	,
		output  wire  [3:0] dig
		
 );

wire [7:0] num;

accum  accum_inst
(
		.clk_24m	(clk_24m	),
        .rst_n		(rst_n		),
        
        .num		(num		)
		
); 

Data_show  Data_show_inst
(
		.clk_24m	(clk_24m	),
        .rst_n		(rst_n		),
        .num		(num		),
  
        .seg		(seg 		),
        .dig		(dig		)
); 


endmodule

2.底层模块accum,分频器和计数器

分频器产生频率为1HZ的时钟clk1,对计数功能进行描述。

核心部分代码如下:

initial num = 8'b1; //置初值为1,实现1-60的计数

always@( posedge clk_24m or negedge rst_n )
	if( rst_n == 1'b0 )
		cnt <= 24'd0;
	else if( cnt == 25'd12_000_000-1'b1 )
		begin 
			cnt <= 24'd0;
			clk1 <= ~clk1;
		end
	else 
		begin 
			cnt  <= cnt + 1'b1;
			clk1 <= clk1;
		end

always@( posedge clk1 or negedge rst_n ) //对计数功能进行描述
	if( rst_n == 1'b0 )
		num <= 8'd1;
	else if( num[3:0] == 4'd9 )
		begin
			num[3:0] <= 4'd0;
			num[7:4] <= num[7:4] + 1'b1;
		end
	else if( num[7:4] == 4'd6 && num[3:0] == 4'd0 )
		begin
			num[3:0] <= 4'd1;
			num[7:4] <= 4'd0;
		end
	else
		num[3:0] <= num[3:0] + 1'b1;

3.数码管动态显示模块Data_show

  为实现数码管的动态显示,通过动态扫描的方法处理数码管的位选信号。

  定义信号cnt_w,产生0.01秒的标志信号。通过对其最高位cnt_w[17]的0和1变换实现位选信号dig[1]以及dig[0]的扫描显示,轮流点亮后两位,但由于余辉效应以及人眼的视觉残留,我们看到的是数码管后两位一直保持亮起。

核心代码如下:

reg  [17:0]  cnt_w		;
reg  [3:0] 	 Result	 	;
parameter CNT_W_MAX = 18'd240_000;

always@(posedge clk_24m or negedge rst_n)
	begin
		if(rst_n == 1'b0 )
			cnt_w <= 18'd0;
		else if(cnt_w == CNT_W_MAX)  
			cnt_w <= 18'd0;
		else
			cnt_w <= cnt_w + 1;
	end

always@(posedge clk_24m or negedge rst_n)
	if( rst_n == 1'b0 )
		dig <= 4'b1111;
	else 
		begin
			case( cnt_w[17] )    //动态扫描数码管后两位 实现动态显示
				1'b0:dig    <= 4'b1110; 
				1'b1:dig    <= 4'b1101; 
			endcase
		end
		
always@(posedge clk_24m or negedge rst_n)
	begin
		if( rst_n == 1'b0 )
			Result <= 4'd0;
		else
			begin
				case( cnt_w[17] )  
				1'b0:Result   <= num[3:0]; 
				1'b1:Result   <= num[7:4]; 
				endcase
			end
	end		

always@(*)
	begin
		case ( Result )
			4'd0:seg <= 8'hc0;
			4'd1:seg <= 8'hf9;
			4'd2:seg <= 8'ha4;             
			4'd3:seg <= 8'hb0;              
			4'd4:seg <= 8'h99;             
			4'd5:seg <= 8'h92;             
			4'd6:seg <= 8'h82;             
			4'd7:seg <= 8'hf8;            
			4'd8:seg <= 8'h80;             
			4'd9:seg <= 8'h90;
			default:seg <= 8'hc0;
		endcase
	end	

四.运行结果展示

  成功实现1-60的计数功能,计数器模为60。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个坚定的ICer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值