This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28379D:我的高分辨率 PWM 信号在+/-1 TBCLK 处的第一个周期值的占空比。

Guru**** 2539500 points
Other Parts Discussed in Thread: TMS320F28379D, CCSTUDIO, SYSCONFIG

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1302577/tms320f28379d-the-duty-cycle-of-the-first-period-value-at--1-tbclk-of-my-high-resolution-pwm-signal

器件型号:TMS320F28379D
主题中讨论的其他器件: CCStudioSysConfig
大家好、我在 TMS320F28379D CCStudio 上进行编码。 我想创建一个占空比恰好为50%的高分辨率 PWM 信号。
因此、我将 PWM 配置为高电平周期分辨率、将 CMP 配置为向上/向下计数。 PWM 计算和信号对于所有周期值 (208ns、210ns、220ns)都非常有效、并且我的占空比处于50%以内。
当周期不承认 HRPRD (TBPRDHR=0)并且当 CMP=PRD/2完全正确时、信号中会显示一个错误、但仅当我的代码被启动时。
例如:200ns -> PRD= 10、CMP = 5 = 10/2 (相同、240ns 等)。 我观察到占空比的缩放比例为+/- 1 TBCLK (10ns)。 但奇怪的是、当我在任何周期(例如208ns)实时修改周期值 、然后再次更改为200ns 时、占空比为 50%、并且+/- 1 TBCLK 不再存在。 但是、当我实时查看 PRD、CMPA、CMPB 和 CMHR 值时、它们对于前200ns 周期和第三周期值(200ns)是相同的值(屏幕截图1和3)、但我们观察到了 +/-1 TBCLK。
我不知道该误差来自哪里。 并且这个误差只有当第一个周期值等于200ns、240ns 或其他周期的 CMP=PRD/2时才会出现。 但不适用于其他周期值(例如208ns、220ns 等)。
以下是照片和屏幕截图不同的值(PRD、CMPA 等)拍摄200ns 然后208ns 并返回到200ns 与动态值周期:
此代码以200ns (占空比设置为90ns)启动:
 
     1.   
je modifie la valeur de periode pour 208 ns (占空比: 104 ns) :
     2.   
我再次设置一个200ns 的周期(占空比: 100ns):
   3.  

下面是我的代码,如果它有帮助:

#include "F28x_Project.h"
#include "F2837xD_DEVICE.h"
#include "F2837xD_examples.h"
#include "F2837xD_ePWM_definites.h"                      //初始化定义
#include "SFO_v8.h"
#include "board.h"
#包含

       //---------------- 设置周期和数据库------------------------------------------------------- //
float PeriodeNANOsec = 200 ;                            /国家海洋环境中的边界
浮点占空比= 0.5;
float dutyDB = 0;                                   //DN (ns)= dutyDB * period/2

           //----------------  DEFINITION --------------  //
#define LAST_EPWM_INDEX    4

           //---------------- VARIABLE ---------------- //
uint16_t PRD1_HR;
uint16_t FED;
uint16_t FEDHR;
uint16_t PRD;
uint16_t CMPB;
uint16_t CMPA;
uint16_t CMHR;


           //----------------  GLOBAL ------------------------  //
int MEP_ScaleFactor;
易失性结构 ePWM_regs *ePWM[]={0、&EPwm1Regs、&EPwm2Regs、&EPwm3Regs};
uint16_t 状态;
浮点 DBns;
           //--appel de fonction--//
void PRD_CMP_DB_calculation (float32_t periode、float32_t Duty、float32_t dutyDB);   //计算 PRD、CMP 和 DB 值(高分辨率)
void initGPIO (void);                                                               //gpio 初始化
void initPWM (void);                                                                //pwm 初始化


           //***** 代码主体***** //
int main()
{
   PRD_CMP_DB_calculation (PeriodeNANOsec、dutycycle、dutyDB);
   //初始化控制和模拟子系统的系统控制
   //启用外设时钟
   EALLOW;
   InitSysCtrl();
   EDIS;

   //通过所有 PWM 实现 EPWM1A 和 EPWM1B
   initGPIO();
   Dint;

   InitPieCtrl();

   //禁用 CPU 中断并清除所有 CPU 中断标志:
   EALLOW;
   IER = 0x0000;
   IFR = 0x0000;

   InitPieVectTable();

   //启用全局中断和更高优先级的实时调试事件:
   EINT;  //启用全局中断 INTM
   ERTM;  //启用全局实时中断 DBGM

   //调用 SFO()用校准的 MEP_ScaleFactor 更新 HRMSTEP 寄存器。
   //在启用之前必须使用比例因子值填充 HRMSTEP
   //高分辨率周期控制。
   while (status == SFO_Incomplete)
   {
       Status = SFO();                                        // SFO 函数返回2 (如果发生错误)以及 MEP 的数量
       if (STATUS == SFO_ERROR)                                //步进/粗步进超过最大值255。
       {
           ESTOP0;
       }
   }

   SYSCTL_disablePeripheral (SYSCTL_Periph_CLK_TBCLKSYNC);

   initPWM();

   SYSCTL_enablePeripheral (SYSCTL_Periph_CLK_TBCLKSYNC);
   uint32_t i;

   while (1)
   {
       浮点                                         周期;//周期的新值
       printf ("期间的新值(单位 ns):");
       scanf ("%f"、&periode);
       printf("\n");

       PRD_CMP_DB_calculation (periode、dutycycle、dutyDB);

       for (I=1;I<last_epwm_index;I++)
       {
           (* ePWM[i]).TBPRD= PRD;
           (* ePWM[i]).CMPA.all =(long) CMPA << 16 | CMPHR<< 8;        //启用 HRPWM 占空比
           (* ePWM[i]).CMPB.all =(long) CMPB << 16 | CMHR << 8;
           (* ePWM[i]).DBRED.all = feed;                                //解压组件
           (* ePWM[i]).DBFED.all = FED;
           (* ePWM[i]).DBREDHR.bit.DBREDHR = FEDHR;                    //解压两个 PW1Ms 的上升
           (* ePWM[i]).DBFEDHR.bit.DBFEDHR = FEDHR;
           (* ePWM[i]).TBPRDHR= PRD1_HR<<8;
       }
       Status = SFO ();//在后台,MEP 校准模块
       //持续更新 MEP_ScaleFactor
       if (status == SFO_error)
       {
           ESTOP0;  // SFO 函数在发生错误时返回2,以及
       }             // MEP 步长/粗步长超过最大值255。

   }


        //---------------- 初始化 HRPWM -------------------------------------------------------    //
void initPWM()
{
   uint16_t j;

   EALLOW;
   CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;                          //禁用 ePWM 内的 TBCLK
   EDIS;

   对于(j=1;j<last_epwm_index;j++)
   {
       //----------------    时基/ CMP ------------------  //
       (* ePWM[j]).TBCTL.bit.PRDLD = TB_shadow;                    //设置影子加载
       (* ePWM[j]).TBPRD= PRD;                                     // PWM 频率= 1/(2*TBPRD)

       (* ePWM[j]).CMPA.all =(长) CMPA << 16 | CMPHR<< 8;        //启用 HRPWM 占空比
       (* ePWM[j]).CMPB.all =(长) CMPB << 16 | CMHR << 8;

       (* ePWM[j]).TBPHS.all = 0;
       (* ePWM[j]).TBCTR = 0;

       (* ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;                //选择向上向下计数模式
       (*ePWM[j]).TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
       (* ePWM[j]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
       (* ePWM[j]).TBCTL.bit.CLKDIV = TB_DIV1;                     // TBCLK = SYSCLKOUT
       (* ePWM[j]).TBCTL.bit.FREE_SOFT = 3;

       //----------------    SHADOWS -------------------------  //
       (* ePWM[j]).CMPCTL.bit.LOADAMODE = CC_CTR_PRD;              //在 CTR = PRD 上加载 CMPA
       (* ePWM[j]).CMPCTL.bit.LOADBMODE = CC_CTR_PRD;
       (* ePWM[j]).CMPCTL.bit.SHDWAMODE = CC_shadow;
       (* ePWM[j]).CMPCTL.bit.SHDLBMODE = CC_HOLD;

       //----------------    动作限定符------------------------------------------------------- //

       (* ePWM[j]).AQCTLA.bit.CAU = AQ_SET;                      // PWM 切换为高电平/低电平
       (* ePWM[j]).AQCTLA.bit.cbd = AQ_CLEAR;                        //不设置为 ZRO、HR 周期不稳定
       (* ePWM[j]).AQCTLB.bit.CAU = AQ_CLEAR;                      // PWM 切换高电平/低电平
       (* ePWM[j]).AQCTLB.bit.bd = AQ_SET;                        //不设置为 ZRO、HR 周期不稳定

       //----------------    HRPWM --------------------------  //
       EALLOW;
       (* ePWM[j]).HRCNFG.all = 0x0;

       (* ePWM[j]).HRCNFG.bit.EDGMODE = HR_BEP;                    // HR 周期的 BOht Edge to Work
       (* ePWM[j]).HRCNFG.bit.CTLMODE = HR_CMP;                    // CMPAHR 和 TBPRDHR HR 控制。
       (* ePWM[j]).HRCNFG.bit.HRLOAD = HR_CTR_Zero_PRD;            //在 CTR = 0 且 CTR = TBPRD 时加载

       (* ePWM[j]).HRCNFG.bit.EDGMODEB = HR_BEP;                   // HR 周期的 BOht 边沿开始工作
       (* ePWM[j]).HRCNFG.bit.CTLMODEB = HR_CMP;                   // CMPBHR 和 TBPRDHR HR  控制
       (* ePWM[j]).HRCNFG.bit.HRLOADB = HR_CTR_Zero_PRD;           //在 CTR = 0 且 CTR = TBPRD 上加载
       (* ePWM[j]).HRCNFG.bit.SWAPAB = 0;                          // ePWMxA 和 ePWMxB 输出不变

       (* ePWM[j]).HRCNFG.bit.AUTOCONV = 1;                        //启用 HR 周期的自动转换
       (* ePWM[j]).HRPCTL.bit.TBPHSHRLOADE = 0;                    //启用 TBPHSHR 同步 (对于更新计数 HR 控制是必需的)
       (* ePWM[j]).HRPCTL.bit.HRPE = 1;                            //开启高分辨率周期控制。

       CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;                      //在 ePWM 中启用 TBCLK
       (* ePWM[j]).TBCTL.bit.SWFSYNC = 1;                          //将高分辨率相位同步到起始 HR 周期

       //----------------    死区-------------------------------------------------------  //
       (* ePWM[j]).DBCTL.bit.IN_MODE = DBA_ALL;                    //ICI EPWMxA est la source des retards de front-子孙 和 Front monant。
       (* ePWM[j]).DBCTL.bit.out_mode=DB_FULL_ENABLE;            //见表15-8
       (* ePWM[j]).DBCTL.bit.POLSEL=DB_ACTV_HIC;                  //高电平有效互补-> Tableau 15-8
       (* ePWM[j]).DBCTL.bit.HALFCYCLE = 1;                         //该位必须设置为 HR 死区(DB 为时钟5ns)
       (* ePWM[j]).DBCTL.bit.OUTSWAP = 0;
       (* ePWM[j]).DBCTL.bit.SHDWDBREDMODE = 1;
       (* ePWM[j]).DBCTL.bit.SHDWDBFEDMODE = 1;
       (* ePWM[j]).DBCTL.bit.LOADREDMODE = 2;
       (* ePWM[j]).DBCTL.bit.LOADFEDMODE = 2;
       (* ePWM[j]).DBRED.all = feed;                                //解封组件
       (* ePWM[j]).DBFED.all = FED;
       (* ePWM[j]).HRCNFG2.bit.EDGMODEDB= HR_BEP;                  // DBREDHR 和 DBFEDHR
       (* ePWM[j]).HRCNFG2.bit.CTLMODEDBFED =2;                    //在 ZRO 上加载
       (* ePWM[j]).HRCNFG2.bit.CTLMODEDBRED =2;
       (* ePWM[j]).DBREDHR.bit.DBREDHR = FEDHR;                    //解压两个 PW1Ms 的上升
       (* ePWM[j]).DBFEDHR.bit.DBFEDHR = FEDHR;                    //解压两个 PW1Ms 的下降值

       (* ePWM[j]).TBPRDHR= PRD1_HR<<8;

       EDIS;


   }



       //---------------- 初始化 GPIO -------------------------------------------------------      //
void initGPIO()
{
   EALLOW;                                                //启用对 GPIO 配置寄存器的访问
   //为 PWM1A 配置 GPIO 0
   GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;                     //激活引脚上的上拉电阻
   GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;                    //针对 PWM1A 功能配置引脚
   //为 PWM1B 配置 GPIO 1
   GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;                     //激活引脚上的上拉电阻
   GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;                    //针对 PWM1B 功能配置引脚
   EDIS;                                                  //禁止访问 GPIO 配置寄存器



void PRD_CMP_DB_calculation (float32_t 周期、float32_t DUTY、float32_t dutyDB)
{
       //------- 期间和 PRDHR 计算 ----------------------------------------------------- //
  float invTBCLK= 0.10;                                   //1/TBCLK = 0.1纳秒、TBCLK=10ns 时的时钟冲数
  float PRDfrac= 0;
        PRDfrac = periode*invTBCLK*0.5;                         //页的 TBCLK 数量
        PRD=(PRDfrac);                                   //分割周期的整数部分
        PRD1_HR=((PRDfrac-PRD))*256;

      //------- CMP 和 CMHR 计算 ------- //
  float fracPRD = 0;
        fracPRD = period*invTBCLK;
  浮点恢复= 0;
        Reste = fracPRD * 0.5;                                      //Euclidean 除法、了解如何计算50%占空比下的 CMP
  如果(reste ==(int) reste)                                         //如果 periode /(2.TBCLK) 是整数 (例如:180ns / 20ns = 9 CLK =PRD)
  {
      浮点电阻2 = 0;
            实验2 = PRD *0.5;
      if (reste2 ==(int) reste2 )                                   // if 如果 PRD/2是整数(ex: 200ns : PRD=10 CLK and PRD/2=5)             
      {
          CMPA=PRD/2;
          CMPB = PRD/2;
      }
      else                                                         //如果 PRD/2不是整数(例如180ns -> PRD= 9 CLK 且 PRD/2= 4.5)
      {
          浮点 CMPfrac = PRD/2;
          CMPA =(CMPfrac);
          CMPB = CMPA + 1;
      }
  }
  else                                                           //如果 periode/2.TBCLK 不是整数(例如190ns/20ns = 9.5 CLK =PRD)
  {
      浮点 CMPfrac = PRD/2;
      int  CMPent =(CMPfrac);
      CMPA = CMPent - 1;
      CMPB = CMPent + 1;
  }
  浮点 FRAC = 0;
        FRAC = PRDfrac*占空比;                              //计算 CMHR = FRAC (PRDfrc*占空比)
  INT ent = 0;
      Ent =(FRAC);
  浮点 CMPHRfrac = 0;
        CMPHRfrac =分数元;
        CMPHRfrac = CMPHRfrac*256;
  CMPHR=(CMPHRfrac);

      //------- 死区和 DBHR 计算-------  //
  float RequiredDBvalue= 0;
        RequiredDBvalue = Duty*period*dutyDB;
  float fracFED= 0;
        fracFED = RequiredDBvalue*0.2;//*0.2                      相当于除以10ns/2或半个时钟周期
  fed=(fracFED);
  float fracFEDH= 0;
        fracFEDH=(fracFED-feed)*128;//DBFED                     在7位上,因此对于 cacul 我们实现了(fractionalpart*128)
  FEDH=(fracFEDHR);
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Florentin:

    为了澄清一下、您是否在 HRPWM 输出上看到了+/- 1 TBCLK 抖动? 我不明白这里使用的"小型"术语。  这里可能有一些不兼容的 HRPWM 设置、这可能导致 HRPWM 输出异常。  我明天会更好地了解一下代码、但我首先注意到的是您的加载方案。 如果使用 TBPRDHR 控制、请确保 CMPx 和 CMPxHR 影子加载模式 设置为在 "零和 PRD"时加载。 此外、当您发现问题发生时、通常会设置哪些特定 TBPRD、CMPA 和 CMPB 值?

    此致、

    Allison Nguyen

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Alison:
     当我用特定的周期值运行程序时、我观察到一个+/- 1 TBCLK。  如果 TBCLK 的数量可以被4整除、那么下面是一个200ns 的示例:需要20个 TBCLK 才能完成这个周期、因此 TBPRD = 10、CMPx = 5。 在这里 TBPRDHR = 0并且 CMPxHR = 0 (使用240ns、160ns 等)。  这是一个+/- 1 TBCLK 误差产生的地方。 对于"decaglec"这个词、它是一个错误、我意味着一个偏移。
    但当我动态地更改周期值(改为 208ns)、然后重置初始值(改为200ns)时、此+/- 1 TBCLK 错误会消失 。
    我刚刚将加载模式更改为"zero and PRD"、该错误在程序启动时仍然存在。
     
    感谢你的帮助。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Florentin:  

    感谢您提供有用的信息。 实际上、CMPxHR = 0值不受支持;当 CMPxHR 值 设置为0时、这可能会导致您看到的1 TBCLK 跃进信号。  

    请注意、使用 SysConfig GUI 进行开发在此处也会有所帮助、因为存在警告和错误、可捕捉一些不兼容的设置、例如、如果您计划在将来使用该设置、则可以在本例中捕获这些设置。

    此致、

    艾里森

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Allison:
    我的确已经将 CMPHR 的计算更改为 CMPHR+1以避免 CMPHR = 0的情况、但我在程序启动期间仍观察到+/-1TBCLK。
    感谢提示、我来看看 SysConfig。

    此致。

    佛罗伦萨

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Florentin:

    您能否尝试 注释掉或删除/禁用所有 HRPWM 设置并运行程序? 如果您可以尝试一下-我们可以看看+/- 1 TBCLK 问题是否仅存在于 HRPWM 配置中、这可以帮助我们极大地缩小问题范围。

    如果您最终查看或使用了 SysConfig、或者对 ePWM 模块有任何疑问/反馈、请告诉我!

    此致、

    艾里森

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢提示,我删除/注释出 HRPWM 寄存器以查看差异和+/-1TBCLK 值为200ns, 240ns .. 而且工作正常。 我具有50%的占空比。 那么、我放回到 HRPWM 寄存器、但 HRPE 位除外。  以下是我观察到的情况:
    如果 HRPE = 0、则不存在+/-1TBCLK 不需要的问题、对于完整的 CMP 和 TBPRD 周期、I 具有50%的占空比。
    如果 HRPE = 1、我观察到两种情况:
    1. 我随机选择第一个周期(如206ns),一切正常。 我具有50%的占空比。 然后、我选择一个"整数"周期、如200ns (或240ns)、我观察到一切正常工作(50%占空比)。
    2. 所选的第一个周期为200ns (或240ns),我得到+/-1 TBCLK。 然后、我更改为一个随机值(210ns)、它可以正常工作。  如果我改回200ns、我会注意到+/-1 TBCLK 不再存在、并且占空比正好为50%。
     
    对于 SysConfig、我将看一下、并告诉您它是否有助于解决问题。
     
    此致、  
     
    佛罗伦萨  
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Florentin:

    这肯定会对导致该问题的某些特定设置有很大帮助。 您需要回答几个问题:

    • 是否在设置时写入相同的 CMPAHR 和 CMPBHR 值?  
    • 您是否可以尝试使用设置为与 CMPAHR 和 CMPBHR 相同的值的 TBPRDHR?
    • 我能不能问您为什么要使用 CMPA 和 CMPB 作为行动限定符? 您是否能够尝试仅使用 CMPA-UP 和 CMPA-DOWN 以在 PRD 附近居中?
    • 您可以检查以确保 TBPRDHR 被初始化为0以外的任何值吗?

    请告诉我您是否能够回答这些问题、或者在这样做的过程中了解问题的解决方案。 您是否进行了更改以尝试 SysConfig (如果不担心、请不要担心)?

    此致、

    艾里森

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Allison:

    再次感谢您的帮助。 是的、CMPAHR 和 CMPBHR 的值相同、我修改了代码、使 CMPA = CMPB。 因此我将 AQ 设置为 CMPAUP 和 CMPAdown。 但我必须 设置 CMPB、否则在死区激活时 EPwm1B 信号不稳定。
    关于 SysConfig、我尝试在我的代码中使用它、我有几条错误和编译消息。 我稍后将进行讨论。
    对于 TBPRDHR、我在完成编辑 TBPRDHR = 0并且添加了+ 1 。 这解决了我的问题。 所有的周期和占空比值均符合预期。


    非常感谢您的耐心和帮助。

    佛罗伦萨

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Florentin:

    很高兴您能够解决此 问题!

    如果您不使用 SysConfig、则无需担心、但如果 您将来使用此功能、请随时向我发送反馈 (或一般针对 ePWM 模块/HRPWM 的可用性提供反馈)、因为我们一直在寻找 更容易实现的方法。 感谢您的耐心和愿意通过我的评论工作.

    此致、

    艾里森