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.

[参考译文] TMS320F28377S:C2000WARE/TMS320F28377S:TMS320F28377S 上的 PWM6A 输出问题所需的帮助

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

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1475761/tms320f28377s-c2000ware-tms320f28377s-assistance-needed-for-pwm6a-output-issue-on-tms320f28377s

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

工具与软件:

您好!

下面的原理图显示了我正在使用的控制板、其中包括 TMS320F28377S。 如图所示、该电路板设计为使用 EPWM6A 及更高版本。

在 TI 的 C2000Ware 中提供的示例中、EPWM_UP_AQ 示例仅采用 EPWM1至 EPWM3。 为了根据我的需求调整它、我修改了 EPWM_UP_AQ_cpu01.c 文件、以仅使用 EPWM6A、如下所示。 (但是、我没有对 F2837xS_GPIO.c 或 F2837xS_EPWM.c 等其他文件进行任何更改。)

========================================================================================================================================================================================================================================

#include "F28x_Project.h"

#define EPWM6_TIMER_TBPRD 2000 //周期寄存器
#define EPWM6_MAX_CMPA 950
#define EPWM6_MIN_CMPA 50
#define EPWM6_MAX_CMPB 1950
#define EPWM6_MIN_CMPB 1050

epwm_info epwm6_info;
void InitEPwm6Example (void);
_interrupt void epwm6_isr (void);

void main (void)

InitSysCtrl();
CpuSysRegs.PCLKCR2.bit.EPWM6=1;
颜色;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();

EALLOW;//要写入 EALLOW 保护的寄存器、需要执行此操作
PieVectTable.EPWM6_INT =&epwm6_ISR;
EDIS;//这是禁用对 EALLOW 保护寄存器的写入所必需的

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

IER |= M_INT3;
PieCtrlRegs.PIEIER6.bit.INTx6 = 1;

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

for (;;)

ASM (" NOP");
}
}

//
// epwm6_ISR - EPWM6 ISR 以更新比较值
//
_interrupt void epwm6_isr (void)

//
//更新 CMPA 和 CMPB 值
//
update_compare (&epwm6_info);

//
//清除此计时器的 INT 标志
//
EPwm6Regs.ETCLR.bit.INT = 1;

//
//确认该中断以接收来自组3的更多中断
//
PieCtrlRegs.PIEACK.all = PIEACK_Group3;
}

//
// InitEPwm6Example -初始化 EPWM6值
//
void InitEPwm6Example()

//
//设置 TBCLK
//
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;//递增计数
EPwm6Regs.TBPRD = EPWM6_TIMER_TBPRD;//设置计时器周期
EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;// Disable phase loading (禁用相位加载)
EPwm6Regs.TBPHS.bit.TBPHS = 0x0000;// Phase 为0
EPwm6Regs.TBCTR = 0x0000;//清除计数器
EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2;//时钟与 SYSCLKOUT 的比率
EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV2;

//
//将影子寄存器加载设置为零
//
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADODE;
EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

//
//设置比较值
//
EPwm6Regs.CMPA.bit.CMPA = EPWM6_MIN_CMPA;//设置比较一个值
EPwm6Regs.CMPB.bit.CMPB = EPWM6_MIN_CMPB;//设置比较 B 值

//
//设置操作
//
EPwm6Regs.AQCTLA.bit.ZRO = AQ_SET;//将 PWM6A 设置为零
EPwm6Regs.AQCTLA.bit.CAU = AQ_clear;//在事件 A 上清除 PWM6A、
//向上计数

EPwm6Regs.AQCTLB.bit.ZRO = AQ_SET;//将 PWM6B 设置为零
EPwm6Regs.AQCTLB.bit.CBU = AQ_clear;//在事件 B 上清除 PWM6B、
//向上计数

//
// Interrupt (中断)、其中我们将更改 Compare (比较)值
//
EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;//在发生归零事件时选择 INT
EPwm6Regs.ETSEL.bit.INTEN = 1;// Enable INT (启用 INT)
EPwm6Regs.ETPS.bit.INTPRD = ET_3RD;//在发生第3个事件时生成 INT

//
//信息此示例用于跟踪
// CMPA/CMPB 值的方向
//移动、允许的最小值和最大值和
//指向正确 ePWM 寄存器的指针
//
epwm6_info.ePWM_CMPA_DIRECTION = ePWM_CMP_UP;//通过增大开始
// CMPA & CMPB
epwm6_info.ePWM_CMPB_direction = ePWM_CMP_UP;
epwm6_info.EPwmTimerIntCount = 0;//将中断计数器归零
epwm6_info.EPwmRegHandle =&EPwm6Regs;//将指针设置为
// ePWM 模块
epwm6_info.EPwmMaxCMPA = EPWM6_MAX_CMPA;//设置最小值/最大值
// CMPA/CMPB 值
epwm6_info.EPwmMinCMPA = EPWM6_MIN_CMPA;
epwm6_info.EPwmMaxCMPB = EPWM6_MAX_CMPB;
epwm6_info.EPwmMinCMPB = EPWM6_MIN_CMPB;
}

//
// update_compare -更新指定 ePWM 的比较值
//
void update_compare (ePWM_info * ePWM_info)

//
//每隔10'CMPB 中断一次、更改 th CMPA/CMPB 值
//
if (EPWM_INFO->EPwmTimerIntCount == 10)

EPWM_INFO->EPwmTimerIntCount = 0;

//
//如果我们要增加 CMPA、请检查是否
//我们达到了最大值。 如果不是这样、请增加 CMPA
//否则、更改方向并减小 CMPA
//
if (EPWM_INFO->EPWM_CMPA_DIRECTION == EPWM_CMP_UP)

if (EPWM_INFO->EPwmRegHandle->CMPA.bit.CMPA < EPWM_INFO->EPwmMaxCMPA)

EPWM_INFO->EPwmRegHandle->CMPA.bit.CMPA++;
}
设计

EPWM_INFO->EPWM_CMPA_DIRECTION = EPWM_CMP_DOWN;
EPWM_INFO->EPwmRegHandle->CMPA.bit.CMPA--;
}
}

//
//如果我们要降低 CMPA、请检查是否
//我们达到了最小值。 否则、请降低 CMPA
//否则、更改方向并增加 CMPA
//
设计

if (ePWM_info->EPwmRegHandle->CMPA.bit.CMPA == ePWM_info->EPwmMinCMPA)

EPWM_INFO->EPWM_CMPA_DIRECTION = EPWM_CMP_UP;
EPWM_INFO->EPwmRegHandle->CMPA.bit.CMPA++;
}
设计

EPWM_INFO->EPwmRegHandle->CMPA.bit.CMPA--;
}
}

//
//如果我们要增大 CMPB、请检查是否
//我们达到了最大值。 如果不是这样的话、增加 CMPB
//否则、更改方向并减小 CMPB
//
if (EPWM_INFO->EPWM_CMPB_DIRECTION == EPWM_CMP_UP)

if (EPWM_INFO->EPwmRegHandle->CMPB.bit.CMPB < EPWM_INFO->EPwmMaxCMPB)

EPWM_INFO->EPwmRegHandle->CMPB.bit.CMPB++;
}
设计

ePWM_INFO->EPWM_CMPB_DIRECTION = ePWM_CMP_DOWN;
EPWM_INFO->EPwmRegHandle->CMPB.bit.CMPB--;
}
}

//
//如果我们降低了 CMPB、请检查是否
//我们达到了最小值。 如果不是这样、请减小 CMPB
//否则、更改方向并增加 CMPB
//
设计

if (EPWM_INFO->EPwmRegHandle->CMPB.bit.CMPB ==
EPWM_INFO->EPwmMinCMPB)

EPWM_INFO->EPWM_CMPB_DIRECTION = EPWM_CMP_UP;
EPWM_INFO->EPwmRegHandle->CMPB.bit.CMPB++;
}
设计

EPWM_INFO->EPwmRegHandle->CMPB.bit.CMPB--;
}
}
}
设计

EPWM_INFO->EPwmTimerIntCount++;
}

返回;
}

//
//文件结尾
//
================================================================================================================================================================================================================================================

尽管已根据修改后的文件完成了调试过程、但在使用示波器进行检查时、我在 PWM6A 上没有看到任何输出。

您能否提供有关需要修改哪些文件和特定代码来启用 EPWM6A 输出的指导?

非常感谢您的建议。

此致、
金承洙

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

    你好、Seungsoo、

    一些有助于调试的问题:

    1. 您是否能够 不修改地运行示例并在示波器上看到 ePWM 输出?
    2. 在修改后的项目中、当您单步执行代码并检查 EPWM6寄存器时、您是否看到配置按预期变化?
    3. 当运行修改后的项目时、您是否看到 EPWM6计数器主动进行计数?
    4. 请仔细检查 EPWM6 GPIO 初始化。 您正在关注哪些 GPIO?

    此致、

    Allison

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

    1.我使用的电路板搭载了 F28377S、从 EPWM6开始采用 ePWM。 因此、无法使用现有示例观察 ePWM 输出。
    2.我修改了原始 C2000Ware 示例文件 epwm_up_AQ、在 epwm_up_AQ_cpu01.c 代码中仅将数字从 EPWM1更改为 EPWM6。
    3.如何判断 EPWM6计数器是否在增加?
    4.如下图、我想检查 EPWM6A 的输出、所以我用示波器测量 GPIO10。

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

    您好!

    您可以通过查看 CCS 中的"Registers"窗口、检查 ePWM 配置是否正确编程、并查看 EPWM6在运行期间的变化计数器。

    转至"View">"Registers">滚动至 EPWM6寄存器、然后使用下拉菜单找到 EPWM6 TBCTR 寄存器。 确保在运行时启用了"Continuous Refresh"、以便寄存器值实时更新(随着值的变化、这些值将突出显示黄色)。  

    请告诉我您是否能够查看这些寄存器以及您的配置是否被正确执行-您可以在初始化期间、在您"单步执行"代码行时查看寄存器、以查看寄存器中所做的相应更改。

    您是否已设置 GPIO 以将其配置为输出 EPWM6? 请验证 GPIO 寄存器也是否正确设置。 您能否发送您的初始化?

    此致、

    Allison

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

    您好、Nguyen、

    随附的图像显示了通过目标配置在实时模式下使用 F28377S 板在 C2000Ware 中执行 EPWM_UP_AQ_cpu01示例。

    如前所述、即使按下 Continuous Refresh、EPWM1寄存器值也不会更新、并保持在0x0000。

    如果您能提供解决此问题的任何建议、我将不胜感激。

    感谢您投入宝贵的时间给予大力支持。

    此致、
    金承洙

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

    金承洙

    感谢检查寄存器。 为了澄清、您在代码中的哪个点检查寄存器? 您能否使用"单步执行"按钮或在初始化 ePWM 时基寄存器并发送此操作的屏幕截图的代码行之后设置一个断点?  

    此外、看起来您正在查看"Expressions"窗口。 您能否发送"Registers"窗口的片段、其中 EPWM6寄存器已展开并可查看?

    现在、您发送的 ePWM 寄存器是完全空的、这意味着您可能要配置不同的 ePWM 或查看不同 ePWM 的寄存器、您是在运行 init 之前检查这些寄存器、或者我们需要进行其他方面的研究。

    此致、

    Allison

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

    您好、 Allison

    我发布的上一个屏幕截图是在执行以下步骤后捕获的:
    Target Configurations→Launch Selected Configuration→Connect Target→Enable Silicon Real-Time Mode→Resume。

    此外、使用相同的方法获取了随附的屏幕截图、但这次打开了"Registers"窗口、以提高可见性。

    此外、当我尝试使用 Step Over 按钮时、调试器会切换到显示以下消息的窗口:
    "在没有可用调试信息或程序代码之外的地址"0x3ff16e"处中断。"

    因此、我无法继续执行 Step Over (单步执行)函数。

    此致、
    金承洙

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

    金承洙

    加载程序时、CCS 是否会在 main ()函数的开始处停止? 由于您无法单步执行代码、我怀疑您的代码是否正确运行了初始化-这也会解释您没有看到 ePWM 未得到配置的原因。  

    您在调试窗口中看到的消息意味着 CPU 已到达 Bootrom 中的一个地址(0x3ff16a) 、具体如 F2837xS 数据表(下面)中的器件存储器映射所示-某些 ITRAP 中可能是如此。  

    您是否可以运行未修改的 C2000ware 示例、首先确保您可以加载和单步执行器件初始化、并查看寄存器是否正确更改(如果您不能访问这些引脚、则无需对引脚进行作用域)。 我想将此作为基准、并确保您的设置正常工作。

    此致、

    Allison

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

    您好、Allison、

    构建未修改的 C2000Ware 示例时、我只看到一些建议消息、如下所示。

    但是、当我完成这些步骤时:
    Target Configurations→Launch Selected Configuration→Connect Target→Enable Silicon Real-Time Mode→Resume、
    我仍然会遇到同样的问题、即"在没有可用调试信息的地址"0x3ff16a"处中断、或在程序代码之外。" 消息。

    此外、当我尝试使用 Step Over (单步执行)按钮时、调试器切换到相同消息、因此无法使用 Step Over (单步执行)功能。

    在您之前的建议中、您提到根据器件存储器映射、CPU 可能已落入 ITRAP 之手。
    按照下面文章中的建议、将应用程序从基于 RAM 的配置修改为基于闪存的配置是否可以解决此问题?

    e2e.ti.com/.../tms320f28379d-running-code-from-flash

    此致、
    金承洙

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

    金承洙

    在您之前的建议中、您提到根据器件存储器映射、CPU 可能已成为 ITRAP。
    按照下面文章中的建议、将应用程序从基于 RAM 的配置修改为基于闪存的配置是否可以解决此问题?[/QUOT]

    不可以、ITRAP 本质上是一种安全机制-如果它尝试非法指令或其他相关问题、则停止 CPU。 这不能解决触发 ITRAP ISR 的原因。

    目标配置→启动所选配置→连接目标→启用芯片实时模式→恢复、

    澄清一下、您是否能够将.out 文件成功加载到器件上? 连接后、选择"加载">"加载程序">"浏览项目"、然后选择在构建项目以将其加载到 RAM 或闪存中时生成的".out"文件。 如果正在正确加载、应在加载后在 main ()的开头停止。

    此致、

    Allison

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

    您好、Allison、

    构建未修改的 C2000Ware 示例后、我使用以下步骤在 Debugging 窗口中指定 epwm_up_AQ_cpu01.out 文件:
    Run→Load→Load Program→选择 EPWM_UP_AQ_cpu01.out 文件
       

    单击 Resume (恢复)后、代码的 main()函数行旁边出现了一个蓝色块、如随附的屏幕截图所示。 (蓝色块仅出现在 main()函数中。)

    这是否意味着.out 文件已成功加载、且执行在 main ()的开头停止?

    此致、
    金承洙

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

    Kim Suengsoo、

    是的,这是我需要的确认,谢谢。 在了解这一点后、您可以在观察寄存器窗口的同时使用"Step Over"按钮在初始化中单步执行代码吗? 或者-根据您之前的响应-当您尝试越过第一行时、您是否会看到地址中断消息? 您是否可以在不启用实时模式的情况下尝试加载和运行(您目前使用此模式的具体原因是什么)?

    此致、

    Allison

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

    您好、Allison、

    所附的屏幕截图是在执行以下步骤后获得的:
    Run→Load→Load Program→选择 EPWM_UP_AQ_cpu01.out 文件、然后点击 Step Over 按钮。

    与以前不同、以前的停止消息不再显示。

    但是、如您在"Registers"窗口中所见、EPwm1Regs.TBCTR 值保持为0x0000、即使在点击"Continuous Refresh"按钮后也是如此。

    我怀疑的一件事是蓝色块只出现在 main()函数行的旁边。
    因为 main()函数仅包含以下行:

    //
    // Main
    //
    void main(void)
    {
    //
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xS_SysCtrl.c file.
    //
        InitSysCtrl();
    
    //
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xS_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 F2837xS_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 F2837xS_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 F2837xS_DefaultIsr.c.
    // This function is found in F2837xS_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
        PieVectTable.EPWM1_INT = &epwm1_isr;
        PieVectTable.EPWM2_INT = &epwm2_isr;
        PieVectTable.EPWM3_INT = &epwm3_isr;
        EDIS;   // This is needed to disable write to EALLOW protected registers
    
    //
    // For this example, only initialize the ePWM
    //
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
    
        InitEPwm1Example();
        InitEPwm2Example();
        InitEPwm3Example();
    
        EALLOW;
        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):
    //
        for(;;)
        {
            asm ("  NOP");
        }
    }
    

    这是否就是 EPwm1Regs.TBCTR 保持为0x0000的原因?
    我的假设是否正确?

    此外、我使用实时模式的原因是、作为 CCS 的初学者、我提到 YouTube 视频和博客文章、这些都指导我使用实时模式。

    此致、
    金承洙

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

    金承洙

    单步执行 SYSCTRL INIT 后、您应该会转至下一行代码且 CPU 保持暂停。 在您提供的映像中、可以看到 CPU "正在运行"。 您能不能进入 SYSCTRL INIT、然后单步执行代码以确保其正常执行(在切换过程中观察 SYSCTRL 寄存器以确保各行均已正确配置)。 您是否能够执行 systrl 初始化?

    澄清一下、您是否无法运行 任何 C2000ware 示例? 您是否为此使用 LaunchPad?

    如果您不熟悉 CCS 和 C2000、我也建议您访问 C28x Academy。 这里有一些练习、可指导您如何设置和运行项目以及验证项目。

    此致、

    Allison

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

    您好、Allison、

    感谢您的帮助、我能够解决这个问题。

    使用步越函数进行调试时、我发现代码执行卡在 F2837xS_SYSCTRL.c 中的以下行:

                while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1)

    调查后发现与 TMS320F28377S 相连的振荡器焊接不当。 重新焊接元件后、代码按预期执行、并能够确认 EPWM6信号。

    非常感谢您的支持。 我真的很感激!

    此致、
    金承洙