06分频计数器之呼吸灯2

一设计功能:从灭到亮,时间为2秒,再从亮到灭也为2秒,总的时间为4秒。现象是,led灯的亮度从暗逐渐到亮的过程,再从亮逐渐变暗。

二设计实现之我看:(一)可调占空比的方波。可调占空比,是对于一个周期固定的方波信号,即方波的高电平持续时间或翻转时间不断改变。

(二)实现过程:

      把2秒分成1000份,则每份为2ms,对于这两毫秒的方波,它的占空比在不断变化,如第一个为0.1%, 第二个为0.2%,依次不断增加到最大占空比1(即再把2ms分成1000份,即2us, 每次随着第N个方波的到来,方波的翻转时间随着N变化)然后回到初始值,不断循环。

三设计输入:

    (一)2us的计数器:参数化设计,且每计满2us产生一个标志信号: T2us_full

parameter T2us = 7'd99;

parameter T2ms = 18'd99_999;

 

//2us timer

reg T2us_full;//count to 2us

reg [6:0]div_cnt;

always@(posedge clk)begin

if(rst==0)begin

    T2us_full<=0;

    div_cnt<=7'd0;

    end

else if(div_cnt==T2us)begin

    T2us_full<=1;

    div_cnt<=7'd0;

    end

else begin

    T2us_full<=0;

    div_cnt<=div_cnt+1'b1;

end

end

    (二)以2us为基本计数单位的计数器:第一个模块,每计满2us计数值加一,直到最大值999(也是计到了2ms),回到初始值0。第二个模块,在第一个模块计到最大值999时,产生一个计满2ms的标志信号T2ms_full。

//2us counter

reg [9:0]T2us_cnt;

 

always@(posedge clk)begin

if(rst==0)

T2us_cnt<=10'd0;

else if(T2us_cnt==999)

T2us_cnt<=10'd0;

else if(T2us_full)

T2us_cnt<=T2us_cnt+1'b1;

else

    T2us_cnt<=T2us_cnt;

 

end

//2ms counter

reg T2ms_full;

always@(posedge clk)begin

if(rst==0)

    T2ms_full<=1'b0;

else if(T2us_cnt==999)begin

    T2ms_full<=1'b1;

end

else begin

    T2ms_full<=1'b0;

end

end

    (三)2ms的方波数量的计数器:分成两部分,一是从0-999的加一模式,二是从999-0的减一模式,两个相反模式的切换是利用标志信号控制。具体过程是每计满2ms方波计数值加一,直到最大值999,再利用标志信号切换到减一模式,从999减到0时再切换为加一模式,不断循环。

//the count of wave:1000,cnt_wave.

//two part:0-999 and 999-0 by dec_en

reg dec_en;

reg[9:0]cnt_wave;

always@(posedge clk)begin

if(rst==0)

    cnt_wave<=10'd0;

 

elseif(T2ms_full)begin

    case(dec_en)

    1'b0:

    if(cnt_wave==999)begin

    cnt_wave<=cnt_wave;

    dec_en <=1'b1;

end

    elsebegin

    cnt_wave<=cnt_wave+1'b1;

end

 

1'b1:

    if(cnt_wave==10'd0)begin

        dec_en <=1'b0;

        cnt_wave<=cnt_wave;

    end

    else

        cnt_wave<=cnt_wave -1'b1;

    endcase

end

end

    (四)可变占空比的方波的产生和led的翻转(周期为2秒):一是产生一个方波的标志信号wave_flag。二是通过这个wave_flag的高电平控制LED的亮。

//generate wave

reg wave_flag;

always@(posedge clk)begin

if(rst==0)begin

wave_flag<=1'b0;

end

else if(T2us_cnt==(999-cnt_wave))begin

    wave_flag<=1'b1;

end

else if(T2us_cnt==999)begin

wave_flag<=1'b0;

end

else begin

    wave_flag<=wave_flag;

end

end

 

 //the control of led

always@(posedge clk)begin

if(rst==0)begin

led<=1'b0;

end

else if(wave_flag==1)begin

led<=1;

end

else begin

    led<=0;

end

end

四:总结

    (一)遇到问题:1.一是仿真时,LED的波形一直为零。

    解决办法:直接把仿真时长100ns 改为100us  ,再改为100ms后直到波形出现。原因是,LED灯闪烁周期至少是2ms.完整的时间为2秒,故至少是ms的量级才行。

    2.烧写工程bit文件到开发板,led一直未亮。

    解决办法:由于仿真正确,猜测可能是在建立工程和管脚约束方面出问题了,所以我照着正确的管脚约束文件,改了一下格式。实现LED灯闪烁。

下面表格是管脚约束文件的正确格式:

NET "clk" LOC=p24 | IOSTANDARD=LVCMOS33;

NET "rst" LOC=p94 | IOSTANDARD=LVCMOS33;

NET "led" LOC=p92 | IOSTANDARD=LVCMOS33;

      (二)设计过程的方法

   1.照图施工(如时序图或者电路的系统框图)

    第一点我的做法是,在A4纸上画出各个模块信号的时序图,如时钟信号,2us的计满标志等。通过这些波形的时序图,就能够理清思路,快速完成设计。

      第二点,循序渐进,如不知道怎么设置占空比可变,那就先想想占空比固定的LED闪烁,分成了1秒的计数器和计满1秒后的时钟脉冲翻转,由此可以推理只需要把翻转的计数值改变,即可实现占空比变化。

      (三)仿真波形:

 

 
原文地址:https://www.cnblogs.com/Xwangzi66/p/12845626.html