接上一篇的问题
DeepSleep 状态下能否用RTC来唤醒呢?
先来看一个问题,
前面介绍说,DeepSleep模式下只能
EXTI的中断或者事件来唤醒
问题来了,为什么只能通过EXTI的中断或者事件来唤醒?
EXTI何方神圣?
就是个中断控制器,Cortex M内核 集成了这个东西,哦,不,Cortex M 集成了叫NVIC的东西 (嵌套式矢量型中断控制器)。
而EXTI主要是处理来自于IO管脚(0~15)的16个中断(PA0~PA15,PB0~PB15.....)
除此之外,好像EXTI有多余的脚,不用白不用(是否是因为有多余的脚才引出的下文是我YY的)
EXTI还接收来自LVD,RTC闹钟,USBFSFS的中断。
注意了,敲下黑板,是RTC闹钟,不是特么的RTC秒中断。
再敲下黑板,RTC闹钟接在EXTI中断线上,啥,想想我之前利用按键尝试可以在deep sleep模式下唤醒,而且spec也说了,可以通过EXTI来唤醒deep sleep。那这次就可以用RTC的闹钟中断来唤醒deep sleep喽?
搞一搞,搞一搞。
首先设能RTC闹钟中断
其次初始化RTC闹钟对应在EXTI上的中断
然后设置RTC闹钟
最后等待中断
OK,哇,可以了。终于产生中断了。。。。终于唤醒deep sleep了。。。。
呵呵呵,YY中
关于RTC的设置
还是官方的例子,里面有设置RTC闹钟中断使能的,自己找找,只要眼球和眼角膜还在,可以看得到的
void rtc_configuration(void)
{
/* enable PMU and BKPI clocks */
rcu_periph_clock_enable(RCU_BKPI);
rcu_periph_clock_enable(RCU_PMU);
/* allow access to BKP domain */
pmu_backup_write_enable();
/* reset backup domain */
bkp_deinit();
/* enable LXTAL */
rcu_osci_on(RCU_LXTAL);
/* wait till LXTAL is ready */
rcu_osci_stab_wait(RCU_LXTAL);
/* select RCU_LXTAL as RTC clock source */
rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
/* enable RTC Clock */
rcu_periph_clock_enable(RCU_RTC);
/* wait for RTC registers synchronization */
rtc_register_sync_wait();
/* wait until last write operation on RTC registers has finished */
rtc_lwoff_wait();
/* enable the RTC second and alarm interrupt*/
rtc_interrupt_enable(RTC_INT_SECOND);
rtc_interrupt_enable(RTC_INT_ALARM);
/* wait until last write operation on RTC registers has finished */
rtc_lwoff_wait();
/* set RTC prescaler: set RTC period to 1s */
rtc_prescaler_set(32767);
/* wait until last write operation on RTC registers has finished */
rtc_lwoff_wait();
}
初始化RTC闹钟对应在EXTI上的中断
/*
; 57:RTC Alarm
*/
void rtc_alarm_exti_init(void)
{
/* enable and set EXTI interrupt to the lowest priority */
nvic_irq_enable(RTC_ALARM_IRQn, 2U, 0U);
/* configure EXTI line */
exti_init(EXTI_17, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(EXTI_17);
//exti_interrupt_enable(EXTI_17);
}
设置闹钟 10s "闹" 一下
#define DELAY_SECOND 10
void set_rtc_alarm(void)
{
uint32_t current_counter = 0, max_counter = 0, alarm_counter = 0, year = 0;;
current_counter = rtc_counter_get();
year = (current_counter >> 25) + MIN_YEAR;
max_counter = IS_LEAP_YEAR(year) ? (366 * 24 * 3600) : (365 * 24 * 3600);
/* calculate the alarm_counter = current_counter + 10 second */
if(((current_counter & 0x01FFFFFF) + DELAY_SECOND) < max_counter){
alarm_counter = current_counter + DELAY_SECOND;
}else{
year++;
if(year > MAX_YEAR){
year = MIN_YEAR;
}
alarm_counter = ((year - MIN_YEAR) << 25) + (((current_counter & 0x01FFFFFF) + 10) - max_counter);
}
/* set the alarm_counter */
rtc_lwoff_wait();
rtc_alarm_config(alarm_counter);
rtc_lwoff_wait();
}
简单的测试程序
while(1){
set_rtc_alarm();
dw_deep_sleep_mode();
printf("next...\n");
}
每次闹钟时间到了之后,需要重新设置一下alarm ----set_rtc_alarm()
OK 结束!