数电实验4:PWM波形产生

1 设计要求分析

        本次实验的任务为设计一种PWM波形产生逐级递进的占空比,PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,PWM波形即占空比从高到低,从低到高的一种数字基带波形信号,可以驱动产生呼吸灯的效果。

2 系统设计

2.1 总体设计思路

        实验采用50MHz时钟进行系统仿真,由周期信号计数器,占空比调节模块与PWM波形输出模块构成,由周期信号计数器在时钟驱动下产生一个周期计数值,与占空比调节模块输出的占空比进行比较,来输出特定的PWM信号,同时需要设计一个低电平有效的异步复位信号,当复位信号为低,系统立刻复位。

2.2 接口设计

        

端口数I/O功能描述
I_sys_clkinput50MHz时钟信号
I_sys_rst_ninput低电平有效复位信号
O_pwmoutput输出的PWM波形信号

2.3 周期信号计数器        

        输入为I_sys_clk和I_sys_rst_n,均为wire型变量,代表输入时钟和输入低电平有效复位信号,由于要求异步复位,不与时钟同步,所以在always块中,敏感列表包括时钟上升沿时刻和低电平复位信号下降沿。

        输出端口为period_cnt,变量类型为reg,在复位信号作用下初始化或者从0计到4后溢出清零,其他情况下将在时钟驱动下自加,即一共有从0到4五个状态。

2.4 占空比调节模块

        输入为I_sys_clk和I_sys_rst_n,为wire型变量,以及reg型变量period_cnt,与周期信号计数器相同,占空比调节模块的敏感列表包括时钟上升沿时刻和低电平复位信号下降沿。

        输出端口为duty_cycle和duty_cycle_inc_dec_flag,其中前者代表了当前的占空比数值,和计数器一样有从0到4五种状态,分别代表20%,40%,60%,80%,100%的占空比,后者标志了当前的占空比是正在降低还是正在增加,用0代表递增,1代表递减。

        在复位信号的下降沿,模块将初始化duty_cyle和duty_cycle_inc_dec_flag为0,即开始从占空比20%递增,在无复位信号同时周期计数器正好计满一个周期后(计数值为4),占空比调节模块将在时钟信号上升沿的驱动下,根据duty_cycle_inc_dec_flag的标志对duty_cycle进行自加或者自减,当自增至最大的4或自减至最小的0时,将duty_cycle_inc_dec_flag的值反转。

2.5 PWM输出模块

        输入为duty_cycle和period_cnt,即分别为周期计数器和占空比调节的输出,输出为O_pwm,该模块将两个输入值比较,若占空比值较为大,则输出为1,否则输出为0,用一条assign语句将其赋值给O_pwm。

3 功能仿真测试

3.1 源程序设计

`timescale 1ns / 1ps

module Pwm(
    input           I_sys_clk,
    input           I_sys_rst_n,
    
    output          O_pwm
    );
    reg     [2:0]   period_cnt;
    reg     [2:0]   duty_cycle;
    reg             duty_cycle_inc_dec_flag;
    //PWM输出模块
    assign      O_pwm = (period_cnt >= duty_cycle) ? 1'b0 :1'b1;
    //周期计数器
    always @(posedge I_sys_clk or negedge I_sys_rst_n) begin
        if(!I_sys_rst_n) begin
            period_cnt <= 3'd0;
        end
        else if(period_cnt == 3'd4) begin
            period_cnt <= 3'd0;
        end
        else begin
            period_cnt <= period_cnt+1'b1;
        end
    end
    //占空比调节模块
    always @(posedge I_sys_clk or negedge I_sys_rst_n) begin
        if(!I_sys_rst_n)begin
            duty_cycle <= 3'd0;
            duty_cycle_inc_dec_flag <= 3'b0;
        end
        else begin
            if(period_cnt == 3'd4) begin
                if(duty_cycle_inc_dec_flag == 1'b0) begin
                    if(duty_cycle == 3'd4) begin
                        duty_cycle_inc_dec_flag <= 1'b1;
                    end
                    else begin
                        duty_cycle <= duty_cycle +3'd1;
                    end
                end
                else begin
                    if(duty_cycle == 3'd0) begin
                        duty_cycle_inc_dec_flag <= 1'b0;
                    end
                    else begin
                        duty_cycle <= duty_cycle -3'd1;
                    end
                end
            end
        end
    end
endmodule

3.2 testbench程序测试

`timescale 1 ps/ 1 ps
module Pwm_tb();
// test vector input registers
reg I_sys_clk;
reg I_sys_rst_n;
// wires                                               
wire O_pwm;

//模块例化                       
Pwm i1 (
	.I_sys_clk(I_sys_clk),
	.I_sys_rst_n(I_sys_rst_n),
	.O_pwm(O_pwm)
);

initial begin                                                                                     
    I_sys_clk = 1'b0;//初始化时钟
    I_sys_rst_n = 1'b0;//初始化复位信号
    #10 I_sys_rst_n = 1'b1;                       
end  
//50MHz时钟产生                                                  
always #10 I_sys_clk =~I_sys_clk;                                                 
                                     
                                                 
endmodule

3.3 时序仿真波形

 

3.4 结果分析 

        由上面的时序波形图可知,O_pwm会输出占空比从低到高再从高到低的PWM波形

4 思考

        如果要求信号占空比的步进为25%(即存在四个状态25%,50%,75%,100%),该如何设计程序并实现?

        应该将周期计数器的溢出上限和占空比模块的占空比值上限从4改为3,即以25%的步进产生4种占空比值,代码和仿真图如下:

   always @(posedge I_sys_clk or negedge I_sys_rst_n) begin
        if(!I_sys_rst_n) begin
            period_cnt <= 3'd0;
        end
        else if(period_cnt == 3'd3) begin//4修改为3
            period_cnt <= 3'd0;
        end
        else begin
            period_cnt <= period_cnt+1'b1;
        end
    end
    
    always @(posedge I_sys_clk or negedge I_sys_rst_n) begin
        if(!I_sys_rst_n)begin
            duty_cycle <= 3'd0;
            duty_cycle_inc_dec_flag <= 3'b0;
        end
        else begin
            if(period_cnt == 3'd3) begin//4修改为3
                if(duty_cycle_inc_dec_flag == 1'b0) begin
                    if(duty_cycle == 3'd3) begin//4修改为3
                        duty_cycle_inc_dec_flag <= 1'b1;
                    end
                    else begin
                        duty_cycle <= duty_cycle +3'd1;
                    end
                end
                else begin
                    if(duty_cycle == 3'd0) begin
                        duty_cycle_inc_dec_flag <= 1'b0;
                    end
                    else begin
                        duty_cycle <= duty_cycle -3'd1;
                    end
                end
            end
        end
    end
endmodule

 5 技术小结与感想

        通过这次实验,了解了状态机的工作原理和编写流程,实现了PWM波形的输出,同时也练习了Vivado的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sue٩(๑•̀ω•́๑)۶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值