zxopenljx 发表于 2020-4-28 14:56:27

数码管动态显示之分频模块

首先,我们要知道自己所用开发板的晶振时钟频率f0 以及我们想得到的目标时钟频率f1。

    f0 = 50MHZ    f1 = 1kHZ

我们采用计数器的思想
定义一个cnt(计数器)、cnt_max(计数终点值)
最小计数器的位宽为26位

f0 = 50MHZ       T0 = 1/f0 =20ns         
f1 = 1kHZ          T1 =1/f1= 1ms
cnt_max(计数终点值) = 1ms/20ns = 50MHZ/1kHZ

计数器分频时序:

计数器(cnt)在时钟上升沿采集数据,我们要得到一个周期为1ms的时钟,即0.5ms低电平和0.5ms高电平。那么,我们让输出的clk_out在计数终点值一半(cnt_max/2)时,取反一次就可以了。如下图所示。

我们将需求分析清楚后,写代码就显得不是那么难了。

源代码:   
    00 module freq(clk, rst_n, clk_out);
    01
    02      input clk;               //系统时钟
    03      input rst_n;               //复位
    04      
    05      output reg clk_out;       //输出时钟
    06      
    07      reg cnt;            //定义一个26位位宽的计数器
    08      
    09      /*定参*/
    10      parameter cnt_max =50_000_000/1000/2-1;    //0.5ms 设定一个计数的最大值(根据所需输出时钟来设定)
    11      
    12      //计数
    13      always@(posedge clk,negedge rst_n)
    14      begin
    15      if(!rst_n)                                 //判断复位
    16               begin
    17                   cnt <=26'd0;                  //计数器清零
    18                   clk_out <=1'b0;               //给输出时钟一个高电平(1)或低电平(0)都可以,在这里笔者给了一个低电平
    19               end   
    20         else                                 //如果没有复位
    21               begin
    22                   if(cnt < cnt_max)            //判断计数器cnt,是否小于cnt_max
    23                     cnt <= cnt +1;             //如果小于,让计数器cnt + 1,继续计数
    24                   else                           //否则
    25                     begin
    26                           cnt <=26'b0;          //让计数器清零
    27                           clk_out <=~clk_out;//时钟取相反值
    28                     end
    29               end
    30      end
    31
    32 endmodule

这样我们就得到了我们所需的1kHZ的数码管驱动时钟了。

zxopenljx 发表于 2023-8-19 17:42:01

数码管动态显示之分频模块
页: [1]
查看完整版本: 数码管动态显示之分频模块