接收PID输出的可调占空比PWM

  1. PWM波原理非常简单, 核心是精度控制, 原定占空比输入为百分比, 导致精度只能到1%, 现在直接引入pid输入, 在module计算占空比, 精度可以到0.01%

  2. 四舍五入的两种技巧

java 复制代码
`timescale 1ns / 1ps
//****************************************VSCODE PLUG-IN**********************************//
//----------------------------------------------------------------------------------------
// IDE :                   VSCODE     
// VSCODE plug-in version: Verilog-Hdl-Format-3.7.20250728
// VSCODE plug-in author : Jiang Percy
//----------------------------------------------------------------------------------------
//****************************************Copyright (c)***********************************//
// Copyright(C)            Please Write Company name
// All rights reserved     
// File name:              
// Last modified Date:     2025/08/07 11:50:51
// Last Version:           V1.0
// Descriptions:           
//----------------------------------------------------------------------------------------
// Created by:             Please Write You Name 
// Created date:           2025/08/07 11:50:51
// mail      :             Please Write mail 
// Version:                V1.0
// TEXT NAME:              pwm.v
// PATH:                   C:\Users\Administrator\Desktop\工作记录\vivado\PWM\PWM.srcs\sources_1\new\pwm.v
// Descriptions:           
//  频率生成、占空比精度均为万一                       
//----------------------------------------------------------------------------------------
//****************************************************************************************//

module pwm(
    input                               clk                        ,
    input                               rst_n                      ,
    input                               enable                     ,//enable 为0输出默认值
    input                [  17: 0]      Freq_wave                  ,
    input                [  15: 0]      Duty_cycle                 ,//由pid产生 max 为65535--》100%
    output                              pwm_out_p                  ,
    output                              pwm_out_n                   
);

    //---------------------------------------------------------------------------------------
    // PWM Parameters  
    //我们使用锯齿波和直流比较生成pwm 
    //  1. sys_clk_freq_hz 生成PWM的系统时钟频率
    //  2. Freq_wave 决定锯齿波的频率,同时也是pwm的频率
    //  3. duty_cycle 定义pwm波的占空比  单位为百分比
    //  4  thres为锯齿波的比较值,大于时pwm为0;小于时pwm为1                                                                              
    //---------------------------------------------------------------------------------------
    parameter                           sys_clk_freq_hz             = 400_000_000          ;
    //parameter                           Freq_wave                   = 100_000              ;    
    //parameter                           Duty_cycle                  = 50                   ;

    //parameter                           max_cnt_wave                = sys_clk_freq_hz/Freq_wave;
    //parameter                           thres                       = Duty_cycle * max_cnt_wave /100;
    //---------------------------------------------------------------------------------------
    // 内部变量定义                                                                                    
    //---------------------------------------------------------------------------------------   
    reg                [  17: 0]        r_Freq_wave                 ;
    reg                [   6: 0]        r_Duty_cycle                ;
    reg                [  11: 0]        cnt_wave                    ;
    reg                                 out_pwm                     ;
    wire               [  11: 0]        max_cnt_wave                ;
    wire               [  10: 0]        thres                       ;
    wire               [  27: 0]        duty_temp                   ;

    //---------------------------------------------------------------------------------------
    // 时序与组合逻辑定义                                                                                    
    //---------------------------------------------------------------------------------------
     // 1. 频率计算(带四舍五入,降低频率误差)
    assign                              max_cnt_wave                = (sys_clk_freq_hz+ r_Freq_wave/2) / r_Freq_wave;
        // 2. 占空比计算(基于PID输出,无比例误差)
    // 公式:duty_threshold = (pid_output * max_cnt_wave) / MAX_DUTY
    //assign                              thres                       = r_Duty_cycle * max_cnt_wave/100;
    assign                              duty_temp                   = r_Duty_cycle * max_cnt_wave;
    assign                              thres                       = duty_temp[27:16] + (duty_temp[15] ? 1'b1 : 1'b0);// 四舍五入
        
        // 输入数据打拍
        always @(posedge clk or negedge rst_n)
            begin
                if(!rst_n)
                    begin
                    r_Freq_wave <= 100_000;
                    r_Duty_cycle <= 37268;
                    end
                else if(enable)
                    begin
                    r_Freq_wave  <= Freq_wave;
                    r_Duty_cycle <= Duty_cycle;
                    end
                
            end
        //

        always @(posedge clk or negedge rst_n)
            begin
                if(!rst_n)
                    cnt_wave <= 0;
                else if(cnt_wave == max_cnt_wave-1)
                    cnt_wave <= 0;
                else cnt_wave <= cnt_wave + 1;
            end

       always @(posedge clk or negedge rst_n)
           begin
               if(!rst_n)
                    out_pwm <= 0;
               else if(cnt_wave <= thres-1)
                    out_pwm <= 1;
               else
                    out_pwm <= 0;
           end
    assign                              pwm_out_p                   = out_pwm              ;
    assign                              pwm_out_n                   = ~out_pwm             ;

                                                                   
                                                                   
endmodule
相关推荐
9527华安8 小时前
国产安路FPGA开发设计培训课程,提供开发板+工程源码+视频教程+技术支持
fpga开发·fpga·安路·视频教程·培训·安路fpga
UVM_ERROR15 小时前
硬件设计实战:解决Valid单拍采样失效问题(附非阻塞赋值与时序对齐核心要点)
驱动开发·fpga开发·github·芯片
brave and determined16 小时前
可编程逻辑器件学习(day36):从沙粒到智能核心:芯片设计、制造与封装的万字全景解析
fpga开发·制造·verilog·fpga·芯片设计·硬件设计·芯片制造
步达硬件1 天前
【FPGA】FPGA开发流程
fpga开发
我爱C编程2 天前
【仿真测试】基于FPGA的完整16QAM通信链路实现,含频偏锁定,帧同步,定时点,Viterbi译码,信道,误码统计
fpga开发·16qam·帧同步·卷积编码·viterbi译码·维特比译码·频偏锁定
s09071362 天前
ZYNQ DMA to UDP 数据传输系统设计文档
网络协议·fpga开发·udp
燎原星火*3 天前
QSPI IP核 基本参数
fpga开发
XINVRY-FPGA3 天前
XCVU9P-2FLGC2104I Xilinx AMD Virtex UltraScale+ FPGA
嵌入式硬件·机器学习·计算机视觉·fpga开发·硬件工程·dsp开发·fpga
FPGA_小田老师3 天前
FPGA Debug:PCIE一直自动重启(link up一直高低切换)
fpga开发·pcie debug·pcie初始化问题
hexiaoyan8273 天前
视频信号检测板卡:208-Base Camera Link 图像信号模拟器
fpga开发·图像信号模拟器·视频信号检测·视频信号分析·智能图像分析