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:当高解析周期寄存器(TBPRDHR)的值为非零时、死区不稳定。

Guru**** 2576215 points
Other Parts Discussed in Thread: TMS320F28379D, C2000WARE, SYSCONFIG

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1301047/tms320f28379d-dead-band-unstable-when-the-value-of-the-high-resoltion-period-register-tbprdhr-is-non-zero

器件型号:TMS320F28379D
主题中讨论的其他器件: C2000WARESysConfig

大家好、我不熟悉微控制器编程。 我使用: TMS320F28379D. CCS 上执行代码。 我希望 在 F2837xD 上以向上计数模式在有效复杂模式下以50%占空比生成 PWM 信号(高分辨率)、并生成死区。

当死区被停用(HRPE 打开)时、PWM 信号在50%占空比下正常工作。 但当死区打开时、PWM 信号不稳定。
死区有两种情况:
 - 首先,当高分辨率周期被激活且 TBPRDHR=0 <<8 信号是稳定的、死区在工作。 示例:period=210ns、所以 TBPRD=20、TBPRDHR=0和 105ns 的占空比。
  第二,当高分辨率周期被激活且 TBPRDHR 非零时,信号不稳定。 示例:周期206ns、所以 TBPRD = 19、TBPRDHR = 0.6<<8、占空比= 103ns。


我观察到了10ns 的变化(1 TBCLK)。 我还观察到 EPwm1B 信号稳定、但当触发器在 EPwm1B 通道上时、EPw1A 信号不稳定。 但 EPw1A 的通道上没有、两个通道都不稳定。
我不知道如何使信号稳定。
提前感谢您的帮助。

以下是信号和差异的照片(香奈儿1 : Epwm1B 和香奈儿2 : Epwm1A ),图片代表一个 PWM 信号206ns 周期,双周期50%和死区30%的死区时间的死区时间等(30.9ns):

连续信号采集:

单次采集 :

以下是我的完整代码、如果它有所帮助:

#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 = 206;                            //在 NANOSECONDE 边缘
浮点占空比= 0.5;
浮点 dutyDB = 0.30;                                   //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 CMP;
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);
   DBns = dutyDB * PeriodNANOsec/2;
   //初始化控制和模拟子系统的系统控制
   //启用外设时钟
   EALLOW;
   InitSysCtrl();
   EDIS;

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

   //将 PIE 控制寄存器初始化为默认状态。
   //默认状态是所有 PIE 中断都被禁用并且标志
   //被清除。
   InitPieCtrl();

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

   //使用指向 shell 中断的指针初始化 PIE 矢量表
   //服务例程(ISR)。
   //这将填充整个表,即使中断
   //在本例中未使用。  这对于调试十分有用。
   //在 F2837xD_DefaultIsr.c 中可找到 shell ISR 例程。
   //此函数可以在 F2837xD_PieVect.c 中找到。
   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)
   {


       for (I=1;I<last_epwm_index;I++)
       {
           (* 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 =(long) CMP << 16 | CMPHR<< 8;        //启用 HRPWM 占空比
       (* ePWM[j]).CMPB.all =(long) CMP << 16 | CMHR << 8;

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

       (* ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_UP;                //选择向上/向下计数模式
       (* ePWM[j]).TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
       (* 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_CLEAR;                      // PWM 切换高电平/低电平
       (* ePWM[j]).AQCTLA.bit.PRD = AQ_SET;                        //不设置为 ZRO、HR 周期不稳定
       //(* ePWM[j]).AQCTLB.bit.CBU = AQ_SET;                      // PWM 切换为高电平/低电平
       //(* ePWM[j]).AQCTLB.bit.PRD = AQ_CLEAR;

       //----------------    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 的下降值


       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=periode*invTBCLK;                         //排列 p 的 TBCLK 的数量
  int PRDint=(PRDfrac);                                   //分割周期的整数部分
      PRD=PRDint-1;
      PRD1_HR=(PRDfrac-PRDint)*256;

      //------- CMP 和 CMHR 计算 ------- //
  Int reste = PRD/2;                                      //Euclidean 除法、了解如何计算50%占空比下的 CMP
  if (reste!=0)                                          //如果 PRD 是奇数
  {
      CMP=PRDint/2 - 1;
  }
  else                                                    //如果 PRD 为偶数
  {
      CMP=PRD/2;
  }
  浮点 FRAC = PRDfrac*占空比;                              //计算 CMHR = FRAC (PRDfrc*占空比)
  int ent =(FRAC);
  浮点 CMPHRfrac =分数端;
  CMPHRfrac = CMPHRfrac*256;
  CMPHR=(CMPHRfrac);

      //------- 死区和 DBHR 计算-------  //
  float RequiredDBvalue=Duty*period*dutyDB;
  float fracFED=RequiredDBvalue*0.2;//*0.2                      相当于除以10ns/2或半个时钟周期
  fed=(fracFED);
  float fracfedHR=(facFED-feed)*128;//DBFED                     在7位上,因此对于 cacul 我们实现了(fractionalpart*128)
  FEDH=(fracFEDHR);

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

    尊敬的 Florentin:

    感谢您发送示波器截图和代码。 /-1 TBCLK 抖动通常是一些与 HRPWM 不兼容的设置的症状。 我现在看到的主要问题是计数模式与您尝试配置的模式不兼容。  如果您试图通过 MEP 来控制 EPWMA/B 的两个边沿、则必须使用向上向下双向计数模式。 上数模式不支持两个边沿的 MEP 边沿控制、这也是您当前配置的模式。 如果您处于向上计数模式、HR 模式也不支持死区模块。 因此、我建议切换到该程序的向上向下计数模式。

    要检查的其他注意事项:

    • 如果您更改为向上向下双向计数模式并执行两个边沿控制、那么在这种情况下、您需要按如下方式进行动作限定器设置:
      • CMPxUp =设置
      • CMPxDown =清除
      • TBCTR = PRD 或 TBCTR = ZRO 上无操作
    • 此外、如果要启用 HR 周期控制、请确保两个通道(A 和 B)都已启用、否则非 HR 输出将具有+/- 1 TBCLK 周期抖动。

    如果尚未引用软件示例、我建议您还查看我们在 {C2000Ware}\device_support\f2837xd\examples\CPU1\和 C:\ti\c2000Ware_5_01_00_00\driverlib\f2837xd\examples\CPU1\HRPWM 中提供的 HRPWM 示例。 在设置 HRPWM 配置时、请将这些内容用作指导。 请注意: 如果您有兴趣以这种方式进行开发,使用 CCS 中的 SysConfig GUI 还会捕获许多此类设置,并警告您不兼容问题。

    此致、

    艾里森

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

    感谢您的帮助和回答。

    我以向上/向下计数配置了信号、并且在修改了周期和占空比计算之后、当死区处于活动状态时(具有预期值)、该信号很稳定。


    再次感谢、
    此致、

    佛罗伦萨