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/TMS320F28035:在 PWM 递增/递减计数器模式中、设置 TBCTR = 0会导致 TBCTR >TBPRD 错误

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/831018/ccs-tms320f28035-in-pwm-up-down-counter-mode-set-tbctr-0-cause-an-error-that-is-tbctr-tbprd

器件型号:TMS320F28035

工具/软件:Code Composer Studio

大家好、

在 PWM 递增-递减计数器模式中、 我在使 TBCTR = 0大约几个时钟后设置一个断点、通过观察寄存器窗口、我可以获得以下信息

TBSTS 中的位[2]、 CTRMAX = 1、 表示时基计数器达到最大值0xFFFF

2. 在 TBSTS 中的位[0], CTRDIR = 0,这意味 着时基计数器当前正在递减计数

TBCTR ==65506

TBPRD ==30000

如果我在使 TBCTR = 0之前设置断点、然后逐步执行、TBCTR 似乎是一个正确的值、通过一步调试、它的值逐渐增加。μ s

我很困惑这是怎么发生的、是什么使 TBCTR 大于 TBPRD?

    请提供任何帮助

提前感谢

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

    嗨、Soldier 76、

    TBSTS 中的 CTRMAX 是说明中给出的锁存状态位。 这意味着、CTRMAX 一旦被置位、将保持不变、直到它被手动清零(通过向它写入1)。 由于 TBPRD 为30000、我相信您在写入 TBPRD 寄存器之前可能已经启用了 PWM、并且计数器在 TBPRD 更新时会传递 TBPRD 值。 这可能是 CTRMAX 为1的原因。 因此、这不应该是我要查看的设置、以弄清发生了什么情况。

     

    话虽如此、我相信您面临的问题是由您的代码中的 ISR 引起的。

    请检查您是否篡改了任何 ISR 中的 PWM 配置(尤其是 TBCTR/TBPRD/TBCTL 寄存器)。

    如果情况不是这样、请检查 CPU 是否获得了足够的带宽来使这个到 TBCTR 的写入发生?

     

    我之所以提出这一问题、是因为您提到它在步进调试模式中按预期工作。 CPU 不接受默认处于调试模式的中断。 我在通过和失败情形之间看到的唯一区别是、ISR 执行在工作情况中似乎没有发生。

     

    希望这对您有所帮助。 如果我的回复解决了您的困惑,请单击“验证答案”按钮。

     

    谢谢、此致

    Pramod

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

    感谢 Pramod P 的回复、

    我检查过几次、但仍然没有发现任何问题。 因此,我简化了代码,它只有 epwm1模块和 delay_US()函数,此外,我阻止了全局中断。

    我发现了一个明显的现象。 当 TBCTR 处于向上计数方向时、使 TBCTR = 0不会进入异常状态。 但是当 TBCTR 处于倒计数方向时、 使 TBCTR = 0将进入异常状态、即 TBCTR > TBPRD、我按照  以下屏幕截图设置断点,DELAY_US(600L)延迟、从而使 TBCRT 处于倒计数方向

    第一张图片、TCTR 在执行时正处于递增计数的方向   

    第二张图片、执行时 TBCTR 处于倒计数方向   

    这种异常是否有其他原因?

    void main (void)

    //仅在从闪存运行时使用
    //请注意,变量 FLASH 由编译器使用-d FLASH 定义
    ifdef 闪存
    //将时间关键代码和闪存设置代码复制到 RAM
    // RamfuncsLoadStart、RamfuncsLoadEnd 和 RamfuncsRunStart
    //符号由链接器创建。 请参阅链接器文件。
    memcpy (((uint16_t *)&RamfuncsRunStart、(uint16_t *)&RamfuncsLoadStart、
    (无符号长整型) RamfuncsLoadSize);

    //调用闪存初始化以设置闪存等待状态
    //此函数必须驻留在 RAM 中
    InitFlash();//调用闪存包装程序初始化函数
    #endif //(闪存)


    DEVICE_Init();

    //后台循环的定时同步
    // PeripheralHeaderIncludes.h 中的定时器周期定义
    // CpuTimer0Regs.PRD.All = mSec1;//任务
    // CpuTimer1Regs.PRD.All = mSec5;// B 任务
    // CpuTimer2Regs.PRD.All = mSec100;// C 任务
    //
    ////任务状态机初始化
    // Alpha_State_PTR =&A0;
    // a_Task_ptr =&a1;
    // B_Task_ptr =&b1;
    // C_Task_ptr =&c1;
    //
    // VTimer0[0]= 0;
    // VTimer1[0]= 0;
    // VTimer2[0]= 0;
    // LedBlinkCnt = 5;

    DELAY_US (9000L);


    // Pwm1_Logic_Init();
    pwm1_3_Init();
    // EXT_Int1_Init();
    // pwm2_Init();
    // sadc_Init();

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC=1;//同时启用 ePWM 时钟
    EDIS;

    //EINT;//启用全局中断 INTM
    //ERTM;
    DELAY_US (10L);

    //delay_US (600L);


    //below 正在重新注册一些 PAN 检测寄存器
    EPwm1Regs.TBCTR = 0x0000;//清除计数器

    DELAY_US (10L);
    while (1){;}

    ------------------------------------------------------------------

    void Pwm1_3_Init (void)

    /*********
    //pwm1和 pwm3配置为相同的频率周期。
    //除(EPwm1Regs.TBCTL.bit.PHSEN)不同
    //pwm3使用其 tz 中断来记录 pwm1 CTR 寄存器以计算驱动器延迟、并记录 PAN 检测脉冲的计数
    秘书长的报告 /

    //----------------------------------
    //pwm1.
    //------------------------------------
    wPWM1Freq = 1000;//初始频率
    wPWM1Period =(uint16)(60000000 / wPWM1Freq);


    EPwm1Regs.TBCTL.bit.PRDLD = TB_Immediate;//TB_SHADOW;//设置 CTR=0上的负载

    EPwm1Regs.TBPRD = wPWM1Period / 2;// PWM 频率= 1/周期
    EPwm1Regs.TBPHS.Half.TBPHS = 0x0000;//相位为0
    EPwm1Regs.TBCTR = 0x0000;//清除计数器

    //设置 TBCLK
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;//顺计时
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;//禁用相位加载
    // EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;//设置 CTR=0上的负载
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;//同步下流模块
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;//时钟与 SYSCLKOUT 之比
    EPwm1Regs.TBCTL.bit.CLKDIV = 0;//缓慢、以便我们可以在示波器上观察

    //EPwm1Regs.TBCTL.bit.free_soft = 11;// XYN、仿真模式位1X 自由运行

    //设置比较
    EPwm1Regs.CMPA.half.CMPA = wPWM1Period / 4;
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;// CTR 上的负载=零

    ////设置操作
    // EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;//设置
    // EPwm1Regs.AQCTLA.bit.PRD = AQ_CLEAR;//清除

    //设置操作
    EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR;
    EPwm1Regs.AQCTLA.bit.PRD = AQ_SET;

    //高电平有效互补 PWM -设置死区
    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FUL_ENABLE;
    EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
    EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm1Regs.DBRED = DB_2_5us;
    EPwm1Regs.DBFED = DB_2_5us;

    //config pwm1 ISR
    //ISR 用途:
    //1. 关闭 pwm1输出、这会导致检测到脉冲
    //2. 一段时间后,关闭 ISR,设置 PAN 检测结束标志 EOPD
    EALLOW;
    PieVectTable.EPWM1_INT =&EPWM1_INT_ISR;//映射 PWM 中断
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;// PIE 电平启用、Grp3 / Int1、ePWM1
    EDIS;

    EPwm1Regs.ETSEL.bit.INTSEL = 0;//et_CTR_PRD;//计数器归零事件时的 INT
    EPwm1Regs.ETSEL.bit.INTEN = 0;//禁用 INT
    EPwm1Regs.ETPS.bit.INTPRD = et_1st;//在每个第一个事件上生成 INT


    IER |= M_INT3;//启用连接到 EPWM1-6 INT 的 CPU INT3:


    // EINT;//启用全局中断 INTM
    // ERTM;//启用全局实时中断 DBGM

    //----------------------------------
    //COMP1 2.
    //------------------------------------
    //Comp1为上半电流限值
    //Comp2作为下半电流限值
    //如果输入电流没有过流,引脚 I/O 的输出应该为低电平
    EALLOW;
    //配置模拟比较器
    Comp1Regs.COMPCTL.bit.SYNCSEL = 1;//与 SYSCLK 同步/使用限定条件
    Comp1Regs.COMPCTL.bit.QUALSEL = 3;//需要输入针对3个连续 SYSCLK 保持稳定
    Comp1Regs.COMPCTL.bit.CMPINV = 0;//输出为低电平
    Comp1Regs.COMPCTL.bit.COMPSOURCE = 0;//使用内部 DAC
    Comp1Regs.COMPCTL.bit.COMPDACEN = 1;//启用 DAC
    Comp1Regs.DACVAL.bit.DACVAL = 821;//COMP1;//跳闸电流= DACVAL/1023*82.5


    Comp2Regs.COMPCTL.bit.SYNCSEL = 1;//与 SYSCLK 同步/使用限定条件
    Comp2Regs.COMPCTL.bit.QUALSEL = 3;//需要输入针对3个连续 SYSCLK 保持稳定
    Comp2Regs.COMPCTL.bit.CMPINV = 1;//输出为低电平
    Comp2Regs.COMPCTL.bit.COMPSOURCE = 0;//使用内部 DAC
    Comp2Regs.COMPCTL.bit.COMPDACEN = 1;//启用 DAC
    COMP2Regs.DACVAL.BIT.DACVAL = 202;//COMP2;//跳闸电流= DACVAL/1023*82.5


    //根据 TZ1和 TZ2定义事件(DCAEVT1)
    EPwm1Regs.DCTRIPSEL.bit.DCAHCOMPSEL = DC_COMP1OUT;// DCAH =比较器1输出
    //EPwm1Regs.DCTRIPSEL.bit.DCALCOMPSEL = DC_TZ2;// DCAL = TZ2
    EPwm1Regs.TZDCSEL.bit.DCAEVT1 = TZ_DCAH_HI;// DCAEVT1 = DCAH 低电平(当比较器输出变为低电平时将变为有效)
    EPwm1Regs.DCACTL.bit.EVT1SRCSEL = DC_EVT1;// DCAEVT1 = DCAEVT1 (未滤波)
    EPwm1Regs.DCACTL.bit.EVT1FRCSYNCSEL = DC_EVT_异 步;//采用异步路径

    //根据 TZ1和 TZ2定义事件(DCBEVT1)
    EPwm1Regs.DCTRIPSEL.bit.DCBHCOMPSEL = DC_COMP2OUT;// DCBH =比较器1输出
    //EPwm1Regs.DCTRIPSEL.bit.DCBLCOMPSEL = DC_TZ2;// DCAL = TZ2
    EPwm1Regs.TZDCSEL.bit.DCBEVT1 = TZ_DCBH_HI;// DCBEVT1 =(当比较器输出变为低电平时将变为有效)
    EPwm1Regs.DCBCTL.bit.EVT1SRCSEL = DC_EVT1;// DCBEVT1 = DCBEVT1 (未滤波)
    EPwm1Regs.DCBCTL.bit.EVT1FRCSYNCSEL = DC_EVT_异 步;//采用异步路径

    //启用 DCAEVT1和 DCBEVT1是一次性触发源
    //注意:DCxEVT1事件可定义为单次触发。
    // DCxEVT2事件可定义为逐周期。
    EPwm1Regs.TZSEL.bit.DCAEVT1 = 1;
    EPwm1Regs.TZSEL.bit.DCBEVT1 = 1;

    //我们希望 DCAEVT1和 DCBEVT1事件执行什么操作?
    // DCAEVTx 事件会强制 EPWMxA
    // DCBEVTx 事件会强制 EPWMxB
    EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;// EPWM1A 将变为高电平
    EPwm1Regs.TZCTL.bit.TSB = TZ_FORCE_LO;// EPWM1B 将变为低电平

    EDIS;


    //----------------------------------
    //comp3
    //------------------------------------
    EALLOW;
    //配置模拟比较器
    Comp3Regs.COMPCTL.bit.SYNCSEL = 1;//与 SYSCLK 同步/使用限定条件
    Comp3Regs.COMPCTL.bit.QUALSEL = 3;//需要输入针对3个连续 SYSCLK 保持稳定
    Comp3Regs.COMPCTL.bit.CMPINV = 0;//输出为低电平
    Comp3Regs.COMPCTL.bit.COMPSOURCE = 0;//使用内部 DAC
    Comp3Regs.COMPCTL.bit.COMPDACEN = 1;//启用 DAC
    Comp3Regs.DACVAL.bit.DACVAL = 496;//
    EDIS;


    // EINT;//启用全局中断 INTM
    // ERTM;

    ----------------------------------------------------


    //不要修改此行。
    #define DELAY_US (a) DSP28x_usDelay (((( long double) A * 1000.0L)/(long double) cpu_rate)- 9.0L)/ 5.0L

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

    嗨、Soldier 76、

    我将在最后尝试一次、以重现并调查此行为。  

    请在8月27日之前收到我的回复、因为我现在已与其他活动绑定在一起。

    同时、如果您可以将此项目作为附件发送、那将非常好。

    谢谢、此致

    Pramod

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

    您好、Pramod

    e2e.ti.com/.../HB358K.rarThank以获取帮助。 我将等待您的回答。

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

    嗨、Soldier 76、

    我有一段时间可以备用并创建一个测试用例、并且能够看到相同的行为。

    首先,我们不建议直接对 TBCTR 进行软件写入,这样会导致与您看到的结果不一致的结果。

    顺便提一下、这不仅是一种调试行为、而且在没有使用调试器的情况下也会发生。 只是您没有注意到它。 此外、该意外 TBCTR 的行为不限于计数器递减计数时。 当计数器递增计数时、如果您尝试通过软件强制 TBCTR 进入 TBPRD、则可能会发生这种情况。

    通过软件强制 TBCTR 为0或 TBPRD 将会导致缺少 CTR = 0和 CTR = PRDEQ 事件。

    在您的情况下、避免这种情况的一种方法是使 TBCTR = 1 (在您的情况下、而不是0)。

    如果此修复程序解决了您的问题,请单击“验证答案”按钮。

    谢谢、此致

    Pramod

     

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

    您好、Pramod

    非常感谢您的及时回复。

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

    您好,Pramod

    很高兴能帮我解决另一个问题?,这也是关于 PWM 的问题。

    链接如下

    谢谢、此致

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

    您好、Soldier76、

    我和同事会仔细研究、然后回复您。 我正在锁定此主题、因为已解决此问题。 我们可以在另一个线程上继续。

    谢谢、此致

    Pramod