很多单片机都有低功耗模式, STM32 也不例外。在系统或电源复位以后,微控制器处于运行状态。运行状态下的 HCLK 为 CPU 提供时钟,内核执行程序代码。当 CPU 不需继续运行时,可以利用多个低功耗模式来节省功耗,例如等待某个外部事件时。用户需要根据最低电源消耗,最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。
#include "wkup.h" //待命模式 void Sys_Standby(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能 PWR外设时钟 PWR_WakeUpPinCmd(ENABLE); //使能唤醒管脚功能 PWR_EnterSTANDBYMode(); //进入待命( STANDBY)模式 } //系统进入待机模式 void Sys_Enter_Standby(void) { RCC_APB2PeriphResetCmd(0X01FC,DISABLE); //复位所有 IO 口 Sys_Standby(); } //检测 WKUP 脚的信号 //返回值 1:连续按下 3s 以上 // 返回值 0:错误的触发 u8 Check_WKUP(void) { u8 t=0; LED0=0; while(1) { if(WKUP_KD) { t++; delay_ms(30); if(t>=100) { LED0=0; return 1; } } else { LED0=1; return 0; } } } void EXTI0_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line0);// 清除 LINE10 上的中断标志位 if(Check_WKUP()) { Sys_Enter_Standby(); } } void WKUP_Init(void) { GPIO_InitTypeDef GPIO_ist; NVIC_InitTypeDef NVIC_ist; EXTI_InitTypeDef EXTI_ist; //使能GPIOA和复用功能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); GPIO_ist.GPIO_Pin=GPIO_Pin_0;//PA0 GPIO_ist.GPIO_Mode =GPIO_Mode_IPD;//下拉输入 GPIO_Init(GPIOA,&GPIO_ist); //中断线 0 连接 GPIOA.0 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); EXTI_ist.EXTI_Line=EXTI_Line0; EXTI_ist.EXTI_Mode= EXTI_Mode_Interrupt; EXTI_ist.EXTI_Trigger=EXTI_Trigger_Rising; EXTI_ist.EXTI_LineCmd= ENABLE; EXTI_Init(&EXTI_ist);//初始化外部中断 NVIC_ist.NVIC_IRQChannel=EXTI0_IRQn; NVIC_ist.NVIC_IRQChannelPreemptionPriority=2; NVIC_ist.NVIC_IRQChannelSubPriority=2; NVIC_ist.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_ist); if(!Check_WKUP())Sys_Standby(); }
void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) { /* Check the parameters */ assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); assert_param(IS_FUNCTIONAL_STATE(NewState)); if (NewState != DISABLE) { RCC->APB2RSTR |= RCC_APB2Periph; } else { RCC->APB2RSTR &= ~RCC_APB2Periph; } }
#ifndef _WKUP_H #define _WKUP_H #include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #define WKUP_KD PAin(0)//PA0 检测是否外部 WK_UP 按键按下 u8 Check_WKUP(void);//检测 WKUP 脚的信号 void WKUP_Init(void);//PA0 WKUP 唤醒初始化 void Sys_Enter_Standby(void);//系统进入待机模式 #endif
#include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "lcd.h" #include "usmart.h" #include "rtc.h" #include "wkup.h" void init(void) { NVIC_Configuration(); delay_init(); uart_init(9600); LED_Init(); LCD_Init(); WKUP_Init(); usmart_dev.init(72);//初始化SMART组件 } int main(void) { u8 t; init(); POINT_COLOR=RED; while(RTC_Init()) //RTC初始化 ,一定要初始化成功 { LCD_ShowString(60,130,200,16,16,"RTC ERROR! "); delay_ms(800); LCD_ShowString(60,130,200,16,16,"RTC Trying..."); } //显示时间 POINT_COLOR=BLUE;//设置字体为蓝色 LCD_ShowString(60,130,200,16,16," - - "); LCD_ShowString(60,162,200,16,16," : : "); while(1) { if(t!=calendar.sec) { t=calendar.sec; LCD_ShowNum(60,130,calendar.w_year,4,16); LCD_ShowNum(100,130,calendar.w_month,1,16); LCD_ShowNum(124,130,calendar.w_date,2,16); switch(calendar.week) { case 0: LCD_ShowString(60,148,200,16,16,"Sunday "); break; case 1: LCD_ShowString(60,148,200,16,16,"Monday "); break; case 2: LCD_ShowString(60,148,200,16,16,"Tuesday "); break; case 3: LCD_ShowString(60,148,200,16,16,"Wednesday"); break; case 4: LCD_ShowString(60,148,200,16,16,"Thursday "); break; case 5: LCD_ShowString(60,148,200,16,16,"Friday "); break; case 6: LCD_ShowString(60,148,200,16,16,"Saturday "); break; } LCD_ShowNum(60,162,calendar.hour,2,16); LCD_ShowNum(84,162,calendar.min,2,16); LCD_ShowNum(108,162,calendar.sec,2,16); LED0=!LED0; } delay_ms(10); } }
cortex_m3_stm32嵌入式学习笔记(十五):待机唤醒实验(WK_UP外部中断)
原文地址:http://blog.csdn.net/qq_16255321/article/details/43086403