怀揣少年梦 发表于 2021-12-16 14:36

【国产FPGA高云GW1N-4系列开发板测评】动态数码管显示之秒表

<p style="text-align:justify"><span style="font-size:10.5pt"><span style="150%"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">本次就进行数码管动态显示练习</font></span></span></span></span></span></p>

<p style="text-align:justify"><span style="font-size:10.5pt"><span style="150%"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">一、目标</font></span></span></span></span></span></p>

<p style="text-indent:21.0000pt; text-align:justify"><span style="font-size:10.5pt"><span style="150%"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">利用三个拨码开关和四个数码管进行秒表计时。即一个拨码开关开始计时,一个拨码开关暂停计时,一个拨码开关复位。</font></span></span></span></span></span></p>

<p style="text-align:justify"><span style="font-size:10.5pt"><span style="150%"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">二、原理</font></span></span></span></span></span></p>

<p style="text-indent:21.0000pt; text-align:justify"><span style="font-size:10.5pt"><span style="150%"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="Calibri">1</font><font face="宋体">、动态数码管的原理:上一次练习进行了静态数码管显示。但是同时让多个数码管显示数字呢?其实很简单,就是利用人的视觉暂留现象(人眼在观察外物时,光信号传入大脑神经,需经过一段短暂的时间,光的作用结束后,视觉影像并不立即消失)和数码管的余晖现象(当停止向发光二极管供电时发光二极管亮度仍能维持一段时间),即可以让一只数码管亮,再让另一个数码管亮,如果中间切换的时间很短就会让人眼觉得同时显示两个数码管,这种显示方式为动态扫描。</font></span></span></span></span></span></p>

<p style="text-indent:21.0000pt; text-align:justify"><span style="font-size:10.5pt"><span style="150%"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="Calibri">2</font><font face="宋体">、秒表原理:即让分频时钟产生</font><font face="Calibri">1Hz</font><font face="宋体">的时钟信号,并每隔一秒加</font><font face="Calibri">1</font><font face="宋体">,同时呢进行数码管动态扫描。秒表是由</font><font face="Calibri">3</font><font face="宋体">个拨码开关进行控制的。</font></span></span></span></span></span></p>

<p style="text-align:justify"><span style="font-size:10.5pt"><span style="150%"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">三、硬件</font></span></span></span></span></span></p>

<p style="text-indent:21.0000pt; text-align:justify"><span style="font-size:10.5pt"><span style="150%"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">由开发板的原理图可知,四个拨码开关向上拨都是高电平,向下拨都是低电平。可以进行扫描拨码开关的输入电平,进而实现秒表的控制。</font></span></span></span></span></span></p>

<p style="text-indent:21.0000pt; text-align:justify"></p>

<p style="text-align:justify"><span style="font-size:10.5pt"><span style="150%"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">四、软件部分</font></span></span></span></span></span></p>

<p style="text-align:justify"><span style="font-size:10.5pt"><span style="150%"><span style="font-family:Calibri"><span style="font-size:10.5000pt"><span style="font-family:宋体"><font face="宋体">代码如下:</font></span></span></span></span></span></p>

<p style="text-align:justify">时钟分频部分</p>

<pre>
<code>`define UD #1//在引用已定义的宏名时,必须在宏名的前面加上符号“`”,表示该名字是一个经过宏定义的名字.
               //宏定义不是Verilog HDL语句,不必在行末加分号。如果加了分号会连分号一起进行置换
               //宏名和宏内容必须在同一行中进行声明。如果在宏内容中包含有注释行,注释行不会作为被置换的内容

module div_clk(
    inputsys_clk,//系统时钟 50Mhz
   
    output clk_1hz,//1Hz时钟
    output clk_1ms//1ms时钟
);


reg time_cnt = 0;//用于保存分频计数值
reg ms_cnt = 0; //用于保存分频计数值
reg flag = 0;//用于产生正负信号标志
reg ms_flag = 0;//用于产生正负信号标志
always @(posedge sys_clk)
begin
    if(time_cnt == 26'h2faf080-1'b1)
      time_cnt &lt;= `UD 26'd0;
    else
      time_cnt &lt;= `UD time_cnt + 1'b1;
end


always @(posedge sys_clk)
begin
    if(ms_cnt == 16'hc350-1'b1)
      ms_cnt &lt;= `UD 16'd0;
    else
      ms_cnt &lt;= `UD ms_cnt + 1'b1;
end


//分频,产生1Hz时钟
always @(posedge sys_clk)
begin   
    if(time_cnt == 26'h2faf080/2-1'b1)
      flag &lt;= `UD 1'b1;
    else if(time_cnt == 26'h2faf080-1'b1)
      flag &lt;= `UD 1'b0;
end   


//分频,产生1000Hz时钟
always @(posedge sys_clk)
begin   
    if(ms_cnt == 16'hc350/2-1'b1)
      ms_flag &lt;= `UD 1'b1;
    else if(ms_cnt == 16'hc350-1'b1)
      ms_flag &lt;= `UD 1'b0;
end

assign clk_1ms = ms_flag;
assign clk_1hz = flag;

endmodule</code></pre>

<p style="text-align:justify">&nbsp;</p>

<p style="text-align:justify">秒表控制和动态扫描部分</p>

<pre>
<code>/*
数码管显示实验,进行每秒显示不同的数字
4个数码管
*/

`define UD #1//延时1个时间单位

module stopwatch(
    inputsys_clk,//系统时钟
    inputsys_rst_n,
    inputkey,

    output dig,//位选
    output regsmg//数码管段码
);


wire clk_1hz;//变量
wire clk_1ms;
div_clk u_div_clk
(
    .sys_clk(sys_clk),
    .clk_1hz(clk_1hz),
    .clk_1ms(clk_1ms)
);



reg stop_flag = 0;
reg start_flag = 0;
reg continue_flag = 0;
reg reset_flag = 0;

always @(posedge sys_clk)
begin
    if(key == 1)
      start_flag = 1;//开始计时
    else
      start_flag = 0;//停止计时,并归0
    if(key == 1)
      stop_flag = 1;//暂停计时
    else
      stop_flag = 0;//继续计时
    if(key == 1)
      reset_flag = 1;//复位
    else
      reset_flag = 0;
end

reg second_counter_ge = 0;//秒个位计时
reg second_counter_shi = 0;//秒十位计时
reg minute_counter = 0;//分计时
reg num = 0;//要显示的数字

always @(posedge clk_1hz)
begin
    if(second_counter_ge == 4'd9) //秒个位加到9进位(使用除法,比较耗费资源)
    begin
      second_counter_ge &lt;= `UD 4'd0;
      second_counter_shi &lt;= `UD second_counter_shi + 1'b1;
      if(second_counter_shi == 4'd5) //秒十位加到5,并且个位到9,分钟加1
      begin
            second_counter_shi &lt;= `UD 4'd0;
            minute_counter &lt;= `UD minute_counter + 1'b1;
            if(minute_counter == 4'd9)
            begin
                second_counter_shi &lt;= 0;
                minute_counter   &lt;= 0;
                second_counter_ge&lt;= 0;
            end
      end
    end
    else
    begin
      if(start_flag &amp;&amp; (!stop_flag) &amp;&amp; (!reset_flag))//正常计时,暂停不增加秒
            second_counter_ge &lt;= `UD second_counter_ge + 1'b1;
      else if(start_flag == 0 || reset_flag == 0)
      begin
            second_counter_ge &lt;= 0;
            minute_counter &lt;= 0;
      end
    end      
end

parameter smg_one   = 4'b1110;
parameter smg_two   = 4'b1101;
parameter smg_three = 4'b1011;
parameter smg_four= 4'b0111;
reg sel ;
reg disp_sel;
//使用状态机进行数码管扫描
always @(posedge clk_1ms or negedge sys_rst_n)
begin
    if(!sys_rst_n)
    begin   
      sel &lt;= smg_one;
      disp_sel = 4'b1110;
    end
    else
    begin
      case(sel)
            smg_one:
            begin
            disp_sel &lt;= 4'b1110;sel &lt;= smg_two;num &lt;= second_counter_ge;
            end
            smg_two:
            begin
            disp_sel &lt;= 4'b1101;sel &lt;= smg_three;num &lt;= second_counter_shi;
            end
            smg_three:
            begin
            disp_sel &lt;= 4'b1011;sel &lt;= smg_four;num &lt;= 4'd10;
            end         
            smg_four:
            begin
            disp_sel &lt;= 4'b0111;sel &lt;= smg_one;num &lt;= minute_counter;
            end
            default :sel &lt;= smg_one;
      endcase
    end
end


//共阳极
assign dig = disp_sel; //显示一位
//0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80,0x90
//显示部分 共阳极,为0有效
always @(*)
begin   
    case(num)
      4'd0:smg = 8'hc0;//数字0
      4'd1:smg = 8'hf9;//数字1
      4'd2:smg = 8'ha4;//数字2
      4'd3:smg = 8'hb0;//数字3
      4'd4:smg = 8'h99;//数字4
      4'd5:smg = 8'h92;//数字5
      4'd6:smg = 8'h82;//数字6
      4'd7:smg = 8'hf8;//数字7
      4'd8:smg = 8'h80;//数字8
      4'd9:smg = 8'h90;//数字9
      4'd10:smg = 8'hBF;//符号-
      default:smg = 8'hc0;//数字0
    endcase
end


endmodule

</code></pre>

<p style="text-indent:21.0000pt; text-align:justify">&nbsp;</p>

<p style="text-align:justify">五、实验现象</p>

<p style="text-align:justify"></p>

<p style="text-align:justify">&nbsp;</p>

<p style="text-align:justify"></p>

<p style="text-align:justify">&nbsp;</p>

annysky2012 发表于 2021-12-16 15:55

评测很详细,继续加油

怀揣少年梦 发表于 2021-12-16 16:54

annysky2012 发表于 2021-12-16 15:55
评测很详细,继续加油

<p>FPGA小白一枚,多谢鼓励</p>
页: [1]
查看完整版本: 【国产FPGA高云GW1N-4系列开发板测评】动态数码管显示之秒表