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.

[参考译文] TMS320F28035:关于切换到备用时钟。

Guru**** 2974170 points

Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1320865/tms320f28035-about-switching-to-an-alternative-clock

器件型号:TMS320F28035
主题中讨论的其他器件:C2000WARE

你好。
请告诉我在检测到 MISS_CLOCK 时切换到备用时钟的情况。
PLL_INITIAL (6、2)使用20M_XTAL 生成60MHz 系统时钟。
对于切换测试,运行以下代码,该过程将继续执行 NMI_ISR()。
NmiIntruptRegs.NMIFLGFRC.bit.CLOCKFAIL = 1;

我们知道、有必要重新配置 PLL 才能在该函数内切换到内部 OSC1。
这种理解是否正确?
我想使用内部 OSC1并使用 PLL_Initial (12、2)生成一个60MHz 系统时钟。
但是、当执行此函数时、CPU 将停止。
相反、如果未执行此函数、CPU 将继续运行。
XTAL->OSC1在未复位 PLL 的情况下切换是否成功?

祝你一切


​

__interrupt void nmi_isr(void)
{
    PLL_Initial(12, 2);     // CLK=10M*12/2=60M  XTAL->OSC1

    EALLOW;
    NmiIntruptRegs.NMIFLGCLR.bit.CLOCKFAIL = 1;
    NmiIntruptRegs.NMIFLGCLR.bit.NMIINT = 1;
    EDIS;
}

void 
PLL_Initial(Uint16 val, Uint16 divsel)
{
   volatile Uint16 iVol;

   //
   // Make sure the PLL is not running in limp mode
   //
   if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
   {
        EALLOW;
        
        //
        // OSCCLKSRC1 failure detected. PLL running in limp mode.
        // Re-enable missing clock logic.
        //
        SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1;
        EDIS;
        
        //
        // Replace this line with a call to an appropriate
        // SystemShutdown(); function.
        __asm("        ESTOP0");     // Uncomment for debugging purposes
    }

    //
    // DIVSEL MUST be 0 before PLLCR can be changed from
    // 0x0000. It is set to 0 by an external reset XRSn
    // This puts us in 1/4
    //
    if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
    {
        EALLOW;
        SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
        EDIS;
    }

    //
    // Change the PLLCR
    //
    if (SysCtrlRegs.PLLCR.bit.DIV != val)
    {
        EALLOW;
        
        //
        // Before setting PLLCR turn off missing clock detect logic
        //
        SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
        SysCtrlRegs.PLLCR.bit.DIV = val;
        EDIS;

        //
        // Optional: Wait for PLL to lock.
        //
        // During this time the CPU will switch to OSCCLK/2 until
        // the PLL is stable.  Once the PLL is stable the CPU will
        // switch to the new PLL value.
        //
        // This time-to-lock is monitored by a PLL lock counter.
        //
        // Code is not required to sit and wait for the PLL to lock.
        // However, if the code does anything that is timing critical,
        // and requires the correct clock be locked, then it is best to
        // wait until this switching has completed.
        //
        
        //
        // Wait for the PLL lock bit to be set.
        //

        //
        // The watchdog should be disabled before this loop, or fed within
        // the loop via ServiceDog().
        //

        //
        // Uncomment to disable the watchdog
        //
        DisableDog();

        while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
        {
            //
            // Uncomment to service the watchdog
            //
            // ServiceDog();
        }

        EALLOW;
        SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
        EDIS;
    }

    //
    // If switching to 1/2
    //
    if((divsel == 1)||(divsel == 2))
    {
        EALLOW;
        SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
        EDIS;
    }

    //
    // If switching to 1/1
    // * First go to 1/2 and let the power settle
    //   The time required will depend on the system, this is only an example
    // * Then switch to 1/1
    //
    if(divsel == 3)
    {
        EALLOW;
        SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
        DELAY_US(50L);
        SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
        EDIS;
    }
}

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

    测试条件类似于 www.ti.com/lit/SPRUI10:第74页所示的情况 D"PLLCR 已归零。 用户必须重新配置 PLLCR"

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

    感谢您的答复。
    没错。 它是模拟的。
    那么、当在不可屏蔽中断内使用 PLL_Initial (12、2)函数复位时、CPU 为什么停止工作?
    请告诉我可能的原因。
    我已经附加了 XTAL 初始化函数。
    INTOSC1继续振荡。

    void XTAL_Sel (void)  {
         EALLOW;
         SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 0;     // Turn on XTALOSC
         DELAY_US(1000L);                           // 1mS delay to ensure crystal
                                                    // oscillator is up and running.
                                                    // Adjust as needed.
         SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 1;      // Turn off XCLKIN
         SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 0;  // Switch to external clock
         SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1;   // Switch from INTOSC1 to INTOSC2/ext clk
         SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0;    // Clock Watchdog off of INTOSC1
         SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1;     // Turn off INTOSC2
         SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;    // Leave INTOSC1 on
         EDIS;
    }

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

    您能解释一下我的"CPU 停止工作"是什么意思吗? 因为 CPU 必须具有某种功能。 必须执行一些代码。 它不能简单地"停止"。 CPU 实际上停止(即不进行任何操作)的唯一时间是处于3种低功耗模式(IDLE、STANDBY 或 HALT)中的一种

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

    这正是您所说的。 没有写入代码以转换到 LPM_MODE。
    当我查看详细信息的时候、只是 SCI 通信是不可能的。
    我将使用 CPUTIMER 0生成2ms 任务、但它已更改为1ms 周期。
    当在不可屏蔽中断内执行 PLL_Initial (12、2)时产生 NG。
    请勿复位。 或 PLL_Initial (6、2)正常。
    从上面看、它似乎没有切换到 INTOSC1。
    我了解 INTOSC1会在检测到 CLOCKFAIL 时自动切换。
    我是否需要提前进行任何设置?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我了解当检测到 CLOCKFAIL 时 INTOSC1会自动切换

    是的。

    看起来 CPU 并未实际"停止"、但是您代码的运行方式正在发生改变。 我建议您 按"原样"使用 DSP2803x_sysctrl.c 中的函数(请参见 C:\ti\c2000\C2000Ware_5_01_00_00\device_support\f2803x\common\source 目录)。 这些都是经过测试的功能、不需要任何修改即可工作。

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

    谢谢你。 请您再告诉我一点。
    在 DSP2803x_sysctrl.c 文件的 InitPll 函数中、
    while (SysCtrlRegs.PLLSTS.bit.PLLLOCKS!= 1)
    {
    //
    //取消注释以处理看门狗
    //
    // ServiceDog ();
    }
    是否可以保留 ServiceDog ();是否已注释掉?
    启用/禁用内部 WD 是否与 CLK 开关无关?
    在 InitSysCtrl(void)中删除 IntOsc1Sel()并按我理解的方式写入 XtalOscSel()是否可以?
    此致!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是否可以离开 ServiceDog ();是否已注释?

    如果 WD 计数器溢出、它将复位器件。

    内部 WD 启用/禁用是否与 CLK 切换无关?

    可以。

    是否可以在 InitSysCtrl(void)中删除 IntOsc1Sel()并根据我的理解写入 XTalOscSel()?

    可以。 如前所述、如果按原样使用 C2000ware 中的函数、应该不会出现任何问题。