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.

[参考译文] MSPM0G3507:重新启用时防止 TIMA1事件

Guru**** 2457760 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1486779/mspm0g3507-prevent-tima1-event-on-re-enable

器件型号:MSPM0G3507

工具与软件:

嗨、 我遇到了一些 PWM 计时器问题-让我描述一下我正在做的工作:
(原谅长的描述-它是尽可能短,我可以使它)。

我将使用 TIMA0、TIMG7、TIMA1和 TIMG6创建四个交错中心对齐 PWM 信号。
TIMA0使用其处于50%占空比的第二个通道生成事件、以90度相移触发 TIMG7、并以180度相移交叉触发 TIMA1。
TIMA1同样使用第二个通道以相对于 TIMA0 270度的相移触发 TIMG6。
到目前为止一切顺利。
这些 PWM 正在驱动四个 MOSFET、我需要在占空比中间(在其负载事件中)测量它们的电流。
我将使用 TIMA1生成零、CCU1、加载和 CCD1事件、以触发 ADC。
ADC 设置为使用 FIFO、并在转换四个样本时触发中断。

现在-当我改变 PWM 频率时、问题出现、这将影响定时器在何时被采样时的同步。
为了尝试解决此问题、我首先实现了影子加载/比较。
现在我调用一个用于更改频率的函数、首先计算新的 load 和 Compare 值(全局变量)。 然后、我在 CCD1上为 TIMA0启用中断。
在 ISR 中、我首先禁用了这个中断、因此它只运行一次。 接下来、我禁用所有定时器的重复、使它们完成当前周期、然后停止。
我还针对 TIMA1的归零事件禁用 IMASK (因为这会在 TIMA0停止后触发它的 ADC 测量...)
最后、我在 TIMG6发生 CCD0事件时启用中断。

在第二个 ISR 中、我再次禁用该中断。
然后、我尝试禁用 TIMA1并清除它的任何事件、并将它的计数器设置为0、然后再重新启用它的事件。
我对 TIMG6执行相同的操作。

最后、我重新启用 TIMA0。
在我看来、这应该能"重新启动"整个 PWM 机器、就像程序启动时一样。 这很好地工作、直到我尝试改变频率。
更具体地说、当我重新启用 TIMA0时、TIMA1会立即触发一个事件、以触发 ADC 采样、现在该事件为 TIMA0的 Zero、从而使整个 ADC 同步退出窗口。

我的问题:
当 TIMA1最初不执行此操作时、为什么它会在此时触发事件? (它应启动、直到它被 TIMA0的加载事件交叉触发。)

下面是初始启动的屏幕截图:



这里的这个变换频率函数被称为:


(谨记您-在这里、我没有重新启用重复、这就是为什么在重新启动时它只是一个单次触发。)
标记"2"表示我尝试避免的事件、这会破坏同步。

以下是 TIMA0 ISR 的代码(抱歉、代码太乱)

void TIMA0_IRQHandler()
{
    GPIOB->DOUTTGL31_0 = DL_GPIO_PIN_17;

    // Disable this IRQ
    NVIC_DisableIRQ(TIMA0_INT_IRQn);

    // Halt the timer
    //DL_Timer_disableClock(TIMA0);
    //TIMA0->COMMONREGS.CCLKCTL = GPTIMER_CCLKCTL_CLKEN_DISABLED;
    TIMA0->COUNTERREGS.CTRCTL &= ~GPTIMER_CTRCTL_REPEAT_MASK;
    TIMG7->COUNTERREGS.CTRCTL &= ~GPTIMER_CTRCTL_REPEAT_MASK;
    TIMA1->COUNTERREGS.CTRCTL &= ~GPTIMER_CTRCTL_REPEAT_MASK;
    TIMG6->COUNTERREGS.CTRCTL &= ~GPTIMER_CTRCTL_REPEAT_MASK;

    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    TIMA1->COUNTERREGS.LOAD = new_load_value;
    TIMG6->COUNTERREGS.LOAD = new_load_value;

    TIMA1->COUNTERREGS.CC_01[0] = new_compare_value;
    TIMG6->COUNTERREGS.CC_01[0] = new_compare_value;

    TIMA1->COUNTERREGS.CC_01[1] = new_trigger_compare_value;

    TIMA0->COUNTERREGS.LOAD = new_load_value;
    TIMG7->COUNTERREGS.LOAD = new_load_value;

    TIMA0->COUNTERREGS.CC_01[0] = new_compare_value;
    TIMG7->COUNTERREGS.CC_01[0] = new_compare_value;

    TIMA0->COUNTERREGS.CC_01[1] = new_trigger_compare_value;

    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // Disable zero and CCD1 events for TIMA1
    TIMA1->GEN_EVENT1.IMASK &= ~DL_TIMER_EVENT_ZERO_EVENT;
    TIMA1->GEN_EVENT1.IIDX;
    TIMA1->GEN_EVENT1.ICLR = 0xFFFFFF;

    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    TIMG6->CPU_INT.IIDX;
    NVIC_ClearPendingIRQ(TIMG6_INT_IRQn);
    NVIC_EnableIRQ(TIMG6_INT_IRQn);

    GPIOB->DOUTTGL31_0 = DL_GPIO_PIN_17;
}


这是 TIMG6 ISR 的代码:
void TIMG6_IRQHandler()
{
    GPIOB->DOUTTGL31_0 = DL_GPIO_PIN_3;

    // Disable this IRQ
    NVIC_DisableIRQ(TIMG6_INT_IRQn);

    TIMA1->COUNTERREGS.CTRCTL &= ~GPTIMER_CTRCTL_EN_ENABLED;

    TIMA1->GEN_EVENT1.IMASK = 0;
    TIMA1->GEN_EVENT1.IIDX;
    TIMA1->GEN_EVENT1.ICLR = 0xFFFFFF;
    TIMA1->COUNTERREGS.CTR = 400;

    TIMA1->GEN_EVENT1.IMASK |= (DL_TIMER_EVENT_CC1_UP_EVENT |
        DL_TIMER_EVENT_CC1_DN_EVENT |
        DL_TIMER_EVENT_LOAD_EVENT |
        DL_TIMER_EVENT_ZERO_EVENT);

    TIMG6->COUNTERREGS.CTRCTL &= ~GPTIMER_CTRCTL_EN_ENABLED;
    TIMG6->GEN_EVENT1.IMASK = 0;
    TIMG6->COUNTERREGS.CTR = 0;
    TIMG6->GEN_EVENT1.IMASK |= (DL_TIMER_EVENT_CC1_UP_EVENT |
        DL_TIMER_EVENT_CC1_DN_EVENT |
        DL_TIMER_EVENT_LOAD_EVENT |
        DL_TIMER_EVENT_ZERO_EVENT);      

    // Resume
    // TIMA0->COUNTERREGS.CTRCTL |= GPTIMER_CTRCTL_REPEAT_REPEAT_1;
    // TIMG7->COUNTERREGS.CTRCTL |= GPTIMER_CTRCTL_REPEAT_REPEAT_1;
    // TIMA1->COUNTERREGS.CTRCTL |= GPTIMER_CTRCTL_REPEAT_REPEAT_1;
    // TIMG6->COUNTERREGS.CTRCTL |= GPTIMER_CTRCTL_REPEAT_REPEAT_1;
    TIMA0->COUNTERREGS.CTRCTL |= GPTIMER_CTRCTL_EN_ENABLED;

    GPIOB->DOUTTGL31_0 = DL_GPIO_PIN_3;
}

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

    您好!

    我想、您可以在更改频率之前尝试重新初始化 timerA0和 timerA1。 我认为某些寄存器未被完全清除、因此导致了此问题。

    此致、

    Cash Hao

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

    400的数字有什么意义? 这是否为周期的1/4? 它是否会受到 NEW_LOAD_VALUE 的影响?

    要了解触发了哪个事件(TIMA1->GEN_EVENT1.MIS)、可能会提供很多信息。