由于内部RC震荡的误差实在太大,每秒的误差竟然能达到100+ms,实在受不了,于是寻求使用外部晶振来提高时钟的精度。在网上查了一圈,愣是没找到一个有用的参考,问了下Atmel的技术人员,说可以使用外部晶振,于是我就从ASF的例程中看看有没有帮助的地方。
先查看时钟配置函数 sysclk_init(),里面有个判断
- else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_XTAL) {
- osc_enable(OSC_SLCK_32K_XTAL);
- osc_wait_ready(OSC_SLCK_32K_XTAL);
- pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);
- }
看字面意思就知道,配置时钟如果是外部慢时钟,就使用以下方法云云,一共三个函数,pmc_switch_mck_to_sclk已经使用过了,在进入休眠模式时,用来切换主时钟的,那剩余两个就是初始化外部晶振让它起振了。把这两个函数拷贝到RTT初始化函数中,再把RTT时钟源函数rtt_sel_source(RTT, false)中的false改为true。这里具体我没细查,原来参数是false时,使用的是RTC时钟,现在改为true,使用的就是外部晶振了。
附RTT初始化函数:
- void configure_rtt(void)
- {
- uint32_t ul_previous_time;
- osc_enable(OSC_SLCK_32K_XTAL);
- osc_wait_ready(OSC_SLCK_32K_XTAL);
- //pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);
- // Configure RTT for a 1 second tick interrupt
- rtt_sel_source(RTT, true);
- rtt_init(RTT, 32768);
- ul_previous_time = rtt_read_timer_value(RTT);
- while(ul_previous_time == rtt_read_timer_value(RTT));
- // Enable RTT interrupt
- NVIC_DisableIRQ(RTT_IRQn);
- NVIC_ClearPendingIRQ(RTT_IRQn);
- NVIC_SetPriority(RTT_IRQn, 0);
- NVIC_EnableIRQ(RTT_IRQn);
- rtt_enable_interrupt(RTT, RTT_MR_RTTINCIEN);
- }