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:由 ECAP 触发 CLA 任务

Guru**** 2551310 points
Other Parts Discussed in Thread: CONTROLSUITE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/821006/tms320f28379d-triggering-cla-task-by-ecap

器件型号:TMS320F28379D
Thread 中讨论的其他器件:controlSUITE

大家好、

我尝试通过 ECAP 中断触发 CLA 任务。 我的 ADC 中断可以触发 CLA、但我不知道我在 ECAP/CLA 配置中做了什么错误。

这是我的 CLA 中断配置。

静态内联 void Init_cla_Interrupt (void)
{
EALLOW;

// CLA 的软复位-在软复位之后、必须等待至少1个 SYSCLKOUT 周期、然后再重新配置 MIER 位。
Cla1Regs.MCTL.bit.SOFTRESET = ON;

//不需要配置 CLA1TASSKSRCSELLOCK 寄存器,只分配任务一次

//将触发器设置为 CLA 任务
// AdcDrv 将 ADC 中断(每个 ADC 最多4个)分配给不同的 ADC 通道(每个 ADC 16个)
DmaSrcCLA.1TABLET.CLA1_ECTAG.CLA = CLA1TTREST.TAG_CLA
DmaClaSrcSelRegs.CLA1TASKSRCSEL1.bit.task2 = CLA_TRIG_ADCAINT1;
DmaClaSrcSelRegs.CLA1TASKSRCSEL1.bit.TASK3 = CLA_TRIG_ADCDINT1;
DmaClaSrcSelRegs.CLA1TASKSRCSEL1.bit.TASK4 = CLA_TRIG_EPWM2INT;
DmaClaSrcSelRegs.CLA1TASSKSRCSEL2.bit.TASK5 = CLA_TRIG_SD1INT;
DmaClaSrcSelRegs.CLA1TASSKSRCSEL2.bit.TASK8 = CLA_TRIG_NOPERPH;

//为 CLA 任务设置指针
Cla1Regs.MVECT1 =(UL)(Cla1Task1);
Cla1Regs.MVECT2 =(UL)(Cla1Regs.MVECT3
);Cla1Regs.MVECT3 =(UL)(Cla1Task3);
Cla1Regs.MVECT4 =(UL)(Cla1Reg4);Cla1MVECT5
=(Cla1Reg5);Cla1Regt5 (UL);Cla1Regt5 (Cla1Regt5)
Cla1Regs.MVECT8 =(UL)(Cla1Task8);

//为所有8个 CLA 任务设置中断使能
Cla1Regs.MIER = 0xFF;

EDIS;

EALLOW;

//清除所有旧的中断标志
Cla1Regs.Clalr.all = 0xFF;
//清除旧的旧的标志 MICRO1Regs.MicroCLS.Cltask.all
= 0xFF;

//为所有任务配置
中断向量
PieVectTable.CLA1_2_INT = endOfClaIsr;
PieVectTable.CLA1_3_INT = endOfClaIsr;
PieVectTable.CLA1_4_INT = endClaResetIsr;
PieVectTable.CLA1_5_INT = endOfClaIsr;
PieVectTable.CLA1_8_INT = endOfClaInitIsr;

//在组和子组级别启用 CLA 中断
PieCtrlRegs.PIEIER11.all = 0xFFFF;//启用组11
IER 中的所有中断|=(M_INT11); //启用组11

// CLA 直接访问中断,而不是通过 PIE 访问(C2000 CLA 常见问题解答)
//在组和子组级别为 ECAP 启用 CLA 中断
// PieCtrlRegs.PIEIER4.all = 0xFFFF;//启用组4中的所有中断
// IER ||=(M_INT4); //启用组4

EDIS;

EALLOW;

//通过软件中断初始化 CLA 变量到 CLA 任务8
Cla1Regs.MIFRC.bit.INT8 = ON;
asm (" RPT #3 || NOP");
while (Cla1Regs.MIRUN.bit.INT8 = 1);

EDIS;
} 

这里是我的 ECAP 配置。

void Init_CaptureDrv (void)
{
US 模块=(US) ECAP_DRV_MODULE_1;
UL 周期= 0U;

EALLOW;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//// Pinmux 配置 GPIO25 => J6引脚51;OUTPUTXBAR2
// OutputXbarRegs.OUTPUT2MUX0TO15CFG.bit.MUX8 = 3U; // MUX8 => ECAP5OUT
// OutputXbarRegs.OUTPUT2MUXENABLE.bit.MUX8 =打开;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////eCAP
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// GPIO95 => J5引脚42
// GpioCtrlRegs.GPCPUD.bit.GPIO95 =关闭;//上拉使能
// GpioCtrlRegs.GPCDIR.bit.GPIO95 =关闭;//输入
// InputXbarRegs.INPUT7SELECT =
关闭;// INPUTCL0C.INTRU.INTRU.INTRU.INTRIP.INTRU.INTRCK =关闭

//影子寄存器
UL sRegCTRPHS = 0x00000000; //影子寄存器计数器阶段
UL sRegCAPx = 0x00000000; //影子寄存器 CAPx
美国 sRegECEINT = 0x0000; //影子寄存器中断使能(EALLOW)
美国 sRegECFLG = 0x0000; //影子寄存器中断标志
美国 sRegECCLR = 0x0000; //影子寄存器中断清除
美国 sRegECFRC = 0x0000; //影子寄存器中断强制

对于(MODULE =(US) ECAP_DRV_MODULE_1;MODULE <=(US) ECAP_DRV_MODULE_4;MODULE++)
{
//配置为捕获
eCapDrv.pRegsECAP[模块]->ECCTL2.bit.CAP_APWM =关闭;

//禁用 CAP1-CAP4寄存器载入并确保计数器被停止
eCapDrv.pRegsECAP[模块]->ECCTL1.bit.CAPLDEN =关闭;
eCapDrv.pRegsECAP[模块]->ECCTL2.bit.TSCTRSTOP =关闭;

//将计数器相位设置为0
eCapDrv.pRegsECAP[模块]->CTRPHS = sRegCTRPHS;

//将 ECAP 寄存器初始化为0
eCapDrv.pRegsECAP[模块]->CAP1 = sRegCAPx;

//禁用中断和清除标志
eCapDrv.pRegsECAP[模块]->ECEINT.ALL = sRegECEINT;
eCapDrv.pRegsECAP[模块]->ECFLG.ALL = sRegECFLG;
eCapDrv.pRegsECAP[模块]->ECCLR.ALL = sRegECCLR;
eCapDrv.pRegsECAP[模块]->ECFRC.ALL = sRegECFRC;

//确定周期和占空比的两个上升沿和两个下降沿
eCapDrv.pRegsECAP[模块]->ECCTL1.bit.free_soft = 3U; // TSCTR 自由运行
eCapDrv.pRegsECAP[模块]->ECCTL1.bit.CAP1POL =关闭; //上升沿
eCapDrv.pRegsECAP[模块]->ECCTL1.bit.CAP2POL =开; //下降沿
eCapDrv.pRegsECAP[模块]->ECCTL1.bit.CAP3POL =关闭; //上升沿
eCapDrv.pRegsECAP[模块]->ECCTL1.bit.CAP4POL =开; //下降沿
eCapDrv.pRegsECAP[模块]->ECCTL1.bit.CTRST1 =打开; //差动运算
eCapDrv.pRegsECAP[模块]->ECCTL1.bit.CTRST2 =打开; //差动运算
eCapDrv.pRegsECAP[模块]->ECCTL1.bit.CTRST3 =打开; //差动运算
eCapDrv.pRegsECAP[模块]->ECCTL1.bit.CTRST4 =打开; //差动运算
eCapDrv.pRegsECAP[模块]->ECCTL1.bit.prescale =关闭; //不使用预分频器

//同步
eCapDrv.pRegsECAP[模块]->ECCTL2.bit.SYNCI_EN =开; //启用同步输入
eCapDrv.pRegsECAP[模块]->ECCTL2.bit.SYNCO_SEL =关闭; //同步输入被传递到同步输出
eCapDrv.pRegsECAP[模块]->ECCTL1.bit.CAPLDEN =开; //启用捕捉单元
eCapDrv.pRegsECAP[模块]->ECCTL2.bit.tSCTRSTOP =开; //开始计数器
eCapDrv.pRegsECAP[模块]->ECCTL2.bit.rearm =开; // Arm One-Shot
eCapDrv.pRegsECAP[模块]->ECCTL2.bit.CONT_ONESHT =关闭; //连续操作模式
}

//配置 APWM
周期=(UL) CLKDRV_SYSCLKOUT_MHz /(UL) SDCLK_FREQ_MHz;

eCapDrv.pRegsECAP[ECAP_DRV_MODULE_5]->ECCTL2.bit.CAP_APWM =开; // eCap5用作 APWM
eCapDrv.pRegsECAP[ECAP_DRV_MODULE_5]->ECCTL2.bit.SYNCI_EN =关闭; //禁用同步输入选项
eCapDrv.pRegsECAP[ECAP_DRV_MODULE_5]->ECCTL2.bit.SYNCO_SEL = 3U; //禁用同步输出信号
eCapDrv.pRegsECAP[ECAP_DRV_MODULE_5]->CAP1 =(周期- 1U);// UL 设置周期值
eCapDrv.pRegsECAP[ECAP_DRV_MODULE_5]->CAP2 =(周期/2U - 1U);// UL 设置比较值
eCapDrv.pRegsECAP[ECAP_DRV_MODULE_5]->CAP3 =(周期- 1U);// UL 设置周期值
eCapDrv.pRegsECAP[ECAP_DRV_MODULE_5]->CAP4 =(周期/2U - 1U);// UL 设置比较值
eCapDrv.pRegsECAP[ECAP_DRV_MODULE_5]->ECCLR.ALL = 0xFF; //清除暂挂的__interrupts。
eCapDrv.pRegsECAP[ECAP_DRV_MODULE_5]->ECCTL1.bit.FREE_SOFT = 3U; // TSCTR 计数器不受仿真挂起(自由运行)的影响
eCapDrv.pRegsECAP[ECAP_DRV_MODULE_5]->ECCTL1.bit.prescale =关闭; //无预分频
eCapDrv.pRegsECAP[ECAP_DRV_MODULE_5]->ECCTL2.bit.TSCTRSTOP =开; //时间戳计数器自由运行

//调试
eCapDrv.pRegsECAP[ECAP_DRV_MODULE_5]->ECEINT.BIT.CTR_EQ_PRD =开; // CTR 上的中断= PRD


EDIS; //启用写保护
} 

指示中断弹出的标志:

我还在 C2000常见问题解答中发现、CLA 中断不会通过 PIE、而是可以直接触发任务。 我看不到这种情况发生了。 感谢您的任何帮助!

谢谢!

Alex



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

    Alex、

    您能否详细说明调试步骤?  例如:

    • -执行任务8,初始化任务,正确工作并完成(.. 确保 C28x 不会一直等待...)?
    • -在 CLA 任务1中放置一个断点以查看是否已命中。 此外、检查任务1中是否未设置意外断点并停止执行。  
    • - CLA 中断标志是否为任务1设置?
    • -确认任务1的矢量值是否正确?  仔细检查其他寄存器是否设置正确。
    • -我注意到您在清除"旧 CLA 中断标志"时、请确保 eCAP 中断不会被此操作所干扰(检查设置顺序是否正确)

    我建议观看 CLA 实践技术讲座。  它很好地描述了 CLA、如何为它开发代码、以及如何在 Code Composer Studio 中对它进行调试。 我想您会发现它在这样的调试案例中很有用。

    以下是 CLA 技术讲座的链接:

    单击此处了解更多 CLA 常见问题解答和资源。

    但愿这对您有所帮助。 如果这解决了您的问题、请单击绿色的"这解决了我的问题"按钮、让我知道。  

    此致、

    Lori

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

    您好!

    我在 CLA 任务1和8中设置了一个__mdebugstop()。 进入任务8并正确运行。 与我的 ADC 触发 CLA 任务一样、我可以在 我配置的任务中断结束时看到它。 但任务1永远不会被输入。

    我也看不到任务8的 Cla1Regs.MIFR 位设置、也看不到 MIRUN 设置。 正如我昨天向您展示的、我的 ECAP 会在 CTR=PRD 事件上触发中断、并且该中断已启用。 我认为中断和任务开始之间缺少链接。

    寄存 器中的 MVECT 值与.CLA 文件中的 OONE 值以及我将 MVECT 寄存器分配给的值相同。  

    对于由 ADC 触发的任务的配置、我使用了 C2000 controlSUITE 示例、但我找不到任何用于由其他外设触发 CLA 任务的示例。 您能否提供一个简单的配置来通过 ADC 以外的任何外设触发 CLA 任务? 我观看了实际操作的教程、但我看不到我缺少的内容。

    谢谢!

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

    Alex、

    感谢您的反馈。  我将在星期五结束前仔细查看并与您联系。  

    eCAP 的连接方法与 ePWM 和 ADC 的方法相同。  正确、外设的中断直接进入 CLA、而不依赖于 PIE。  

    此致

    Lori

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

    您好!

    感谢你的答复。

    今天、我开始了一些小项目、仅通过 ePWM 和 ECAP 触发 CLA 任务。 好消息是它已经成功了。 坏的情况是我比较了 Cla1Regs 任务矢量和 MIER 位、针对正确中断编号的 DmaClaSrcSelRegs、中断使能和外设中的标志(ECAP、ePWM)。 我看不到有什么不同。 我还应该看看其他什么寄存器? 哪个寄存器参与向 CLA 发送中断?

    谢谢  

    Alex

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

    Alex、

    调试建议-禁用 ePWM 和 ADC 的中断。  看看您是否观察到任何差异。  我知道您的 eCAP 中断具有最高优先级、因此它不应被阻止、但减少代码中发生的事情可能会有所帮助。   

    我进行了一个快速的最小测试。  在这个示例中、中断被强制。

    DisableDog ();
    Dint;
    
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.CLA1 = 1;
    CpuSysRegs.PCLKCR3.bit.ECAP5 = 1;
    
    MemCfgRegs.LSxMSEL.bit.MSEL_LS4 = 1;
    MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS4 = 1;
    MemCfgRegs.LSxMSEL.bit.MSEL_LS5 = 1;
    MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS5 = 1;
    
    Cla1Regs.MVECT1 =(uint16_t)(&Cla1Task1);
    Cla1Regs.MIER =(M_INT1);
    DmaClaSrcSelRegs.CLA1TASKSRCSEL1.bit.task1 = CLA_TRIG_ECAP5INT;
    EDIS;
    
    ECap5Regs.ECCTL2.bit.CAP_APWM = 1; //启用 APWM 模式
    ECap5Regs.ECCTL2.bit.TSCTRSTOP = 0; //停止计时器-在本示例中,我们将强制 INT
    ECap5Regs.ECCLR.ALL = 0x0FF; //清除暂挂中断
    ECap5Regs.ECEINT.BIT.CTR_EQ_PRD = 1;//启用比较等效 PRD 中断
    
    //强制 eCAP5 PRD 中断4次
    ECap5Regs.ECFRC.bit.CTRL_PRD = 1; //强制中断
    asm (" RPT #7 || NOP"); //等待 CLA 启动
    while (Cla1Regs.MIRUN.bit.INT1=1);//等待 CLA 完成
    
    ECap5Regs.ECFRC.bit.CTRL_PRD = 1; //强制中断
    asm (" RPT #7 || NOP"); //等待 CLA 启动
    while (Cla1Regs.MIRUN.bit.INT1=1);//等待 CLA 完成
    
    ECap5Regs.ECFRC.bit.CTRL_PRD = 1; //强制中断
    asm (" RPT #7 || NOP"); //等待 CLA 启动
    while (Cla1Regs.MIRUN.bit.INT1=1);//等待 CLA 完成
    
    ECap5Regs.ECFRC.bit.CTRL_PRD = 1; //强制中断
    asm (" RPT #7 || NOP"); //等待 CLA 启动
    while (Cla1Regs.MIRUN.bit.INT1=1);//等待 CLA 完成
    ESTOP0; 

    CLA 代码:

    Cla1Task1:
    MADDF32 MR0、MR0、#0x3F80;将 MR0递增1
    MMOVXI MR1、#0x00FF
    MMOV16 @0x5098、MR1;清除 eCAP5中断标志
    MNOP
    MNOP
    MNOP
    MSTOP
    MNOP
    MNOP
    MNOP
    _Cla1T1End: 

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

    感谢您的帮助!

    我终于明白了。 在我较大的应用中、外设的初始化在我的初始化例程的开始阶段完成。 CLA 的初始化在稍后完成。 引用 TRM:

    例如、通过向写入36、任务1 (MVECT1)可被设定为在 EPWMINT1上触发
    DmaClaSrcSelRegs.CLA1TASSKSRCSEL1.bit.task1. 可禁用由触发任务
    外设、用户必须将 DmaClaSrcSelRegs.CLA1TASKSRCSELx[TASKx]位字段设置为0。 它
    应该注意的是、CLA 任务仅在配置的中断的电平转换(边沿)时触发
    源。

    最后一句是线索。 我只需要复位外设的中断标志。

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

    Alex、

    感谢您让我知道该解决方案是什么。  是的、CLA 必须看到边沿;如果中断已经挂起、它将丢失。  我会将其添加为 CLA 常见问题解答之一。

    祝您编码愉快、致以诚挚的问候

    Lori