当配置为使用带有 MOSC 作为其源的 PLL 时、我对 SysCtlClockFreqSet 有疑问。 在这种情况下、我看到该函数执行以下操作:
- 为 MOSC 加电
- 将 OSCSRC 设置为 PIOSC
- 快速计算
- 将 OSCSRC 和 PLLSRC 都设置为 MOSC
- 配置 PLL 并等待 PLL 锁定。 出现超时返回错误。
- 将 SYSCLK 从 OSCCLK 更改为 PLL。
- 将 OSCSRC 设置为 PIOSC (稍后添加到地址勘误表 SYSCTL#23)
我想知道为什么在#4中 OSCSRC 更改为 MOSC、以及它是否真的有必要。 我看不到任何明显的目的。 更改为 PIOSC、然后几乎立即更改为 MOSC 也似乎很奇怪。 也许第二个变化只是为了改变 PLLSRC? 勘误表似乎支持这一点:"它将 OSCCLK 设置为 MOSC、这不是必需的"。
这在采用晶体的典型系统中可能无关紧要、但我有一个时钟源可能需要一些时间来启动。 我确实有一些时间来延迟调用 SysCtlClockFreqSet 直到时钟准备就绪、但我怀疑有时可能会失败。
我原本希望死时钟输入会导致在#5中等待 PLL 锁定的超时、但似乎错过了在#4中对 OSCSRC 的第二次更改、这会首先杀死 CPU。 有机会使用看门狗计时器从该计时器中恢复、但超时错误会更灵活。 此外、此时的看门狗复位与稍后在应用代码中的看门狗复位几乎是无法区分的、这使得调试变得更加困难。
此时、我将尝试在启动后不久跟踪罕见的 WDT 复位。 如果我可以重现它、我想知道它是否在时钟切换期间。 为此、我已经修改了 SysCtlClockFreqSet、使其在切换到 PLL 之前一直保持在 PIOSC 上。 它看起来工作正常、如果在时钟输入死区时调用 SysCtlClockFreqSet、那么我现在会得到一个特定的错误、而不是 WDT 复位。 我对可能的意外后果有点担心。 此更改是否会触发任何已知问题?
int main (void) { WaitForFpgaToSignalThat25MHzClockIsReady(); EnableWatchdog (1000/*ms*/);//在2个超时后发生复位 uint32_t clockFreq = SysCtlClockFreqSet ( SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480、 CPU_CLOCK _Hz // 120 MHz ); IF (clockFreq!= CPU_clock_Hz) { //这应该是为了处理 PLL 锁定故障。 //对于常用的 SysCtlClockFreqSet、如果是时钟、它不会被触发 //输入已死(且已绕过等待)。 在这种情况下是看门狗 //复位发生。 LogError (clock_FAIL); SystemReset(); } IF (ResetCauseIsWatchdog()) LogError (安全装置); ClearResetCaus(); DisplayLoggedErrors(); RunApplication(); }