处理低功耗的时候碰一个问题,在wait mode下唤醒之后需要重新设置时钟,参照官方例程中的函数 set_default_working_clock() 修改了相关参数进行设置,串口能正常打印输出了,但是定时器的计时误差巨大,每秒中的误差竟然达到了一百多毫秒,这是万万不能忍受的。
- /**
- * \brief Set default clock (MCK = 24MHz).
- */
- static void set_default_working_clock(void)
- {
- #if (SAMG)
- /* Switch MCK to slow clock */
- pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1);
- /*
- * Configure PLL and switch clock.
- * MCK = XTAL * (PLL_DEFAULT_MUL+1) / PLL_DEFAULT_DIV / MCK_DEFAULT_DIV
- * = 24 MHz
- */
- example_switch_clock(PLL_DEFAULT_MUL, PLL_COUNT, PLL_DEFAULT_DIV,
- MCK_DEFAULT_DIV);
- #else
- /* Switch MCK to slow clock */
- pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1);
- /* Switch mainck to external xtal */
- pmc_switch_mainck_to_xtal(0, BOARD_OSC_STARTUP_US);
- /*
- * Configure PLL and switch clock.
- * MCK = XTAL * (PLL_DEFAULT_MUL+1) / PLL_DEFAULT_DIV / MCK_DEFAULT_DIV
- * = 24 MHz
- */
- example_switch_clock(PLL_DEFAULT_MUL, PLL_COUNT, PLL_DEFAULT_DIV,
- MCK_DEFAULT_DIV);
- /* Disable unused clock to save power */
- pmc_osc_disable_fastrc();
- #endif
- /* Save current clock */
- #if SAMG55
- g_ul_current_mck = 48000000; /* 48MHz */
- #else
- g_ul_current_mck = 24000000; /* 24MHz */
- #endif
- }
这就是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,重新测试,终于得到完美时钟:
这样子系统工作时钟算是没有问题了,但是RTT休眠时钟还是不行,误差也是一百多毫秒每秒。现在板子上没有32K晶振,等下个版本有了晶振再测试一下。