• FPGA PWM呼吸灯


    1. MATLAB仿真

    首先对该PWM算法进行验证,载波和调制信号均为三角波,频率相差50倍。

    f=50000;%时钟频率
    num=10;%重复周期数
    radio=50;%调制比
    carrier=zeros(1,f/radio);%载波
    for i=1:(f/radio)
        if i<=(f/(2*radio))
            carrier(i)=i;
        else
            carrier(i)=(f/radio)-i;
        end
    end
    modulating=repelem(carrier,radio);%调制信号
    carrier=repmat(carrier,1,radio);
    time=0:1/f:num-1/f;
    output=zeros(f,1);%PWM输出
    output(1)=1;
    for i=2:f
        if((carrier(i)>modulating(i) && carrier(i-1)<=modulating(i-1)) || ...
                (carrier(i)<modulating(i) && carrier(i-1)>=modulating(i-1)))
            output(i)=~output(i-1);
        else
            output(i)=output(i-1);
        end
    end
    output=repmat(output,num,1);
    PWM=timeseries(output,time');
    

    绘出图像,如下图所示,可以看到输出信号占空比先增大后减小,输出信号均值跟随调制信号变化。

    subplot(2,1,1);
    stairs((0:f-1)/f,[carrier;modulating]');
    subplot(2,1,2);
    plot((0:f-1)/f,output(1:f));
    ylim([-0.2,1.2]);
    

    image

    2. Simulink验证

    在Simulink中构建一个简单的电路模型,对波形进行观察。

    image

    观察电流波形,可以看到其接近三角波,PWM调制结果正确。

    image

    3. 源文件

    将上面的算法用Verilog进行描述。

    carrier为载波,modulating为调制信号,flag_c指示carrier处于上升沿还是下降沿,同样,flag_m指示modulating的状态。

    clk上升沿到来,carrier变化一次,radio加一;radio计数达50,modulating变化一次。

    module breath_led(
        output reg led = 1'b0,  // LED1, 1 on, 0 off
        input      clk,  // FPGA PL clock, 50 MHz
        input      rst_n // FPGA reset pin
    );
     reg [18:0] carrier = 19'b0;
     reg [18:0] modulating = 19'b0;
     reg [5:0] radio = 6'b0;
     reg flag_c = 0;
     reg flag_m = 0;
        //clock input 50000000
    parameter CLOCK_FREQ = 50000000;
    parameter COUNTER_MAX = CLOCK_FREQ/100;
    
        always @(posedge clk, negedge rst_n) begin
            if(!rst_n) begin
                carrier <= 19'b0;
                flag_c <= 0;
            end
            else begin
                if(flag_c == 0)
                    carrier <= carrier + 1'b1;
                else
                    carrier <= carrier - 1'b1;
                if(carrier == COUNTER_MAX-1)
                    flag_c <= 1;
                else if(carrier == 1)
                    flag_c <= 0;
            end
        end
        always @(posedge clk, negedge rst_n) begin
            if(!rst_n) begin
                radio <= 6'b0;
                modulating <= 19'b0;
                flag_m <= 0;
            end
            else begin
                if(radio == 49) begin
                    radio <= 6'b0;
                    if(flag_m == 0)
                        modulating <= modulating + 1'b1;
                    else
                        modulating <= modulating - 1'b1;
                    if(modulating == COUNTER_MAX-1)
                        flag_m <= 1;
                    else if(modulating == 1)
                        flag_m <= 0;
                end
                else
                    radio <= radio + 1'b1;
            end
        end
        always @(posedge clk, negedge rst_n) begin
            if(!rst_n) begin
                led <= 1'b0;
            end
            else begin
                if(carrier>modulating)
                    led <= 1'b0;
                if(carrier<modulating)
                    led <= 1'b1;
            end
        end
    endmodule

    4. 仿真文件

    `define clk_cycle 10
    module breath_led_sim();
        reg clk, rst_n;
        wire led;
        always #`clk_cycle clk = ~clk;
        initial begin
            clk = 0;
            rst_n = 1;
            #10 rst_n = 0;
            #10 rst_n = 1;
        end
    breath_led breath_led(.rst_n(rst_n), .clk(clk), .led(led));
    endmodule

     仿真1s,观察波形,如下图所示。与MATLAB计算结果相一致。

    image

    5. 实现

  • 相关阅读:
    如何区分DDR1 DDR2 DDR3内存条
    《闪电战》德军攻略
    WINDOWS SERVER 2008 R2安装指南
    【django】django学得好迷茫啊 来个学习规划吧
    【阅读】提问的智慧+有效的报告BUG
    【Python】logging模块学习笔记
    【接口测试】进度表
    【django】django深入学习笔记
    【随笔】2014工作总结
    【英语】Bingo口语笔记(47)
  • 原文地址:https://www.cnblogs.com/dingdangsunny/p/12817185.html
Copyright © 2020-2023  润新知