折騰了一天,靜下來把整個過程理理。 架構
本次軟件運行ARM-Context3架構STM32F103XXX spa
項目需求:系統在某個條件下進入省電模式,能夠經過外部信號喚醒:1、外部震動傳感器,1、串口 設計
當前也有省電模式,但直接進入了待機省電模式,在該模式下只能經過震動傳感器喚醒,沒法經過串口喚醒。要同時知足震動傳感器以及串口喚醒,在現有方案上有兩種方式: 接口
-、將串口的發送信號(ARM的接收)經過電子開關接到外部震動傳感器的輸入端 事件
-、省電模式改爲串口可喚醒的停機模式 ip
第一種方式硬件改動比較大,第二種方式則只須要修改軟件。決定:升級軟件 it
停機模式(STOP) io
有兩種方式進入STOP,-、中斷喚醒方式 -、事件喚醒方式,根據需求採用方式一 軟件
退出STOP時直接從進入STOP的下一條指令開始運行,SRAM中的數據保留 配置
進入STOP
首先須要設置好外部中斷,這裏有兩個外部中斷,代碼以下:
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource10);
//PA0配置
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿觸發
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//外部中斷0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//搶佔優先級爲2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //從優先級 爲1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//PA10配置
EXTI_InitStructure.EXTI_Line = EXTI_Line10;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//外部中斷0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //從優先級 爲2
NVIC_Init(&NVIC_InitStructure);
中斷初始化完成後,就須要完成中斷服務程序,以下:
void EXTI0_IRQHandler(void){
if(EXTI_GetITStatus(EXTI_Line0) != RESET){
EXTI_ClearITPendingBit(EXTI_Line0);
EXTI_ClearFlag(EXTI_Line0);
}
}
//中斷服務程序中彷佛什麼也沒作,但EXTI_GetITStatus這幾個接口必須有,不然沒法喚醒
完成這些後就能夠進入STOP了
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
至於喚醒後該如何作,是要從新初始化仍是乾脆從新啓動這就由設計人員自行決定了