TI E2E™ 设计支持论坛将于 5 月 30 日至 6 月 1 日进行维护。如果您在此期间需要技术支持,请联系 TI 的客户支持中心寻求帮助。

该讨论已被锁定。
您不能再向该讨论中发布新回复。如果您有问题可以开始新讨论

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

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

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 任务。

                      惠特尼