股票

SAM4S时钟重新设置后不准确的问题

处理低功耗的时候碰一个问题,在wait mode下唤醒之后需要重新设置时钟,参照官方例程中的函数 set_default_working_clock() 修改了相关参数进行设置,串口能正常打印输出了,但是定时器的计时误差巨大,每秒中的误差竟然达到了一百多毫秒,这是万万不能忍受的。

  1. /**
  2.  * \brief Set default clock (MCK = 24MHz).
  3.  */
  4. static void set_default_working_clock(void)
  5. {
  6. #if (SAMG)
  7.     /* Switch MCK to slow clock  */
  8.     pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1);
  9.     /*
  10.      * Configure PLL and switch clock.
  11.      * MCK = XTAL * (PLL_DEFAULT_MUL+1) / PLL_DEFAULT_DIV / MCK_DEFAULT_DIV
  12.      *     = 24 MHz
  13.      */
  14.     example_switch_clock(PLL_DEFAULT_MUL, PLL_COUNT, PLL_DEFAULT_DIV,
  15.             MCK_DEFAULT_DIV);
  16. #else
  17.     /* Switch MCK to slow clock  */
  18.     pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1);
  19.     /* Switch mainck to external xtal */
  20.     pmc_switch_mainck_to_xtal(0, BOARD_OSC_STARTUP_US);
  21.     /*
  22.      * Configure PLL and switch clock.
  23.      * MCK = XTAL * (PLL_DEFAULT_MUL+1) / PLL_DEFAULT_DIV / MCK_DEFAULT_DIV
  24.      *     = 24 MHz
  25.      */
  26.     example_switch_clock(PLL_DEFAULT_MUL, PLL_COUNT, PLL_DEFAULT_DIV,
  27.             MCK_DEFAULT_DIV);
  28.     /* Disable unused clock to save power */
  29.     pmc_osc_disable_fastrc();
  30. #endif
  31.     /* Save current clock */
  32. #if SAMG55
  33.     g_ul_current_mck = 48000000; /* 48MHz */
  34. #else
  35.     g_ul_current_mck = 24000000; /* 24MHz */
  36. #endif
  37. }

这就是ASF中的示例函数,用在SAM4S16C开发板上,板载时钟是12M,而我的板子时钟是4M,于是我把PLL_DEFALUT_MUL倍乘参数改为23,其余不变。输出是正常的,但是就是时间严重不准确。并且时间还变慢了,原来1s的定时延长到了3s,这可不是板子晶振换成了4M的问题,而是使用开发板也是这个情况!

既然都错了,我就尝试进行修改。先把 PLL_DEFALUT_MUL 倍乘参数改为29, 把 MCK_DEFAULT_DIV 分频参数 改为不分频,这样 (29+1)x4M/1/1=120M,再把下面的传递参数 g_ul_current_mck  改为120M,重新测试,终于得到完美时钟:

SAM4S时钟重新设置后不准确的问题

这样子系统工作时钟算是没有问题了,但是RTT休眠时钟还是不行,误差也是一百多毫秒每秒。现在板子上没有32K晶振,等下个版本有了晶振再测试一下。

打赏
原文链接:,转发请注明来源!

发表评论