【FPGA】【入门基础】二、FPGA实现PWM呼吸灯

这篇博客分享了一段Verilog代码,用于实现一个PWM(脉宽调制)控制器。代码详细注释了各个模块的功能,包括计数器、状态标志位和占空比调整,以实现周期为10ms的PWM信号,占空比可在1s内增减变化。通过.xdc文件配置了时钟和I/O端口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码

废话不多说,直接上代码,千言万语都在注释里。
博主也是基于例程学习的,在这只是加上自己的理解,并写在注释里来记录学习成果。

.v文件

module pwm_led(
    input wire clk ,    //定义输入时钟
    input wire rst_n ,  //定义复位信号
    output wire led     //定义一个输出led信号
);

//parameter define 常量定义
parameter CNT_10MS  = 500000 - 1;//时钟频率为50M,此为定义10ms计数值
parameter CNT_2S    = 200 -1;    //和10ms计数相配合,计200次10ms即为2s
parameter CHANGE_TIME = 100 - 1; //和10ms计数相配合,计100次10ms即为1s
parameter PWM_OFFSET  = 5000;    //占空比的值每次增加或减少的量

reg [19:0] cnt_10ms;    //计10ms的二进制数的20位寄存器
reg [7:0] cnt_2s;       //计2s的二进制数的8位寄存器(结合上面常量定义进行理解)
reg pwm ;               //该定义为led状态的反量,结合下面的assign理解
reg [19:0] duty_cycle;  //占空比定义,最大值和周期10ms对应
reg work_flag;          //状态标志位,决定占空比的值是增加还是减少

assign led = ~pwm ; 

//---cnt_10ms
always @(posedge clk or posedge rst_n) begin
    if (rst_n==1'b0) begin
        // reset
        cnt_10ms <= 'd0 ; 
    end
    else if (cnt_10ms == CNT_10MS) begin
        cnt_10ms <= 'b0;
    end
    else begin
        cnt_10ms<=cnt_10ms+1'b1;
    end
end

//---cnt_2s
always @(posedge clk or posedge rst_n) begin
    if (rst_n==1'b0) begin
        // reset
        cnt_2s<=1'b0;
    end
    else if (cnt_10ms==CNT_10MS) begin
        if(cnt_2s==CNT_2S)begin
            cnt_2s<=1'b0;
        end
        else begin
            cnt_2s<=cnt_2s+1'b1;
        end
    end
end

//---work_flag
always @(posedge clk or posedge rst_n) begin
    if (rst_n==1'b0) begin
        // reset
        work_flag<=1'b0;
    end
    else if (cnt_2s==CHANGE_TIME&&cnt_10ms==CNT_10MS) begin
        work_flag<=1'b1;//当计数到1s时,改变状态标志位
    end

     else if (cnt_2s == CNT_2S && cnt_10ms == CNT_10MS) begin
        work_flag <= 1'b0;//当计数到2s时,改变状态标志位
     end
end

//---duty_cycle
always @(posedge clk or posedge rst_n) begin
    if (rst_n==1'b0) begin
        // reset
        duty_cycle<=1'b0;
    end
    else if (work_flag==1'b0) begin
        if (cnt_10ms==CNT_10MS) begin
            duty_cycle<=duty_cycle+PWM_OFFSET;//当状态标志位为0时,增加占空比
        end
        else begin
            duty_cycle<=duty_cycle;
        
    end
end

    else if (work_flag==1'b1) begin
        if (cnt_10ms==CNT_10MS) begin
            duty_cycle <= duty_cycle - PWM_OFFSET;//当状态标志位为1时,减少占空比
        end
        else begin
            duty_cycle <= duty_cycle;
        end
    end
end

//---pwm    此处更准确来说是led状态的判断,在一个周期内当时间小于占空比或大于占空比时的状态
always @(posedge clk or posedge rst_n) begin
    if (rst_n==1'b0) begin
        // reset
        pwm <= 1'b0;
    end
    else if (cnt_10ms<duty_cycle) begin
        pwm <= 1'b1;
        end 
        else begin
            pwm <= 1'b0;
        end
end

endmodule

.xdc文件

############## clock define##################
create_clock -period 20.000      [get_ports clk]
set_property PACKAGE_PIN N18     [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
############## key define##################
set_property PACKAGE_PIN P16     [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
##############LED define##################
set_property PACKAGE_PIN P15 	 [get_ports led]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports led]
set_property IOSTANDARD LVCMOS33 [get_ports clk]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值