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.

[参考译文] CCS/TMS320F28377S:ePWM 干扰

Guru**** 2482225 points
Other Parts Discussed in Thread: TMS320F28377S, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/777321/ccs-tms320f28377s-epwm-glitch

器件型号:TMS320F28377S
主题中讨论的其他器件: C2000WARE

工具/软件:Code Composer Studio

您好!

我有一个与 DSP TMS320F28377S 的 ePWM 输出相关的问题。

在我的代码中、EPWM7输出根据感应信号和一个中断中占空比的实时计算进行更新。 如下图所示、PWM 输出有时在一个开关周期内全部在 A 中为高电平、在 B 中全部为低电平、看起来像是毛刺脉冲或错误。 我在 PWM 生成中使用了互补模式。 此类干扰以非常低的频率发生(有时捕获一个干扰需要10秒)。 感应到的外部信号和实时计算都应该正确。 由于我的采样频率为50kHz、开关频率平均为300kHz、如果计算和感应信号出现问题、PWM 干扰将持续几个开关周期、而不是仅一个周期、并在如此低的频率下发生。 因此、它在更新占空比时看起来更像是 PWM 干扰。

我想知道、什么会导致像这样的 ePWM 模块干扰或错误? 如何避免这种现象?

 

顺便说一下、PWM 的初始化函数如下所示。 ePWM_TIMER_TBPRD、ePWM_CMPA、ePWM_CMPB、ePWM_TIMER_PHASE、RED 和 FED 的值根据一个 ADC 中断中的计算结果进行更新。

//代码//////////////////////////
空 InitEPwm7()

//设置 TBCLK
EPwm7Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;//向上计数
EPwm7Regs.TBPRD = ePWM_TIMER_TBPRD;//设置定时器周期
EPwm7Regs.TBCTL.bit.PHSEN = TB_ENABLE;//启用相位加载
EPwm7Regs.TBPHS.bit.TBPHS =0x0000;//相位为0
EPwm7Regs.TBCTL.bit.PRDLD = TB_SHADOW;//
EPwm7Regs.TBCTL2.bit.SYNCOSELx=1;//同步输出的扩展选择、EPWMxSYNCO = CMPC
EPwm7Regs.TBCTL.bit.SYNCOSEL = 3;//0:同步输出选择为 SYNC 信号;1:当 TB 计数器= 0时;3:扩展、

EPwm7Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;//时钟与 SYSCLKOUT 的比率
EPwm7Regs.TBCTL.bit.CLKDIV = TB_DIV1;
//
//将影子寄存器加载设置为零
EPwm7Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm7Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm7Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm7Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm7Regs.CMPCTL2.bit.SHDWCMODE = CC_SHADOW;
EPwm7Regs.CMPCTL2.bit.LOADCMODE = CC_CTR_ZERO;
//
//设置比较值
EPwm7Regs.CMPA.bit.CMPA = ePWM_CMPA;//设置比较值
EPwm7Regs.CMPB.bit.CMPB = ePWM_CMPB;//设置比较 B 值
EPwm7Regs.CMPC = ePWM_TIMER_PHASE;// 0.5 TS
//
//设置 outputA 上的操作,EPWM7A 是 SR 开关的原始 PWM
EPwm7Regs.AQCTLA.bit.CAU = AQ_SET;//在事件 A 上设置 PWM1A、递增计数
EPwm7Regs.AQCTLA.bit.CBU = AQ_CLEAR;//在事件 B 上清除 PWM1A、递增计数
//
//设置死区发生器
EPwm7Regs.DBCTL.bit.IN_MODE = DBA_ALL;//EPWMA 是下降沿和上升沿的源
EPwm7Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;//启用死区模块、波特图和红色有效
EPwm7Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;//高电平有效互补
EPwm7Regs.DBRED.bit.DBRED =红色;//在打开 SR 开关之前设置死区时间
EPwm7Regs.DBFED.bit.DBFED= FED;//在打开交流开关之前设置死区时间、TR

//通过跳闸1的 Vo 过压时关闭栅极信号
EALLOW;
EPwm7Regs.TZSEL.bit.OSHT1 = 1;//启用 T1作为触发信号
EPwm7Regs.TZCTL.bit.TZA = 2;//强制 EPWM7A 为低电平
EPwm7Regs.TZCTL.bit.TSB = 2;//强制 EPWM7B 为低电平
EDIS;

//在过流通过跳闸2时关闭栅极信号
EALLOW;
EPwm7Regs.TZSEL.bit.OSHT2 = 1;//启用 T2作为触发信号
EPwm7Regs.TZCTL.bit.TZA = 2;//强制 EPWM7A 为低电平
EPwm7Regs.TZCTL.bit.TSB = 2;//强制 EPWM7B 为低电平
EDIS;

//过流通过跳闸3时关闭栅极信号
EALLOW;
EPwm7Regs.TZSEL.bit.OSHT3 = 1;//启用 T3作为触发信号
EPwm7Regs.TZCTL.bit.TZA = 2;//强制 EPWM7A 为低电平
EPwm7Regs.TZCTL.bit.TSB = 2;//强制 EPWM7B 为低电平
EDIS;

如果您能给我任何提示或建议、我将不胜感激。 这个问题对于我的整个实验来说非常重要。

期待您的回复。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我认为问题不在您的初始化代码中。 您似乎正在更新控制 ISR 中的多个参数。 其中一个是 PWM 阶段、这意味着您同时更新多个 PWM? 在任何情况下、在更新同一模块中的周期和比较值时都会出现问题;例如、如果写入的新 TB 周期低于当前 TBCTR、计数器将会错过阈值并继续递增计数。 这种情况可能正在发生。

    此器件上的 PWM 模块配有"一次性"重新加载功能、允许您在同一时钟周期内更新所有新参数。 在本器件的当前版本用户指南中、图 14-12和第14.4.7.2节。 我在您的代码中看不到 GLDCTL 寄存器的配置、因此您可能没有使用此功能。 请查看 UG 文档中的说明、以查看它是否适用于您的情况。

    您是否还能澄清"范围捕获:"TCTR 被外部信号复位"中的红色文本? 谢谢。

    此致、

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

    您能为我调试吗? 我想知道、当信号在 PWM 周期中一直处于低电平或高电平时、CMPA、CMPB 中的值是多少。

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

    您好!  

    非常感谢您的回复。 外部信号是来自硬件电路的零电流检测信号。 我通过 GPIO 发送该信号并链接到 EPWM7SYNCIN 以重置基于时间的计数器。 每当复位信号处于活动状态时、将加载第0相、计数器将从零开始计数。 如下图所示、外部复位信号在 PWM 干扰发生之前处于活动状态。 因此、基于时间的计数器在某种程度上没有使用 EPWM7SYNCIN 信号复位。

     正如您提到的、如果写入的新 TB 周期低于当前 TBCTR、计数器将会错过阈值并继续递增计数、这可能是一个原因、我稍后将对此进行检查。 此外、尽管我在主相位和从相位(2个 PWM 模块)之间使用了同步功能、但在调试此问题时未设置从相位 PWM。

    我必须在闪存模式下运行代码并运行转换器。 因此、我无法直接显示 CMPA 和 CMPB 中的值。 我将尝试识别它。 但我确实限制了 EPMW_CMPA 和 EPWM_CMPB 的值、确保在加载到 ePWM 模块时不会溢出。 下面是 ADC 中断中计算的部分代码。

    ADC 中断中的//实时计算代码

    A=1/wr;
    //tdelay = 100e-9;
    如果(v_comp < 0.64)

    tdelay = 1e-9*(12.346*v_comp*v_comp-46.173*v_comp+124.49);

    其他

    tdelay = 1e-9*(-250*v_comp*v_comp+285*v_comp+20);

    co_delay = sqrt (1+tdelay_m2*wr*wr);
    Bound = co_delay/(k1+co_delay);
    if (绑定< 0.52)

    Bound = 0.52;

    if (界限> 0.56)

    Bound = 0.55;

    B=Vout/Vin_Abs;
    C=1/(b-1);//= Vin/(Vo-Vin)

    IF (Vin_Abs {
    k=(b-1)*sqrt (1+tdelay*tdelay*wr*wr);//
    TR1 = 150e-9;

    其他     //模式2

    K=K1;
    TR1 = 80e-9;

    D=1/k;

    ton_ac = ton_c+k*a;
    ten_SR = a*sqrt (k*k*c*c-1)-tdelay;
    TON_SR = TON_AC*c+ten_SR+tdelay;
    tr2=a*(pi-acos (b-1)*d)-acos (d)+10e-9;
    tzvs = a*sqrt (k*k-1);

    tsw=ton_ac+TR1+ton_SR+TR2+tzvs+200e-9;
    //}

    如果(Vout>Vo_TH2)//在 Vout 完全大于 Vin 时启用 ZCD 外部复位信号

    EALLOW;
    EPwm7Regs.TBCTL.bit.PHSEN = 1;//TB_ENABLE;
    EDIS;

    //更新 ePWM 的比较值

    ePWM_CMPA = ten_SR*2e8;
    ePWM_CMPB =(ten_SR+TR2+tzvs+ton_ac)*2e8;
    红色= TR2*2e8;
    FED = TR1*2e8;
    ePWM_TIMER_TBPRD = TSW*2e8;
    ePWM_TIMER_PHASE = TSW*1e8;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    请继续并监视受控变量、尤其是 CMPA、CMPB、TBPRD 和 PHASE。 也许您可以设置数据记录器、将值记录到滚动缓冲区中、然后在问题发生时将其冻结。

    BTW、您是否在实际写入寄存器之前将这些转换为定点?

    ePWM_CMPA = ten_SR*2e8;
    ePWM_CMPB =(ten_SR+TR2+tzvs+ton_ac)*2e8;
    红色= TR2*2e8;
    FED = TR1*2e8;
    ePWM_TIMER_TBPRD = TSW*2e8;
    ePWM_TIMER_PHASE = TSW*1e8;

    此致、

    Richard
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    非常感谢! 是的、我正在尝试监控变量。 BTW、我不清楚如何在闪存模式下设置数据记录器。 您能为我提供有关此内容的任何链接或参考吗?
    此外、我将时间变量 tsen_SR、TR2等定义为浮点数据、并将 ePWM_CMPA、ePWM_CMPB 等定义为 UINT16数据。 然后、我直接将 UINT16数据发送到 ePWM 寄存器。 在此过程中、我是否需要进行任何转换?

    非常感谢。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    TI 站点上有多种数据记录解决方案。 我更喜欢记录浮点数据的方法是使用数字控制库、它是 C2000Ware 的一部分。 在默认位置下载并安装后、请在以下位置查找库:
    C:\ti\c2000\C2000Ware_1_00_06_00\libraries\control\DCL
    数据记录器位于头文件"DCL_fdlog.h"中。 这只是我的偏好。 您应该能够非常轻松地将其与代码集成并从闪存运行。 如果遇到任何问题、请回帖。

    在写入寄存器时、需要仔细考虑数字类型:在 C28x 上、'float'是一个32位单精度数、而 UINT16是一个无符号16位定点。 编译器将为您处理转换、但您仍应检查"float"的值、以确保它实际上可以用16位表示。 这是数据记录器出现的地方、我怀疑这可能是问题所在。

    此致、

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

    非常感谢您的帮助。 我刚刚找到了问题的原因。
    在我的设置中、我在 TBCTR = 0上加载这些比较值。 当发生毛刺脉冲时、CMPA 的值太小(实际上是零)、因此无法正常生成 PWM。 在 I LIMIT CMPA >=2后、它运行良好、不再出现毛刺脉冲。

    再次感谢、我从这个中学到了很多东西。

    最棒的
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很棒! 很高兴知道您解决了问题、感谢您告知我们。

    此致、

    Richard