#FPGA(动态数码管)

1.IDE:Quartus II


2.设备:Cyclone II  EP2C8Q208C8N  


3.实验:之前做的数码管实验一直有问题,今天解决了。

(1)模块要足够细化,不要写得臃肿 !!!!!!!!!!

(2)注意每次扫描前需要将所有数码管先关闭,因为我们的数码管会在上一次使用时打开某一位。


4.时序图:


5.步骤:


6.代码:

smg.v

module smg
#( parameter show_number = 14'd9999 )
(
input      wire          clk,
input      wire        rst_n,

output     reg        qw,      //用于共阳极数码管控制数码管的开关(千位)
output     reg        bw,      //用于共阳极数码管控制数码管的开关(百位)
output     reg        sw,      //用于共阳极数码管控制数码管的开关(十位)
output     reg        gw,      //用于共阳极数码管控制数码管的开关(个位)
output     reg [7:0]  smg      //映射到真实引脚中
);

parameter   show_zero   = 8'b11000000;
parameter   show_one    = 8'b11111001;
parameter   show_two    = 8'b10100100;
parameter   show_three  = 8'b10110000;
parameter   show_four   = 8'b10011001;
parameter   show_five   = 8'b10010010;
parameter   show_six    = 8'b10000010;
parameter   show_seven  = 8'b11111000;
parameter   show_eight  = 8'b10000000;
parameter   show_nine   = 8'b10010000;

reg [25:0] cnt;
reg [13:0] counter;     //数码管计数值
reg [3:0]  qw_value;    //数码管千位的值
reg [3:0]  bw_value;    //数码管百位的值
reg [3:0]  sw_value;    //数码管十位的值
reg [3:0]  gw_value;    //数码管个位的值
reg [1:0]  scan_ws;     //数码管扫描位数序列号(0 个位 1 百位 2 十位 3 千位)
reg [3:0]  scan_value;  //单个位扫描值


/*
 *计数器(时基20ns 50MHz)
 */
always @ (posedge clk or negedge rst_n) begin
   if(!rst_n)
	   cnt <= 26'd0;
	else begin
	   if(cnt < 26'd50000000)
		   cnt <= cnt + 1'b1;
		else
		   cnt <= 26'd0;
	end
	
end

/*
 *定时器(1s),用于数码管显示
 */
always @ (posedge clk or negedge rst_n) begin
   if(!rst_n) 
		counter <= 14'd0;
   
	else if(cnt == 26'd50000000) begin
	   if(counter < 14'd9999) 
		   counter <= counter +1'b1;
      else
         counter <= 14'd0;
	end

end
		

/*
 *选择打开的数码管
 */
always @ (posedge clk or negedge rst_n) begin
   if(!rst_n) begin
		  qw <= 1'b1;
		  bw <= 1'b1;
		  sw <= 1'b1;
		  gw <= 1'b1;
	     scan_value <= 4'd0;
   end
   else if(!(cnt % 26'd200000)) begin      //4ms 
        bw <= 1'b1;                        //全关(因为程序执行中会打开部分数码管,每次单位数码管扫描前先关闭所有数码管)
        sw <= 1'b1;
        gw <= 1'b1;
        qw <= 1'b1;
		  case(scan_ws)                     //决定打开哪个数码管
		     2'b00  : begin
			  scan_value <= gw_value;
           gw <= 1'b0;			   
			  end                                     
			  2'b01  : begin                         
			  scan_value <= sw_value;                 
			  sw <= 1'b0;
			  end
			  2'b10  : begin
			  scan_value <= bw_value;
			  bw <= 1'b0;
			  end
			  2'b11  : begin
			  scan_value <= qw_value;
			  qw <= 1'b0;
			  end
			  default : ;
		  endcase
	end 
end

/*
 *向数码管写入数据
 */
always @ (posedge clk or negedge rst_n) begin
   if(!rst_n) begin
	   smg <= show_zero;
	end
   else begin
	    case(scan_value)            
          4'd0 : smg <= show_zero;
          4'd1 : smg <= show_one;
          4'd2 : smg <= show_two;
          4'd3 : smg <= show_three;
          4'd4 : smg <= show_four;
          4'd5 : smg <= show_five;
          4'd6 : smg <= show_six;
          4'd7 : smg <= show_seven;
          4'd8 : smg <= show_eight; 
          4'd9 : smg <= show_nine;  
          default : ;
		 endcase 
	end
end	
	

/*
 *扫描位号赋值
 */
always @ (posedge clk or negedge rst_n) begin
       if(!rst_n)
		  scan_ws <= 2'b00;
       else if(!(cnt % 26'd200000)) begin         //到达刷新时间
		  if(scan_ws == 2'b11)
		     scan_ws <= 2'b00;
		  else
		     scan_ws <= 2'b01 + scan_ws;
		 end
		 else
		     scan_ws <= scan_ws ;
end

/*
 *向扫描值千百十个位赋值
 */
always @ (posedge clk or negedge rst_n) begin
       if(!rst_n) begin
			qw_value <= 4'd0;
			bw_value <= 4'd0;
			sw_value <= 4'd0;
			gw_value <= 4'd0;
		 end
		 else begin
		   qw_value <= show_number/10'd1000;
		   bw_value <= show_number/7'd100%4'd10;
		   sw_value <= show_number/4'd10%4'd10;
		   gw_value <= show_number%4'd10;
		 end
end		   
		 
		 
 
endmodule
	 

top_smg.v

/*
 *顶层模块
 */
module top_smg
(
input      wire      clk,
input      wire      rst_n,

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

/*
 *实例化
 */
smg 
#(.show_number     (14'd1234) )
smg_inst
 (
  .clk             (clk  )      ,
  .rst_n           (rst_n)      ,
             
  .qw              (qw   )      ,      
  .bw              (bw   )      ,      
  .sw              (sw   )      ,      
  .gw              (gw   )      ,      
  .smg             (smg  )
 );
 
endmodule
 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值