zoukankan      html  css  js  c++  java
  • 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秒后的时钟脉冲翻转,由此可以推理只需要把翻转的计数值改变,即可实现占空比变化。

          (三)仿真波形:

     

     
  • 相关阅读:
    如何运行 PPAS上的pgpoolII
    Postmaster主循环的大致流程
    对ListenSocket 的研究(三)
    对ListenSocket 的研究(二)
    对ListenSocket 的研究(五)
    PostgreSQL的postmaser的fork的学习体会
    赛门铁克公告:解密Kneber恶意软件 狼人:
    微软免费杀毒软件MSE最新版本释出 狼人:
    Facebook出现邮件错发故障 隐私安全再受关注 狼人:
    McAfee和Brocade将联合开发网络安全解决方案 狼人:
  • 原文地址:https://www.cnblogs.com/Xwangzi66/p/12845626.html
Copyright © 2011-2022 走看看