找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 17287|回复: 2
打印 上一主题 下一主题
收起左侧

STM32F072芯片RTC周期性唤醒休眠模式的话题

[复制链接]
跳转到指定楼层
楼主
ID:98618 发表于 2015-12-8 03:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

整理:MilerShao

有人使用STM32F072芯片开发电子产品,产品需要用到STOP休眠模式,希望用RTC的周期性自动唤醒功能来唤醒芯片。他发现芯片进入STOP后根本无法通过RTC定时唤醒MCU。查看ST的官方相关估计库,似乎并没有关于RTC 定时唤醒的参考项目。

我大致找了下,ST官方好像是没有现存的关于32F0芯片 RTC定时唤醒的例程。这里一起交流下RTC 定时唤醒话题。

其实,实现这个RTC 定时唤醒还是比较简单的。这里有个可编程的可自动重装的向下计数器,按照相应的时钟频率赋予适当的值,每当向下计数到0时便产生一个唤醒标志,如果此时使能了相应的定时唤醒中断,它就可以把MCU从低功耗模式唤醒。需做如下四项基本的准备工作。

1、确定RTC时钟,即RTCCLK.可以是LSE、LSI、HSE/32其中一个。下面的例程中选用LSI.

2、为自动唤醒定时计数器选择合适的时钟源。可以是RTCCLK的2,4,8,16分频后的某一个,或者使用RTCCLK经过预分频后的秒时钟CK_SPRE。下面例程中选用RTCCLK/16作为唤醒计时器【RTC_WUTR】的时钟源。


3、结合上面选定的唤醒定时器的时钟和需要STOP休眠的时间,计算出将赋给唤醒定时器【RTC_WUTR】的重载值。比方这里以LSI/16作为定时器的计数时钟,假设定时1S,LSI的频率按40K算的话,那40k/16=2500,16进制即0x9c4.

那如果定时1S的话,赋值应该就是0X9C4.【LSI有波动,定时可能误差】

4、做好RTC周期性定时唤醒的中断配置,即NVIC配置。RTC唤醒事件是连接到EXTI 20号线。


下面是我做测试RTC 定时唤醒功能的一个简单例程,需要时可以参考。其中主程序MAIN()内容比较简单,无限循环里的内容就是LED灯先灭,进入STOP模式,1S左右后被RTC 唤醒定时器唤醒,唤醒后LED亮一会,然后再进入下一轮循环。


/*************************************************************/

int main(void)

{

GPIO_Config();

GPIO_SetBits(GPIOA, GPIO_Pin_5);

RTC_Config(); /* RTC Configuration */

WKUP_NVIC_Config(); /* EXTI LINE 20 CONFIG */

while(1)

{

GPIO_ResetBits(GPIOA, GPIO_Pin_5);

PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);

GPIO_SetBits(GPIOA, GPIO_Pin_5); /* LED1 On after wake up by RTC*/

Delay(); //LED ON for a while

}

}

/*************************************************************/

static void RTC_Config(void)

{

/* Enable the PWR clock */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

/* Allow access to RTC */

PWR_BackupAccessCmd(ENABLE);

RCC_LSICmd( ENABLE); //启动LSI


while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)

{ } /* Wait till LSi is ready */

/* Select the RTC Clock Source */

RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);//选择LSI作为RTC时钟源

/* Enable the RTC Clock */

RCC_RTCCLKCmd(ENABLE);//启动RTC

RTC_WakeUpCmd(DISABLE); //关闭RTC 唤醒定时器!!!

RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16);//醒定时器时钟

RTC_SetWakeUpCounter( 0x9c4); //RTC WAKE UP TIMER赋重装值

RTC_WakeUpCmd( ENABLE); //启动RTC 唤醒定时器


}

/********RTC wake up interrupt NVIC ********/

void WKUP_NVIC_Config(void)

{

EXTI_InitTypeDef EXTI_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;


/* Configure EXTI line 20 (connected to the RTC wakeup event) */

EXTI_ClearITPendingBit(EXTI_Line20);

EXTI_InitStructure.EXTI_Line = EXTI_Line20;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

/* NVIC configuration */

NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);


/* Enable peirodic wakeup interrupt */

RTC_ITConfig(RTC_IT_WUT, ENABLE); //

/* Clear the wakeup Pending Bit */

RTC_ClearITPendingBit(RTC_IT_WUT);

}

/****** RTC periodic wake up interrupt service routine*******/

void RTC_IRQHandler(void)

{

if (RTC_GetITStatus(RTC_IT_WUT) != RESET)

{

/* Clear RTC wake up interrupt pending bit */

RTC_ClearITPendingBit(RTC_IT_WUT);

/* Clear EXTI line20 pending bit */

EXTI_ClearITPendingBit(EXTI_Line20);

}

}

这里要提醒下,上面测试代码中的RTC_Config()配置函数里的红色语句代码经常有人漏掉,这2行对于操作RTC后备域寄存器时是必需的。

另外,RTC_WakeUpCmd(DISABLE); 这句也是必须的,否则就没法对唤醒定时器进行时钟配置和唤醒定时器赋值。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:196714 发表于 2017-5-4 22:38 | 只看该作者
折代码 根本不行,唤醒只有就死机 串口打印不出来
回复

使用道具 举报

板凳
ID:398862 发表于 2018-10-7 19:47 | 只看该作者
最讨厌教程里说这也简单那也简单!!!请问你在秀你的智商吗?是不是特有优越感?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表