文章意义:
看到很多技术帖子讲述RTC定时唤醒功能的时候,老是需要去读取当前时间,再设定下一个闹钟唤醒时间,无形中多了很多变量和操作。所以我决定分享一种简单的RTC定时唤醒方法,适合于不需要实现具体时间获取的场合,仅实现RTC定时唤醒的功能。
RTC定时唤醒的意义:
电池类便携式产品一般都要求低功耗,以延长产品工作时间。电池类产品开机方式一般有按键开启(电动牙刷等)、隔空感应式开启(自动冲厕类产品等),定时开启(具备预约功能类产品)等。
单片机低功耗唤醒方式一般有两种,一种是通过按键或者外部传感器的唤醒信号进行外部中断唤醒,传感器可以实现无接触唤醒,但这要求传感器自身具备低功耗属性,即其自身具有打盹方式唤醒检测,或者其检测时仍具备低功耗属性。另一种方式为采用RTC定时唤醒(打盹方式),比如1秒内唤醒系统检测5毫秒,剩下的时间则进入低功耗模式。
接下来记录一下stm32cubemx 采用stm32f030f4单片机实现RTC定时唤醒的方法,个人认为是最简单的实现方法了:
1.打开cubemx软件,选择对应MCU,然后使能SW仿真,默认使用内部晶振:
2.选择RTC,使能时钟源、日历、闹钟(3个打钩):
3.接下来设置定时唤醒的时间,与Asynchronous Predivider value 和Synchronous Predivider value以及所使用的时钟有关,下面是一张采用不同时钟设置1秒唤醒时两个参数的配置值:
其计算方法也十分简单,比如我采用LSI内部40KHz时钟,则计算方法为:
1/(40000/128)*312=0.9984≈1秒,
所以我们只需要更改Synchronous Predivider value的值来更改定时时间就行了,比如我们需要500毫秒唤醒一次,只需要把311改为155便可以了。记住我们设置的参数要比计算参数小1才行,因为他们都是默认从1开始计数的。
这里我采用40KHz内部时钟设置1秒RTC唤醒(红箭头的参数需要注意设置为与图中一致即可):
四个使能之后闹钟在同一时刻唤醒,即实现了RTC在我们设置的时间计时到达之后便会唤醒。
4.使能RTC对应的唤醒中断:
5.设置空闲引脚高阻输入,以避免无效功耗(打钩后无配置功能的引脚则会默认为高阻输入状态):
6.设置工程名,保存工程路径,设置保存类型(我用的是keil工程),生成工程:
这样RTC唤醒功能在RTC初始化后便开始计时唤醒了,接下来我们去工程里面实现进入待机模式和RTC唤醒:
进入待机模式:
void sys_enter_standby_mode(void)
{
__HAL_RCC_PWR_CLK_ENABLE(); // 使能PWR时钟
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); // 清除唤醒标记
HAL_PWR_EnterSTANDBYMode(); //进入待机模式
}
main函数,PA4接了1个LED灯(教程没配置,需你们自行配置),程序内容为RTC初始化后便开始1秒计时,同时点亮LED灯500毫秒后进入待机模式,进入待机模式后各种变量和配置都会被清除,所以灯也会熄灭;再经过500毫秒后RTC定时唤醒时间到,系统将被唤醒然后从头开始执行,再次点亮灯,所以我们只需要看灯是否有闪烁,便知道系统是否进入了待机模式并成功实现了RTC唤醒:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC_Init();
//MX_RTC_Init();
MX_TIM3_Init();
MX_TIM14_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
MX_RTC_Init();//1s触发1次RTC唤醒中断
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
HAL_Delay(500);
sys_enter_standby_mode();
}
}
下面是我自己做的一个隔空操控的低功耗唤醒小项目,功能为每1秒唤醒5毫秒检测人手,检测到人手之后系统唤醒工作,实现从左到右挥手实现调光亮,从右到左挥手实现切换照明灯的手势识别功能,期间不再自行进入待机模式,直到人手隔空操控系统关机,则重新进入打盹模式等待唤醒工作。
**添加链接描述
有需要的可以留言一下,等下次有空的话我会再写一篇文章分享这个项目,感谢阅读!