本帖最后由 正点原子运营 于 2024-4-19 11:07 编辑
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板
2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版
6)正点原子STM32技术交流QQ群:725095144
本章介绍STM32F103低功耗模式中的睡眠模式,通过调用WFI命令进入睡眠模式后,ARM Corten-M3内核将停止以降低功耗,在该睡眠模式下可以被任意中断唤醒。通过本章的学习,读者将学习到低功耗模式中睡眠模式的使用。 本章分为如下几个小节: 29.1 硬件设计 29.2 程序设计 29.3 下载验证
29.1 硬件设计 29.1.1 例程功能 1. TFTLCD上显示实验信息 2. LED0闪烁时,按下KEY0按键后,LED1亮起,LED0停止闪烁 3. LED0停止闪烁时,按下WKUP按键后,LED1熄灭,LED0闪烁
29.1.2 硬件资源 1. LED LED0 - PB5 LED1 - PE5 2. 正点原子2.8/3.5/4.3/7/10寸TFTLCD模块 3. 按键 WKUP - PA0 KEY0 - PE4
29.1.3 原理图 本章实验介绍STM32F103低功耗模式中的睡眠模式,不涉及连接原理图。
29.2 程序设计 29.2.1 HAL库的PWR驱动 HAL库中提供了配置进入睡眠模式的驱动函数,其配置步骤如下: ①:进入睡眠模式 在HAL库中对应的驱动函数如下: ①:进入睡眠模式 该函数用于进入睡眠模式,其函数原型如下所示: - void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry);
复制代码该函数的形参描述,如下表所示: 表29.2.1.1 函数HAL_PWR_EnterSLEEPMode()形参描述 该函数的返回值描述,如下表所示: 表29.2.1.2 函数HAL_PWR_EnterSLEEPMode()返回值描述 该函数的使用示例,如下所示: - #include "stm32f1xx_hal.h"
- void example_fun(void)
- {
- /* 进入睡眠模式*/
- HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
- }
复制代码29.2.2PWR驱动 本章实验的PWR驱动主要负责向应用层提供睡眠模式唤醒按键的初始化和进入睡眠模式的函数,同时实现唤醒按键的中断回调函数。本章实验中,PWR的驱动代码包括pwr.c和pwr.h两个文件。 PWR驱动中,睡眠模式唤醒按键的相关宏定义,如下所示: - #define PWR_WKUP_INT_GPIO_PORT GPIOA
- #define PWR_WKUP_INT_GPIO_PIN GPIO_PIN_0
- #define PWR_WKUP_INT_GPIO_CLK_ENABLE() \
- do { \
- __HAL_RCC_GPIOA_CLK_ENABLE(); \
- }while (0)
- #define PWR_WKUP_INT_IRQn EXTI0_IRQn
- #define PWR_WKUP_INT_IRQHandler EXTI0_IRQHandler
复制代码PWR驱动中,睡眠模式唤醒按键的初始化函数,如下所示: - /**
- *@brief 进入睡眠模式
- *@param 无
- *@retval 无
- */
- voidpwr_enter_sleep(void)
- {
- GPIO_InitTypeDef gpio_init_struct = {0};
-
- __HAL_RCC_PWR_CLK_ENABLE();
- PWR_WKUP_INT_GPIO_CLK_ENABLE();
-
- HAL_NVIC_SetPriority(PWR_WKUP_INT_IRQn, 0, 0);
- HAL_NVIC_EnableIRQ(PWR_WKUP_INT_IRQn);
-
- /* 配置唤醒引脚 */
- gpio_init_struct.Pin = PWR_WKUP_INT_GPIO_PIN;
- gpio_init_struct.Mode = GPIO_MODE_IT_RISING;
- gpio_init_struct.Pull = GPIO_PULLDOWN;
- gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(PWR_WKUP_INT_GPIO_PORT, &gpio_init_struct);
-
- /* 关闭SysTick中断 */
- SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
-
- /* 进入睡眠模式 */
- HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
- }
复制代码因为进入睡眠模式后,能够被任意的中断唤醒,因此睡眠模式唤醒按键的初始化只需要配置好按键的外部中断即可。 PWR驱动中,睡眠模式唤醒按键对应的中断回调函数,如下所示: - /**
- *@brief HAL库外部中断中断回调函数
- *@param 无
- *@retval 无
- */
- voidHAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
- {
- if (GPIO_Pin ==PWR_WKUP_INT_GPIO_PIN)
- {
- /* 重新开启SysTick中断 */
- SysTick->CTRL |=SysTick_CTRL_TICKINT_Msk;
- }
- }
复制代码因为睡眠唤醒按键的中断只是为了唤醒睡眠模式,因此并不需要作太多事务,仅需将SysTick的中断重新打开,保证HAL库能正常运行即可。
29.2.3 实验应用代码 本章实验的应用代码,如下所示: - int main(void)
- {
- uint8_t t = 0;
- uint8_t key;
-
- HAL_Init(); /* 初始化HAL库 */
- sys_stm32_clock_init(RCC_PLL_MUL9); /* 配置时钟,72MHz */
- delay_init(72); /* 初始化延时 */
- usart_init(115200); /* 初始化串口 */
- led_init(); /* 初始化LED */
- key_init(); /* 初始化按键 */
- lcd_init(); /* 初始化LCD */
-
- lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
- lcd_show_string(30, 70, 200, 16, 16, "SLEEPTEST", RED);
- lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
-
- lcd_show_string(30, 110, 200, 16, 16, "KEY0:EnterSLEEP MODE", RED);
- lcd_show_string(30, 130, 200, 16, 16, "KEY_UP:ExitSLEEP MODE", RED);
-
- while (1)
- {
- key = key_scan(0);
- if (key == KEY0_PRES)
- {
- /* 按下KEY0按键,开启LED1后进入睡眠模式 */
- LED1(0);
- pwr_enter_sleep();
- LED1(1);
- }
-
- if (++t == 20)
- {
- t = 0;
- LED0_TOGGLE();
- }
-
- delay_ms(10);
- }
- }
复制代码从上面的代码中可以看出,在完成相关的初始化操作后,并不断地扫描按键,若扫描到KEY0按键被按下,则会点亮LED1后进入睡眠模式,此时ARM Cortex-M3内核便停止了,从该睡眠模式唤醒需要有任意的中断产生,因此可以由WKUP按键产生外部中断来唤醒睡眠。退出睡眠模式后,LED1将被熄灭。
29.3 下载验证 在完成编译和烧录操作后,可以看到LED0闪烁提示系统程序正在运行,此时可以按下KEY0按键,可以看到LED1亮起,但LED0不再闪烁,这是因为系统已经进入睡眠模式了,此时再按下WKUP按键,即可从睡眠模式下唤醒,可以看到LED1熄灭,LED0继续闪烁。 |