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.

[参考译文] TMDSCNCD28P65X:ePWM 同步

Guru**** 2526700 points
Other Parts Discussed in Thread: TMDSCNCD28P65X

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1276834/tmdscncd28p65x-epwm-synchronisation

器件型号:TMDSCNCD28P65X

大家好!

我正在尝试为 TMDSCNCD28P65X 控制卡配置 ePWM 模块、但 ePWM 同步存在一些问题。 我已按如下方式调用了已配置的 ePWM 1和 ePWM 2:

EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;

EPwm1_Init ();
EPWM2_Init();
EPWM3_Init ();
EPwm5_Init ();
EPwm18_Init ();

EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;

但是、两个模块之间存在约20n 秒的相位延迟。 请注意、我已为 ePWM 1和 EMPW 2启用相位寄存器并将其设置为零。 为了规避此问题、我已将 EMDW 18配置为用作 ePWM 1和 EMPM 2的时钟源、在本例中、1&2均会同步。 我想了解为什么  TBCLKSYNC 不会 同步 ePWM 模块。  

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

    尊敬的 Manish:

    您可以禁用 ePWM1的相位寄存器吗? 如果 ePWM1是与其他 PWM 模块同步的主要模块。 另外、在调用 CpuSysRegs.PCLKCR0.bit.TBCLKSYNC 之前、您是否可以调用 GTBCLKSYNC 并将其设置为1? 这应该有助于同步这些模块。

    此致!

    马瑞安

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

    您好、Ryan、  

    感谢您的快速响应。 我已经尝试将  GTBCLKSYNC 设置 为1。 这确实会同步所有 PWM 模块。 不过、在这种情况下、相位寄存器值似乎没有影响、例如、如果我启用 PWM2的相位加载并在相位寄存器中分配一些值、则当 GTBCLKSYNC 设置为1时仍然没有相移

    此致、

    马尼什·库马尔

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

    尊敬的 Manish:

    是否为 PWM2启用了影子加载模式? 如果是、您能否在写入 TBPHS 寄存器时验证它是否在 CCS 寄存器窗口中得到更新。 当你在 TBCTR 上同步 PWM 模块= ZRO .. 等等? 为了将 TBPHS 加载到 TBCTR 值、您需要从 ePWM1生成到 ePWM2的某种软件同步。 此外、请确保 ePWM2 synchronin 是 ePWM1的 SyncOut。  

    此致!

    马瑞安

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

    您好、Ryan

    这是我尝试实现的代码、

    空 main (void)

    {
    //
    //系统控制初始化:

    InitSysCtrl();

    //
    //启用 PWM1、PWM2和 PWM3
    //
    CpuSysRegs.PCLKCR2.bit.EPWM1=1;
    CpuSysRegs.PCLKCR2.bit.EPWM2=1;
    //
    //初始化 ePWM1、ePWM2、ePWM4、ePWM5的 GPIO 引脚

    EPwm1_EPwm1_ Gpio_Config ();
    EPwm2_EPWQ( Gpio_Config );

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

    //
    // ePWM 模块的初始化
    //
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    CpuSysRegs.PCLKCR0.bit.GTBCLKSYNC = 0;
    EDIS;

    EPwm1_Init ();
    EPWM2_Init();

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.GTBCLKSYNC = 1;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;

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

    //
    //永久循环:
    //
    for (;;)
    {
    ASM (" NOP");
    EPwm2Regs.TBPHS.bit.TBPHS = val;


    void EPwm1_Init ()
    {
    //
    //设置 TBCLK
    //
    EPwm1Regs.EPWMSYNCOUTEN.bit.ZEROEN=1;
    EPwm1Regs.TBCTR = 0;//清除计数器
    EPwm1Regs.TBCTL.bit.CTRMODE = 2;//向上递减计数
    EPwm1Regs.TBPRD = 250;// 200kHz 的计时器周期
    EPwm1Regs.TBCTL.bit.PHSEN = 0;//禁用相位加载
    EPwm1Regs.TBPHS.bit.TBPHS = 0;//相位为0

    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;//时钟比率
    EPwm1Regs.TBCTL.bit.CLKDIV = 0;
    //
    //影子寄存器设置为在 CTR =零时加载
    //
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;// EPWM1A_SHADOD_MODE
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;// EPWM1B_SHADAND_MODE
    EPwm1Regs.CMPCTL.bit.LOADAMODE = 2;// EPWM1A_Load_CTR_ZERO
    EPwm1Regs.CMPCTL.bit.LOADBMODE = 2;// EPWM1B_Load_CTR_ZERO
    //
    //设置比较值
    //
    EPwm1Regs.CMPA.bit.CMPA = 125;//设置比较 A 值
    //
    //设置操作
    //
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;//将 PWM1A 设置为零
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;//清除事件 A 上的 PWM1A、
    //向上计数


    void EPwm2_Init()
    {
    //
    //设置 TBCLK
    //
    EPwm2Regs.TBCTR = 0;//清除计数器
    EPwm2Regs.EPWMSYNCINSEL.bit.SEL = 1;
    EPwm2Regs.TBCTL.bit.CTRMODE = 2;//向上递减计数
    EPwm2Regs.TBPRD = 250;// 200kHz 的计时器周期
    EPwm2Regs.TBCTL.bit.PHSEN = 1;//禁用相位加载
    EPwm2Regs.TBPHS.bit.TBPHS = 0;//相位为0
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0;//时钟比率
    EPwm2Regs.TBCTL.bit.CLKDIV = 0;
    //
    //影子寄存器设置为在 CTR =零时加载
    //
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = 0;// EPWM1A_SHADD_MODE
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = 0;// EPWM1B_SHADAND_MODE
    EPwm2Regs.CMPCTL.bit.LOADAMODE = 2;// EPWM1A_Load_CTR_ZERO
    EPwm2Regs.CMPCTL.bit.LOADBMODE = 2;// EPWM1B_Load_CTR_ZERO
    //
    //设置比较值
    //
    EPwm2Regs.CMPA.bit.CMPA = 125;//设置比较 A 值
    //
    //设置操作
    //
    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;//将 PWM1A 设置为零
    EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;//清除事件 A 上的 PWM1A、
    //向上计数

    因此 EPWM1同步输出是 EPWM2的同步输入、而 PWM 模块中存在固有延迟。 黄色的是 EPWM1A、洋红色是 EPWM2A。

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

    尊敬的 Manish:

    这是我的代码片段、我唯一更改的是 TBPHS 值为250、因此它会产生180度的相移。

    //
    // Included Files
    //
    #include "f28x_project.h"
    
    //
    // Globals
    //
    typedef struct
    {
        volatile struct EPWM_REGS *EPwmRegHandle;
        Uint16 EPwm_CMPA_Direction;
        Uint16 EPwm_CMPB_Direction;
        Uint16 EPwmTimerIntCount;
        Uint16 EPwmMaxCMPA;
        Uint16 EPwmMinCMPA;
        Uint16 EPwmMaxCMPB;
        Uint16 EPwmMinCMPB;
    }EPWM_INFO;
    
    EPWM_INFO epwm1_info;
    EPWM_INFO epwm2_info;
    EPWM_INFO epwm3_info;
    
    
    
    //
    // Main
    //
    void main(void)
    {
    //
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the f2838x_sysctrl.c file.
    //
        InitSysCtrl();
    
    //
    // Step 2. Initialize GPIO:
    // This example function is found in the f2838x_gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
    //    InitGpio();
    
    //
    // enable PWM1, PWM2 and PWM3
    //
        CpuSysRegs.PCLKCR2.bit.EPWM1=1;
        CpuSysRegs.PCLKCR2.bit.EPWM2=1;
        CpuSysRegs.PCLKCR2.bit.EPWM3=1;
    
    //
    // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
    // These functions are in the f2838x_epwm.c file
    //
        InitEPwm1Gpio();
        InitEPwm2Gpio();
        InitEPwm3Gpio();
    
    //
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
        DINT;
    
    //
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the f2838x_piectrl.c file.
    //
        InitPieCtrl();
    
    //
    // Disable CPU interrupts and clear all CPU interrupt flags:
    //
        IER = 0x0000;
        IFR = 0x0000;
    
    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in f2838x_defaultisr.c.
    // This function is found in f2838x_pievect.c.
    //
        InitPieVectTable();
    
    //
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    //
        EALLOW; // This is needed to write to EALLOW protected registers
    
        EDIS;   // This is needed to disable write to EALLOW protected registers
    
    //
    // For this example, only initialize the ePWM
    //
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        CpuSysRegs.PCLKCR0.bit.GTBCLKSYNC = 0;
        EDIS;
    
        EPwm1_Init();
        EPwm2_Init();
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.GTBCLKSYNC = 1;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    //
    // Step 4. User specific code, enable interrupts:
    //
    
    //
    // Enable CPU INT3 which is connected to EPWM1-3 INT:
    //
        IER |= M_INT3;
    
    //
    // Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
    //
        PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
        PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
        PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
    
    //
    // Enable global Interrupts and higher priority real-time debug events:
    //
        EINT;  // Enable Global interrupt INTM
        ERTM;  // Enable Global realtime interrupt DBGM
    
    //
    // Step 5. IDLE loop. Just sit and loop forever (optional):
    //
        //
        // Loop forever:
        //
        for(;;)
        {
            asm (" NOP");
            EPwm2Regs.TBPHS.bit.TBPHS = 250;
        }
    }
    void EPwm1_Init()
    {
    //
    // Setup TBCLK
    //
    EPwm1Regs.EPWMSYNCOUTEN.bit.ZEROEN=1;
    EPwm1Regs.TBCTR = 0; // Clear counter
    EPwm1Regs.TBCTL.bit.CTRMODE = 2; // Count up-down
    EPwm1Regs.TBPRD = 250; // Timer period for 200 kHz
    EPwm1Regs.TBCTL.bit.PHSEN = 0; // Disable phase loading
    EPwm1Regs.TBPHS.bit.TBPHS = 0; // Phase is 0
    
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // Clock ratio
    EPwm1Regs.TBCTL.bit.CLKDIV = 0;
    //
    //Shadow register is set to load on CTR=ZERO
    //
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0; // EPWM1A_SHADOW_MODE
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0; // EPWM1B_SHADOW_MODE
    EPwm1Regs.CMPCTL.bit.LOADAMODE = 2; // EPWM1A_Load_CTR_ZERO
    EPwm1Regs.CMPCTL.bit.LOADBMODE = 2; // EPWM1B_Load_CTR_ZERO
    //
    // Set Compare values
    //
    EPwm1Regs.CMPA.bit.CMPA = 125; // Set compare A value
    //
    // Set actions
    //
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on event A,
    // up count
    
    }
    
    
    void EPwm2_Init()
    {
    //
    // Setup TBCLK
    //
    EPwm2Regs.TBCTR = 0; // Clear counter
    EPwm2Regs.EPWMSYNCINSEL.bit.SEL = 1;
    EPwm2Regs.TBCTL.bit.CTRMODE = 2; // Count up-down
    EPwm2Regs.TBPRD = 250; // Timer period for 200 kHz
    EPwm2Regs.TBCTL.bit.PHSEN = 1; // Disable phase loading
    EPwm2Regs.TBPHS.bit.TBPHS = 0; // Phase is 0
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // Clock ratio
    EPwm2Regs.TBCTL.bit.CLKDIV = 0;
    //
    //Shadow register is set to load on CTR=ZERO
    //
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = 0; // EPWM1A_SHADOW_MODE
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = 0; // EPWM1B_SHADOW_MODE
    EPwm2Regs.CMPCTL.bit.LOADAMODE = 2; // EPWM1A_Load_CTR_ZERO
    EPwm2Regs.CMPCTL.bit.LOADBMODE = 2; // EPWM1B_Load_CTR_ZERO
    //
    // Set Compare values
    //
    EPwm2Regs.CMPA.bit.CMPA = 125; // Set compare A value
    //
    // Set actions
    //
    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero
    EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on event A,
    // up count
    
    }
    //
    // End of file
    //
    

    这是我在示波器上看到的结果:您能确认吗?

    这里还有 ePWM1和2配置的寄存器导出。 请与寄存器进行比较、看看是否有什么不同。

    e2e.ti.com/.../epwmregs.txt

    此致!

    马瑞安