1.基礎(chǔ)介紹?
1-1:單片機(jī)的“低功耗模式”,像是手機(jī)的待機(jī)模式,不同于正常運(yùn)行模式,處于一種省電省資源的狀態(tài)
1-2:在運(yùn)行情況下,HCLK為cpu提供時(shí)鐘,cortex-m3內(nèi)核執(zhí)行程序的代碼,如果處于中斷事件的等待時(shí),可以進(jìn)入低功耗模式用來節(jié)省資源等
1-3:STM32一共有著3個(gè)低功耗模式
(1)睡眠模式(cm3內(nèi)核停止,外設(shè)時(shí)鐘等依舊運(yùn)行)
(2)停止模式(所有的時(shí)鐘)
(3)待機(jī)模式(1.8V內(nèi)核電源關(guān)閉)
1-4:具體介紹(引自正點(diǎn)原子參考手冊)
?2.配置方式
2-1:進(jìn)入待機(jī)模式函數(shù)
配置時(shí)鐘+設(shè)置喚醒源+待機(jī)模式設(shè)置
void Sys_Standby(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PWR外設(shè)時(shí)鐘
PWR_WakeUpPinCmd(ENABLE); //使能喚醒管腳功能,在WkUp的上升沿進(jìn)行
PWR_EnterSTANDBYMode(); //進(jìn)入待機(jī)(STANDBY)模式 設(shè)置相應(yīng)的進(jìn)入條件(已經(jīng)封裝成了完整的函數(shù))
}
?一般而言,進(jìn)入待機(jī)模式的函數(shù)已經(jīng)封裝成了具體的函數(shù),拆開來看:
1.清除Wk_up位
2.設(shè)置PWR_CR位使得CPU進(jìn)入深度睡眠時(shí)又進(jìn)入待機(jī)模式
3.設(shè)置PDDS位CPU設(shè)置深度睡眠模式時(shí)進(jìn)入待機(jī)模式
4.__WFI指令
void PWR_EnterSTANDBYMode(void)
{
/* Clear Wake-up flag */
PWR->CR |= PWR_CR_CWUF;
/* Select STANDBY mode */
PWR->CR |= PWR_CR_PDDS;
/* Set SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR |= SCB_SCR_SLEEPDEEP;
/* This option is used to ensure that store operations are completed */
#if defined ( __CC_ARM )
__force_stores();
#endif
/* Request Wait For Interrupt */
__WFI();
}
4.以Wkup上升沿為喚醒條件,設(shè)置中斷配置函數(shù)
oid EXTI0_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中斷標(biāo)志位
if(Check_WKUP())//關(guān)機(jī)?
{
Sys_Enter_Standby();
}
}
5.代碼:實(shí)現(xiàn)按鈕3s開機(jī),按鈕3s關(guān)機(jī),就像手機(jī)的開關(guān)機(jī)一樣
#include "wkup.h"
#include "led.h"
#include "delay.h"
//待機(jī)模式
//1.設(shè)置時(shí)鐘
//2.設(shè)置喚醒條件
//3.設(shè)置進(jìn)入條件
void Sys_Standby(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PWR外設(shè)時(shí)鐘
PWR_WakeUpPinCmd(ENABLE); //使能喚醒管腳功能,在WkUp的上升沿進(jìn)行
PWR_EnterSTANDBYMode(); //進(jìn)入待機(jī)(STANDBY)模式 設(shè)置相應(yīng)的進(jìn)入條件(已經(jīng)封裝成了完整的函數(shù))
}
//系統(tǒng)進(jìn)入待機(jī)模式
//1.復(fù)位所有的io
//2.待機(jī)模式設(shè)置
void Sys_Enter_Standby(void)
{
RCC_APB2PeriphResetCmd(0x01fc,DISABLE);//復(fù)位
Sys_Standby();//啟動(dòng)待機(jī)模式
}
//檢測WKUP腳的信號(hào)
//返回值1:連續(xù)按下3s以上
// 0:錯(cuò)誤的觸發(fā),進(jìn)入待機(jī)模式
u8 Check_WKUP(void)
{
u8 t=0; //記錄按下的時(shí)間
LED0=0; //亮燈DS0
while(1)
{
if(WKUP_KD)//判斷按下的時(shí)間
{
t++; //已經(jīng)按下了
delay_ms(30);
if(t>=100) //按下超過3秒鐘
{
LED0=0; //點(diǎn)亮DS0
return 1; //按下3s以上了
}
}else
{
LED0=1;
return 0; //按下不足3秒
}
}
}
//中斷,檢測到PA0腳的一個(gè)上升沿.
//中斷線0線上的中斷檢測
void EXTI0_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中斷標(biāo)志位
if(Check_WKUP())//關(guān)機(jī)?
{
Sys_Enter_Standby();
}
}
//PA0 WKUP喚醒初始化
void WKUP_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);//使能GPIOA和復(fù)用功能時(shí)鐘
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0; //PA.0
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD;//上拉輸入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO
//使用外部中斷方式
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //中斷線0連接GPIOA.0
EXTI_InitStructure.EXTI_Line = EXTI_Line0; //設(shè)置按鍵所有的外部線路
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //設(shè)外外部中斷模式:EXTI線路為中斷請求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿觸發(fā)
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); // 初始化外部中斷
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按鍵所在的外部中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占優(yōu)先級2級
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //從優(yōu)先級2級
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道
NVIC_Init(&NVIC_InitStructure); //根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器
if(Check_WKUP()==0) Sys_Standby(); //不是開機(jī),進(jìn)入待機(jī)模式
}
main函數(shù)
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "wkup.h"
int main(void)
{
delay_init(); //延時(shí)函數(shù)初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設(shè)置中斷優(yōu)先級分組為組2:2位搶占優(yōu)先級,2位響應(yīng)優(yōu)先級
uart_init(115200); //串口初始化為115200
LED_Init(); //LED端口初始化
WKUP_Init(); //待機(jī)喚醒初始化
LCD_Init(); //LCD初始化
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"Elite STM32");
LCD_ShowString(30,70,200,16,16,"WKUP TEST");
LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,110,200,16,16,"2015/1/14");
while(1)
{
LED0=!LED0;
delay_ms(250);
}
}
我們來講一下mian函數(shù)的執(zhí)行過程
首先是mian函數(shù)執(zhí)行到WKUP_Init()函數(shù),這個(gè)時(shí)候如果按下按鍵,那么就會(huì)喚醒開機(jī),但是由于我們規(guī)定的函數(shù)??if(Check_WKUP()==0) Sys_Standby()? 所以必須要長按,才能起到喚醒單片機(jī)的作用。當(dāng)長按的時(shí)候,這個(gè)時(shí)候就不會(huì)執(zhí)行if(Check_WKUP()==0) Sys_Standby(),那么啟動(dòng)單片機(jī)
當(dāng)啟動(dòng)單片機(jī)但是按下按鍵的時(shí)候,這個(gè)時(shí)候就會(huì)滿足中斷函數(shù)當(dāng)中的要求文章來源:http://www.zghlxwxcb.cn/news/detail-602528.html
void EXTI0_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中斷標(biāo)志位
if(Check_WKUP())
{
Sys_Enter_Standby();
}
}
這個(gè)時(shí)候就能進(jìn)入待機(jī)系統(tǒng),然后單片機(jī)進(jìn)入待機(jī)狀態(tài)文章來源地址http://www.zghlxwxcb.cn/news/detail-602528.html
到了這里,關(guān)于Stm32待機(jī)模式的進(jìn)入與喚醒的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!