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.

[参考译文] TMS320F28069:带有 PWM2的 ADC SOC/EOC 中断

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/715692/tms320f28069-adc-soc-eoc-interrupts-with-pwm2

器件型号:TMS320F28069

您好!

我正在尝试触发 ADC、以便在 PWM2B 的下降沿开始转换。 当我在 PWM1B 上触发转换时、我能够生成 ADC 中断并最终从通道10读取一个值(当我置位时:EPwm1Regs.ETSEL.bit.SOCBSEL = 6;和 AdcRegs.ADCSOC0CTL.bit.TRIGSEL=6;

是否有人可以告诉我、该设置中缺少哪些内容可防止 SOC 或 EOC 中断发生?  谢谢你!!

这是我的设置

 /*配置 ADC */
    EALLOW;
    AdcRegs.INTSEL1N2.bit.INT1E = 1;      //启用 ADCINT1 *
    AdcRegs.INTSEL1N2.bit.INT1CONT = 0;   //禁用 ADCINT1连续模式*
    AdcRegs.INTSEL1N2.bit.INT1SEL = 0;    //设置 EOC0以触发 ADCINT1触发*
    AdcRegs.ADCSOC0CTL.bit.CHSEL = 0xA;   //将 SOC0通道选择设置为 ADCINB2 *
    AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 8;   //设置 SOC0在 EPWM1B 上启动触发器,因为轮询 SOC0先转换,然后 SOC1 */
    AdcRegs.ADCSOC0CTL.bit.ACQPS = 6;     //将 SOC0 S/H 窗口设置为7个 ADC 时钟周期,(6个 ACQPS 加1)*/
    AdcRegs.ADCCTL1.bit.INTPULSEPOS = 0;  //配置早期中断*
    EDIS;

    /*假定 ePWM1时钟已在 InitSysCtrl()中启用;*/
    EPwm2Regs.ETSEL.bit.SOCBEN = 1;       //在 B 组上启用 SOC *
    EPwm2Regs.ETSEL.bit.SOCBSEL = 8;      //从 CPMB 中选择 SOC,进行向上计数*/
    EPwm2Regs.ETPS.bit.SOCBPRD = 0;       /*在发生第一个事件时生成脉冲*

    /*PWM2:设置周期/占空比/计数模式*/
    EPwm2Regs.TBPHS.Half.TBPHS = 0; //PHASE          /*将 PHASE 寄存器设置为0 *
    EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;    //TB_ENABLE;     //禁用相位加载*
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   /*时钟与 SYSCLKOUT 的比率*
    EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;         //将 PWM2A 设置为零
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;       //在递增计数时按匹配清除 PWM1A *
    EPwm2Regs.AQCTLB.bit.ZRO = AQ_SET;         //将 PWM1B 设置为零*
    EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR;       //在计数 B 递增时按匹配清除 PWM2B */
    EPwm2Regs.CMPB = 180;                      //设置比较 B 值*/
    EPwm2Regs.CMPA.half.CMPA = 250;            //设置比较值*
    EPwm2Regs.TBPRD =周期;                  //为 ePWM1设置周期*
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; /*先递增后启动*
    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;//TB_SYNC_IN;

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

    那么、您说 ePWM1 SOCB 工作、但 ePWM2 SOCB 不工作?

    您能否在 CCS 中上拉"Registers"视图、并确保 ePWM2已加电、并且正确的值正在写入寄存器中? 我不认为您要写入的任何内容受 EALLOW 保护、但我最好仔细检查。

    转换是否仍在进行、但仅缺少中断? 还是结果寄存器也不更新?

    谢谢、

    惠特尼

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

    非常感谢您的帮助! 我成功解决了我的问题。 尽管我仍有疑问:

    我有3个 EPWM:PWM1B、PWM2B 和 PWM3B、并且我已经将这些 EPWM 配置为触发 ADC 转换启动(在 EPWMB 通道的下降沿上) 、最终生成 ADC ISR。

    我是否可以在 ISR 内部找出是哪个 ePWM (在这三个中的一个)导致了 ADC 转换?  

    谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这取决于您的中断是如何设置的。 例如、如果由 PWM1、PWM2和 PWM3触发的 SOC 与 ADCINT1、INT2和 INT3关联、但使用相同的 ISR、则可以读取 PIECTRL.PIEVECT 寄存器以查看哪个中断向量使您进入 ISR、从而进入哪个 PWM。

    如果您对所有 SOC 使用相同的 ADCINT 编号、则可以尝试检查每个 PWM 的 ETFLG 寄存器以查看哪个 PWM 设置了 SOCB。 据我所知、只能通过对 ETCLR 寄存器的写操作将其清零、因此您应该能够将其用于此目的。

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

    现在、我需要从我设置的3个 ISR 中的每个调用 CLA1task1、CLA1task2、CLA1task3。 此调用是否完成以下任务:Cla1ForceTask1andWait();Cla1ForceTask2andWait();Cla1ForceTask3andWait()?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您可以从 ISR 强制执行 CLA 任务、但我不知道您希望等待任务完成。 这似乎需要花费大量时间在 ISR 中。 您可能只想在 ISR 中使用 Cla1ForceTask1、但要检查任务是否在代码中的其他位置完成。

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

     你好!

    我再次回到同一个问题。 我正在尝试使用2个 PWM (在 每个 PWM 的下降沿处于120度相移)来触发同一模拟信号的 SOC。 我使用以下配置:

     /*配置 ADC */
        EALLOW;
        AdcRegs.INTSEL1N2.bit.INT1E = 1;      //启用 ADCINT1 *
        AdcRegs.INTSEL1N2.bit.INT1CONT = 0;   //禁用 ADCINT1连续模式*
        AdcRegs.INTSEL1N2.bit.INT1SEL = 0;    //设置 EOC0以触发 ADCINT1触发*
        AdcRegs.ADCSOC0CTL.bit.CHSEL = 0xA;   //将 SOC0通道选择设置为 ADCINB2 *
        AdcRegs.ADCSOC0CTL.bit.TRIGSEL = ADCTRIG_EPWM1_SOCB;//6;   //设置 EPWM1B 上的 SOC0启动触发器,因为轮询 SOC0先转换,然后 SOC1 */
        AdcRegs.ADCSOC0CTL.bit.ACQPS = 6;     //将 SOC0 S/H 窗口设置为7个 ADC 时钟周期,(6个 ACQPS 加1)*/
        AdcRegs.ADCCTL1.bit.INTPULSEPOS = 0;  //配置早期中断*
        EDIS;

        /*配置 ADC */
        EALLOW;
        AdcRegs.INTSEL1N2.bit.INT1E = 1;                            //启用 ADCINT2 *
        AdcRegs.INTSEL1N2.bit.INT1CONT = 0;                         //禁用 ADCINT2连续模式*
        AdcRegs.INTSEL1N2.bit.INT1SEL = 1;                          //设置 EOC1以触发 ADCINT2触发*/
        AdcRegs.ADCSOC1CTL.bit.CHSEL =0xA;                          //将 SOC1通道选择设置为 ADCINB0 *
        AdcRegs.ADCSOC1CTL.bit.TRIGSEL= ADCTRIG_EPWM2_SOCB;         //设置 EPWM1B 上的 SOC1启动触发器,因为轮询 SOC0先转换,然后 SOC1 */
        AdcRegs.ADCSOC1CTL.bit.ACQPS = 6;                           //将 SOC1 S/H 窗口设置为7个 ADC 时钟周期,(6个 ACQPS 加1)*/
        AdcRegs.ADCCTL1.bit.INTPULSEPOS = 0;                        //配置早期中断*
        EDIS;

    当我获得一个 ISR 时、我会检查设置标志位以查看触发事件的是哪个位、结果是在两个 if 语句中都设置了标志位。

     if (EPwm1Regs.ETFlG.bit.SOCB=1)
       {
          GpioDataRegs.GPBTOGGLE.bit.GPIO32=1;
          EPwm1Regs.ETCLR.bit.SOCB = 1;
       }

       if (EPwm2Regs.ETFlG.bit.SOCB=1)
       {
         GpioDataRegs.GPBTOGGLE.bit.GPIO32=1;
         EPwm2Regs.ETCLR.bit.SOCB = 1;
       }

    请告诉我缺少配置的内容。

    最后、我要做的是触发 CLA、为每个 PWM 触发后采样的三个 ADC 值中的每个值计算 PID 值。 请告知您如何继续。

    此致!

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

    我成功解决了我的问题。 现在、我有3个 PWM 触发 ADC SOC、我将获得三个不同的中断、从中读取 SOC0、SOC1和 SOC2的 ADC 结果。 现在、我需要调用一个 CLA 任务来使用检索到的 ADC 值来计算每个 ISR 的 PID 值。

    是否最好在每次 EOC 中断后进行 CLA 任务调用、而不是现在执行的操作、然后读取 ADC 值并使用它来计算 PID 值?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    另一个问题:

    我从 ISR 调用 Task1、如下所示:

    _interrupt void
    adc_isr1 (空)

    ADCValue_PWM1B = AdcResult.ADCRESULT0;
    Cla1ForceTask1();

    AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //为下一个 SOC 清除 ADCINT1标志*/
    PieCtrlRegs.PIEACX.ALL = PIEACK_Group1; /*确认 PIE 中断*/


    在 CLA 中、我将按如下方式修改 ADC 值:

    _interrupt void
    Cla1Task1 (空)

    _mdebugstop();
    ADCValue1= ADCValue_PWM1B*3;


    然而、ADCValue1的值在 main 中不会改变、我一直读取0。 任何人能否就如何在 CPU 和 CLA 之间共享变量提出建议?

    下面是我在 shared_data.c 中定义变量的方式:

    #pragma DATA_SECTION (ADCValue_PWM1B、"CpuToCla1MsgRAM");
    UINT16 ADCValue_PWM1B;

    #pragma DATA_SECTION (ADCValue1、"Cla1ToCpuMsgRAM");
    uint16 ADCValue1;
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我已经分配了一个 ADC 来触发一个 CLA 任务:AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;我已经注意到 CLA 只被调用一次? 有人能告诉我可能缺少什么吗?


    _interrupt void
    Cla1Task1 (空)

    _mdebugstop();
    ADCValue_PWM1B = AdcResult.ADCRESULT0;
    ADCValue1= ADCValue_PWM1B*2;


    _interrupt void
    cla1_Task1_ISR (空)

    AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
    PieCtrlRegs.PIEACk.bit.ACK11 = 1;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您是否仍然遇到共享 ADCValue1的问题? 如果你看看它在.map 文件中的地址、它肯定被放置在 Cla1ToCpuMsgRAM 中吗?

    您能否通过查看寄存器窗口来确认 ADCINT1标志是否已被正确清除? 您是否使用 CLA_ADC_FIR32示例对代码建模? 它还使用 ADCINT1来触发 CLA 任务。

    惠特尼
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    现在、我将从 ADC EOC ISR 触发 CLA 任务、ADC SOC 由 PWM 的下降沿触发。 我在之前发现我的 CLA 任务只运行一次。 但现在、在我添加 Cla1Regs.MMEMCFG.ALL |= CLA_PROG_ENABLE 之后;在 ISR 内部、一旦我接收到 ADC 中断、CLA 就会被连续调用。

    在 main()的上方,我有这段代码
    EALLOW;
    Cla1Regs.MMEMCFG.ALL = CLA_PROG_ENABLE|CLARAM0_ENABLE|CLARAM1_ENABLE|CLARAM2_ENABLE|CLA_RAM2_ENABLE|CLA_RAM1CPUE;
    Cla1Regs.MCTL.bit.IACKE = 1;
    EDIS;



    _interrupt void
    adc_isr1 (空)


    AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //为下一个 SOC 清除 ADCINT1标志*/
    PieCtrlRegs.PIEACX.ALL = PIEACK_Group1; /*确认 PIE 中断*/

    ADCValue_PWM1B= AdcResult.ADCRESULT0;

    EALLOW;
    Cla1Regs.MMEMCFG.ALL |= CLA_PROG_ENABLE;
    EDIS;

    Cla1ForceTask1();


    如果已经在 main 中声明、我不知道这个 CLA_PROG_ENABLE 与任务1有什么关系。

    我还发现、触发 ADC SOC 的 PWN 下降沿和 ADC ISR (EOS)之间的延迟时间约为600ns。 我是否有任何方法可以使该时间延迟更短。

    谢谢!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我在 ADC ISR 中添加了以下代码、并且正在按预期调用 CLA。 任何人能否解释这段代码与触发 CLA 任务有什么关系?

    EALLOW;
    Cla1Regs.MMEMCFG.ALL |= CLA_PROG_ENABLE;
    EDIS;

    在 main()中,我已经调用了:
    EALLOW;
    Cla1Regs.MMEMCFG.ALL = CLA_PROG_ENABLE|CLARAM0_ENABLE|CLARAM1_ENABLE|CLARAM2_ENABLE|CLA_RAM2_ENABLE|CLA_RAM1CPUE;
    Cla1Regs.MCTL.bit.IACKE = 1;
    EDIS;


    adc_isr1 (空)

    AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; /*为下一个 SOC 清除 ADCINT2标志*/
    PieCtrlRegs.PIEACX.ALL = PIEACK_Group1; /*确认 PIE 中断*/

    EALLOW;
    Cla1Regs.MMEMCFG.ALL |= CLA_PROG_ENABLE;
    EDIS;

    Cla1ForceTask1();