我正在尝试使用超低功耗时钟OSCULP32K在SAM L21 Xplained Pro B中配置计数模式的RTC,使用ASF。为了测试它,我按照快速启动RTC计数轮询示例,通过将RTC计数与给定周期进行比较,每2000 ms切换一次LED0。
在该示例中,RTC_CLOCK_SOURCE使用RTC_CLOCK_SELECTION_ULP1K。当我将其更改为RTC_CLOCK_SELECTION_ULP32K时,LED每2000ms切换24次,而不是每2000 ms切换一次。
我在conf_rtc.h上有以下配置:
# define RTC_CLOCK_SOURCE RTC_CLOCK_SELECTION_ULP32K
然后,在conf_clocks.h中,我将主CPU时钟配置为4Mhz。
/* SYSTEM_CLOCK_SOURCE_OSC16M configuration - Internal 16MHz oscillator */
# define CONF_CLOCK_OSC16M_FREQ_SEL SYSTEM_OSC16M_4M
# define CONF_CLOCK_OSC16M_ON_DEMAND true
# define CONF_CLOCK_OSC16M_RUN_IN_STANDBY false
/* Configure GCLK generator 0 (Main Clock) */
# define CONF_CLOCK_GCLK_0_ENABLE true
# define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC16M
# define CONF_CLOCK_GCLK_0_PRESCALER 1
# define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false
在main.c中,我按如下方式配置和初始化rtc:
/* RTC configuration*/
void configure_rtc_count(void);
struct rtc_module rtc_instance;
// [initiate rtc]
void configure_rtc_count(void)
{
//! [set_conf]
struct rtc_count_config config_rtc_count;
//! [set_conf]
//! [get_default]
rtc_count_get_config_defaults(&config_rtc_count);
//! [get_default]
//! [set_config]
config_rtc_count.prescaler = RTC_COUNT_PRESCALER_DIV_1;
config_rtc_count.mode = RTC_COUNT_MODE_16BIT;
#ifdef FEATURE_RTC_CONTINUOUSLY_UPDATED
config_rtc_count.continuously_update = true;
#endif
config_rtc_count.compare_values[0] = 1000;
//! [set_config]
//! [init_rtc]
rtc_count_init(&rtc_instance, RTC, &config_rtc_count);
//! [init_rtc]
//! [enable]
rtc_count_enable(&rtc_instance);
//! [enable]
}
// [initiate rtc]
/* End RTC configuration*/
一个初始化,main(void)的代码读取:
int main (void)
{
system_init();
configure_rtc_count();
/*test RTC - toggle LED0 each 2000 ms*/
rtc_count_set_period(&rtc_instance, 2000);
for (;;)
{
/*test RTC - if count match, toggle LED0 each 2000 ms*/
if (rtc_count_is_compare_match(&rtc_instance, RTC_COUNT_COMPARE_0))
{
/* Do something on RTC count match here */
port_pin_toggle_output_level(LED_0_PIN);
rtc_count_clear_compare_match(&rtc_instance, RTC_COUNT_COMPARE_0);
}
/*end test RTC*/
}
}
我找不到config_rtc_count.compare_values [0] = 1000的含义的解释;我将其更改为32000,但LED不闪烁,如果我将其降低到1000以下,它会保持相同的切换速率......这是什么意思?
在像http://www.atmel.com/Images/Atmel-42471-SAM-L21-ADC-Sampling-using-Low-Power-Features_ApplicationNote_AT12705.pdf这样的例子中,似乎RTC只在conf_rtc.h中配置了#define RTC_CLOCK_SOURCE。
然而在像http://www.atmel.com/Images/Atmel-42111-SAM-RTC-Count-Driver-RTC-Count_ApplicationNote_AT03249.pdf这样的其他人中,它将GLCK 2定义为:
/* Configure GCLK generator 2 (RTC) */
# define CONF_CLOCK_GCLK_2_ENABLE true
# define CONF_CLOCK_GCLK_2_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_2_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC32K
# define CONF_CLOCK_GCLK_2_PRESCALER 32
# define CONF_CLOCK_GCLK_2_OUTPUT_ENABLE false
有谁知道如何使用ULP32k配置RTC以保持正确的计数率?
答案 0 :(得分:0)
感谢Ed King的建议,请参阅目前关于此事的调查结果:
来自Atmel Studio 7的SAM RTC计数驱动程序(轮询)(ATSAML21J18A)的快速入门,使用rtc_count_is_compare_match(&rtc_instance, RTC_COUNT_COMPARE_0)
每2000ms切换一次LED0。
为了使其在2000ms的正确时间内工作,并且如果要使用超低功耗时钟源,必须在conf_rtc.h中将RTC时钟源定义为:
# define RTC_CLOCK_SOURCE RTC_CLOCK_SELECTION_ULP1K
预分频器必须为RTC_COUNT_PRESCALER_DIV_1;
(请参阅问题中的配置)
无需在conf_clocks.h定义GLCK2。
compare_values[0] = 1000;
似乎是一种分辨率计数器,如果它低于所选择的切换周期,则LED会切换。如果它更高(例如2001年,期间为2000),那么比较似乎永远不会成立,因此LED不会切换。在任何情况下,它都不会改变切换频率。
更改rtc_count_set_period(&rtc_instance, 2000);
中的值会导致切换周期发生变化。
OSCULP32k振荡器有两种模式,一种在32kHz,另一种在1kHz。我想在这个例子中使用32kHz的时钟源,所以我改变了
# define RTC_CLOCK_SOURCE RTC_CLOCK_SELECTION_ULP32K
并尝试了不同的预分频器,但LED保持切换太快。我假设发生这种情况是因为set_period
函数需要1kHz时钟源才能以ms为单位工作,尽管更明确的解释在这里很有用。
作为结论,使用OSCULP32k的目的是降低能耗,因此我猜这个目标是使用ULP32k和ULP1k模式完全填充的。