折腾了一天,静下来把整个过程理理。 架构
本次软件运行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);
至于唤醒后该如何作,是要从新初始化仍是干脆从新启动这就由设计人员自行决定了