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.

[参考译文] CCS/TMS320F28062:当将 ADC 配置为由 CPU timer0触发时、ADC 无法正常工作。

Guru**** 2538955 points
Other Parts Discussed in Thread: CONTROLSUITE, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/704927/ccs-tms320f28062-adc-didn-t-work-when-it-was-configured-to-be-triggered-by-cpu-timer0

器件型号:TMS320F28062
Thread 中讨论的其他器件:controlSUITEC2000WARE

工具/软件:Code Composer Studio

我需要 ADC 模块的 SOC3-SOC12每1ms 启动一次转换。下面列出了我的 ADC 模块配置:

EALLOW;
AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 0x03;//< SOC0-SOC2为高优先级;
AdcRegs.SOCPRICTL.bit.OneShot = 1;//<启用单次触发模式。

AdcRegs.ADCSOC0CTL.bit.CHSEL = 0x03;
AdcRegs.ADCSOC1CTL.bit.CHSEL = 0x05;
AdcRegs.ADCSOC2CTL.bit.CHSEL = 0x0C;

AdcRegs.ADCSOC3CTL.bit.CHSEL = 0x00;//< ADCINA0、电网电压 L1n;
AdcRegs.ADCSOC4CTL.bit.CHSEL = 0x01;//< ADCINA1、电网电压 L2n;
AdcRegs.ADCSOC5CTL.bit.CHSEL = 0x02;//< ADCINA2、电网电压 L3n;
AdcRegs.ADCSOC6CTL.bit.CHSEL = 0x0A;//< ADCINB2、直流总线电压;
AdcRegs.ADCSOC7CTL.bit.CHSEL = 0x07;//<

AdcRegs.ADCSOC8CTL.bit.CHSEL = 0x04;//< ADCINA4、充电模块温度;
AdcRegs.ADCSOC9CTL.bit.CHSEL = 0x06;//< ADCINA6、IPM 温度;
AdcRegs.ADCSOC10CTL.bit.CHSEL = 0x08;//< ADCINB0、空气温度;
AdcRegs.ADCSOC11CTL.bit.CHSEL = 0x09;//< ADCINB1、电机温度;
AdcRegs.ADCSOC12CTL.bit.CHSEL = 0x0B;//< ADCINB3、IGBT 温度;

AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 0x06;//< ePWM1 ADCSOCB 触发 SOC0
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 0x06;//< ePWM1 ADCSOCB 触发 SOC1
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 0x06;//< ePWM1 ADCSOCB 触发 SOC2

AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 1;//< CPU 定时器0触发 SOC3
AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 1;//< CPU 定时器0触发 SOC4
AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 1;//< CPU 定时器0触发 SOC5
AdcRegs.ADCSOC6CTL.bit.TRIGSEL = 1;//< CPU Timer0触发器 SOC6
AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 1;//< CPU Timer0触发器 SOC7
AdcRegs.ADCSOC8CTL.bit.TRIGSEL = 1;//< CPU Timer0触发 SOC8
AdcRegs.ADCSOC9CTL.bit.TRIGSEL = 1;//< CPU Timer0触发 SOC9
AdcRegs.ADCSOC10CTL.bit.TRIGSEL = 1;//< CPU Timer0触发 SOC10
AdcRegs.ADCSOC11CTL.bit.TRIGSEL = 1;//< CPU Timer0触发 SOC11
AdcRegs.ADCSOC12CTL.bit.TRIGSEL = 1;//< CPU Timer0触发 SOC12

AdcRegs.INTSEL1N2.bit.INT1CONT = 1;//<启用连续模式。
AdcRegs.INTSEL1N2.bit.INT1SEL = 2;//<在与 SOC2竞争之后将生成中断。
AdcRegs.INTSEL1N2.bit.INT2CONT = 1;//<启用连续模式。
AdcRegs.INTSEL1N2.bit.INT2SEL = 12;//<在与 SOC11竞争之后将生成中断。
AdcRegs.INTSEL1N2.bit.INT1E = 1;
AdcRegs.INTSEL1N2.bit.INT2E = 1;

AdcRegs.ADCINTSOCSEL1.ALL = 0;
AdcRegs.ADCINTSOCSEL2.ALL = 0;

AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;/ADCINT 在转换结束时生成
AdcRegs.ADCCTL1.bit.VREFLOCONV = 0;
AdcRegs.ADCCTL1.bit.TEMPCONV = 0;
AdcRegs.ADCCTL1.bit.ADCREFSEL = 0;//<选择内部基准电压。
AdcRegs.ADCCTL1.bit.ADCENABLE = 1;
EDIS; 

有两个 ADC 中断、一个用于 SOC2、另一个用于 SOC12。CPU 定时器0被配置为每1ms 发出一次中断、运行良好。但是 CPU 只调用 ADCINT2的 ISR 两次。这个问题困扰了我一整天。最后、我不得不将触发源更改为软件触发。

有没有人可以告诉我为什么 ADC 不使用 CPU 定时器0作为其触发源?

提前感谢您的帮助。

 


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    您也可以共享您的计时器配置和 ISR 代码吗? 检查是否在 ISR 中正确清除了标志。

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

    感谢您的回复。

    Fifin允许 是我的 ADC INT2的计时器配置和 ISR:

    InitCpuTimer();
    ConfigCpuTimer0 (&CpuTimer0、90、analog_sample_period);//< analog_sample_period = 1000
    
    void CPU_timer0_ISR (void)//< PIE1.7
    {
    CpuTimer0.InterruptCount++;
    if (CpuTimer0.Interruptc1)=
    
    
    
    0xCCP1
    
    
    = 0xCCP1、中断1 = 0xCCP1、CCP1、CCP1 = 0xCCP1、CCP1、CCP1、CCP1、CCP1 = 0xCCP1 =中断;中断;CCP1 = 0xCCP1 =清除 CCP1 =中断;CCP1;CCP1 =中断;CCP1 =中断;CCP1 =中断 CCP1 = 0xCCP1 =中断
    PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;
    } 

    ADCINT2的 ISR:

    void ADCInt2ISR (void)//< PIE1.2
    {
    g_AnalogSstruesStruc.m_L3N.m_ValADC =(short) AdcResult.ADCRESULT3 -(short) AdcResult.ADCRESULT5;//<线路电压:
    Current_Resist.ADCRESULt4
    
    =(Adc.ADCRESDUT_SHORT) ADCRESDUT_ADCRT.ADCRESDUT = ADCRED_ADCRESTRU.ADCRT.ADCREST_ADCREST_SHORT = ADCRESTRUT.ADCREST_ADCREST_ADCRT.ADCRESTRUT.ADCREST_ADCRT.ADCREST_ADCRT.ADCRESTRUT.ADCREST_ADCREST_ADCRT.ADCRT6 = ADCRESTRUVW = ADCRED_ADCRED_ADCRED_ADCRESTRU.ADCRESTRU.ADTRU.ADCRESTRU.ADTRU.ADTRU.ADCREST_ADCREST_ADCREST.ADCR
    
    
    
    
    
    G_AnalogsStruc.m_MotorTmpt.m_ValADC = AdcResult.ADCRESULT11;
    G_AnalogStrues.m_IGBTTmpt.m_ValADC = AdcResult.ADCRESULT12;
    
    DF (&G)模拟1st1stb、IG_Df 模拟1stb (&g)
    模拟1stb 模拟1stb
    (1 N);Analog_strulesstr1stb 1f (1 N)模拟1str2f (1 N);Analog_Df 1str1str1stb 1 N)模拟1 f (1 f (1 f 模拟1 N)
    DF (&G)模拟1ststststepstate,&g_AnalogStrues.m_DCBus);
    DF (&G)模拟1stststststststep,&g_1uesStruc.m_MotorStallCurrent);
    
    DF DF (&G 1stststepAnalog,&g_Struesc.m_ChargeTmpt);
    DF Analog 1stststststststststststepstr1stepstepst&g Analog
    ,&t_Stubstrg_Strudstept;Df
    DF (&G) 1ststack Analog、&g_AnalogesStradc.m_MotorTmpt);
    DF (&G) 1stack Analog、&g_AnalogesStruc.m_IGBTTmpt);
    
    
    AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;AdcRegs.pit.ADC1stl
    
    = ADC1stl //确认 PIE 中断
    
    } 

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

    [引用]void cpu_timer0_isr (void)//< PIE1.7{CpuTimer0.InterruptCount++;if (CpuTimer0.InterruptCount >= CFG_Period_anamples_TO_CONTROL){CpuTimer0.InterruptCount = 0;}AdcRegs.ADCCOCFR1<TCO/TO_CONTROL.C12/ TO_CONTROL.C12/ TO_CONTROL.C12/=清除寄存器0;中断 PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;}[/QUERP]

    您好!

    我认为问题是因为您在 CPU 计时器和 ADCINT ISR 中确认组1中断。 您的应用中是否需要这两种 ISR? 您可以在 PIE 级别禁用计时器0中断、并将计时器0用作 ADC 的触发器、或尝试将计时器1或计时器2用作 ADC 触发器。

    谢谢

    Vasudha

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

    我意识到 timer0、ADCINT1和 ADCINT2都在同一组中、即组1、并且在计时器和 ADC ISR 中都得到确认。 这可能会导致问题。 您能否尝试使用计时器1或计时器2作为触发器、并查看 ADCINT2 ISR 是否正在被调用。

    谢谢
    Vasudha
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    很抱歉、我忘记提供一些信息。我使用了与 TI 提供的示例相同的软件优先级中断。ADCINT1、ADCINT2和 timer0中断的优先级分别为1、2、2。ADCSOC1-ADCSOC2由 ePWM1以20kHz 的频率触发。EOC2事件触发 ADCINT1。
    回到我的问题,你所说的真的让我感到困惑。它是否会阻止 CPU 调用 ADCINT2来在计时器和 ADC ISR 结束时确认中断组?但是在 TI 提供的示例中,每个 ISR 都包含一条声明来确认中断组。
    我在每个中断服务函数的末尾确实会注释确认中断组的语句。但问题与以前一样存在。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    是的、您答对了、我们需要在每个 ISR 中确认中断。 我已修改先前的答覆。 我认为 ADC 中断也会在计时器 ISR 中得到应答。

    您的应用中是否需要计时器0 ISR? 您可以在 PIE 级别禁用 CPU 定时器0中断、并且仍会触发 ADC。 ADCINT 和定时器0都在同一 PIE 组中、组中断在两个 ISR 中都被确认、这可能是问题所在。

    对于该解决方案、您可以在外设级别启用 Timer0中断、但在 PIE 级别禁用它。 保持 ADCINT 部件不变。 这将解决问题。

    谢谢
    Vasudha
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    感谢您的耐心等待。
    我通过清零 PIEIER 中的相关位来禁用 CPU TIMER0中断、并保持 ADCINT 不变。但仍然不调用 ADCINT2的 ISR。
    我认为中断没有问题、可能是配置 SOC2-SOC12触发源有问题、所以 ADC 的 SOC2-SOC12不起作用。
    我在应用中调试了我的程序、发现 SOC2-SOC12的结果寄存器没有改变。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Xing、

    您可能不想在计时器 ISR 中执行软件 SOC 强制:

    AdcRegs.ADCSOCFRC1.ALL = 0x1FF8;//< SOC3->SOC12
    

    计时器本身将根据配置生成触发器。  您几乎肯定会通过再次触发 SOC 来创建溢出。

    最好返回 C2000Ware 或 controlSUITE 中的 ADC_SoC 示例、以确保您的 ADC 硬件转换使用 ePWM 触发器。  然后将 ePWM 触发器更改为计时器触发器、以确保计时器触发器的软件配置良好。

    Tommy

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    我根据您的建议仔细比较了我的 ADC 配置和 TI 示例。最后、我发现 TI 示例未将 ADC 配置为在 OneShot 模式下工作。在注释 OneShot 模式语句后、ADCINT2正常工作!
    但我仍然想知道原因。
    根据《Piccolo 技术参考指南》,ADC 将在循环方案中的下一个触发 SOC 上执行单次转换。 因此、无论执行序列、SOC12最终都会被触发、EOC12将生成一个中断。但实际情况是、ADCINT2 ISR 在开始时被调用两次后永远不会再次被调用。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Xing、

    如果您移除了多余的 ADCSOCFRC1触发器、它是否起作用?

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

    Tommy、
    在我发现 CPU timer0没有触发 ADC 转换后、ADCSOCFRC1触发被添加。
    删除 OneShot 模式的配置可以解决我的问题。但我不知道为什么!

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

    Xing、

    我无法得出为什么删除 OneShot 会使一切正常工作的结论。  我认为这里有太多的变量。  例如、双触发 ADC 可能会导致奇怪的行为。

    如果您希望完全调试行为、则需要简化代码并确保每个寄存器设置都生成所需的行为。  这包括 TIMER0成功触发 ADC。

    Tommy

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

    Xing、

    您可以从 ADC_SoC 示例开始、并按如下方式继续。  请确保通过在步骤之间执行 CPU 复位或断电来清除中断标志。

    1. 构建并运行未经修改的示例、在 ISR 中针对指令"ConversionCount = 0"设置断点; 这应按预期运行、每10个 ePWM 触发一次断点停止。
    2. 删除 EPWM 配置。  使用相同的 ADC ISR 断点构建并运行。  由于 ePWM 不会发出 ADC 触发信号、因此该运行永远不会停止。
    3. 将 ADC TRIGSEL 设置从 ePWM (5)更改为 CPU 定时器(1)。  计时器已启用。  使用相同的 ADC ISR 断点构建并运行。  该运行应每10个计时器触发一次。
    4. 通过设置 TCR[TIE]和 PIEIER1[INTx7]来启用计时器中断。  添加一个除设置 PIEACK[PIEACK_Group1]之外不执行任何操作的计时器 ISR。  在计时器 ISR 中和正常 ADC ISR 断点处设置断点。  构建并运行。  对于每个 ADC ISR 停止、该运行应在计时器 ISR 处停止10次。

    Tommy