GD32F103VE睡眠与唤醒

电源管理单元有3种省电模式:睡眠模式,深度睡眠模式和待机模式
进入睡眠模式的步骤如下:
1,配置SLEEPDEEP=0
2,执行WFI指令或执行两次WFE指令(有点奇怪,实测如此,不清楚原因),命令CPU进入深度睡眠模式。


睡眠模式的结果:
1,只是关闭Cortex-M3的内核时钟;
2,打开AHB时钟:SRAM,DMA,FMC,SysTick,SDIO
3,打开APB时钟:Timer0~Timer13,ADC,APB1外设,APB2外设;
4,IRC8M内部RC的8MHz振荡器工作;
4,HXTAL外部高速振荡器工作;
5,PLL锁相环工作;
6,IRC40K内部RC的40KHz振荡器工作,FWDGT独立看门狗定时器启动时会选择IRC40K作为时钟源;
7,LXTAL外部低速振荡器32.768Hz工作,原因是RTC产生报警会让CPU退出待机模式;
8,LDO输出1.2V

睡眠模式唤醒:
1,采用WFI_CMD进入睡眠模式,EXTI外部中断可以唤醒;
2,采用WFE_CMD进入睡眠模式,如果SEVONPEND=0,则任何事件产生中断都可以唤醒;
3,采用WFE_CMD进入睡眠模式,如果SEVONPEND=1,则任何中断都可以唤醒;

退出深度睡眠模式后,CPU使用IRC8M内部RC的8MHz振荡器;
 

 

GD32F103VE睡眠与唤醒,兆易官网给的程序没有测试。等测试后,才发现有问题。

现修改,测试如下:

#include "SleepMode.h"
#include "delay.h"

/*
电源管理单元有3种省电模式:睡眠模式,深度睡眠模式和待机模式;
进入睡眠模式的步骤如下:
1,配置SLEEPDEEP=0
2,执行WFI指令或执行两次WFE指令(有点奇怪,实测如此,不清楚原因),命令CPU进入深度睡眠模式。


睡眠模式的结果:
1,关闭Cortex-M3的内核时钟;
2,打开AHB时钟:SRAM,DMA,FMC,SysTick,SDIO
3,打开APB时钟:Timer0~Timer13,ADC,APB1外设,APB2外设
4,IRC8M内部RC的8MHz振荡器工作;
4,HXTAL外部高速振荡器工作;
5,PLL锁相环工作;
6,IRC40K内部RC的40KHz振荡器工作,FWDGT独立看门狗定时器启动时会选择IRC40K作为时钟源;
7,LXTAL外部低速振荡器32.768Hz工作,原因是RTC产生报警会让CPU退出待机模式;
8,LDO输出1.2V

EXTI触发源:I/O管脚的16根线和内部模块的4根线(包括LVD、RTC闹钟、USB唤醒、以太网唤醒)。
通过配置GPIO模块的AFIO_EXTISSx寄存器,所有的GPIO管脚都可以被选作EXTI的触发源;
EXTI可以产生中断,也产生事件信号
EXTI产生中断,EXTI向处理器提供事件信信号
睡眠模式唤醒:
1,采用WFI_CMD进入睡眠模式,任何中断可以唤醒;
2,采用WFE_CMD进入睡眠模式,如果SEVONPEND=0,则任何唤醒事件都可以唤醒;
3,采用WFE_CMD进入睡眠模式,如果SEVONPEND=1,则任何中断都可以唤醒;

退出深度睡眠模式后,CPU使用IRC8M内部RC的8MHz振荡器;
*/

u8 SleepModeFlag;

void Enter_SleepMode_Use_WFI_CMD(void);
void Enter_SleepMode0_Use_WFE_CMD(void);
void Enter_SleepMode1_Use_WFE_CMD(void);
void Enter_SLEEP_After_Interrupt(void);


//函数功能:采用WFI_CMD进入睡眠模式,任何中断可以唤醒;
//systick中断会唤醒MCU,因此,CPU进入睡眠前先关闭systick的中断;退出睡眠模式后,需要CPU再打开systick的中断
//测试OK
void Enter_SleepMode_Use_WFI_CMD(void)
{
	SleepModeFlag=0;
	SysTickInterruptDisable();//CPU进入睡眠前,需要关闭系统滴答时钟中断
	rcu_periph_clock_enable(RCU_PMU);//使能"电源管理单元时钟"
	pmu_to_sleepmode(WFI_CMD);
	//调用ARM内核指令,进入睡眠
	//通过WFI命令CPU进入睡眠
	//唤醒:任何中断均可唤醒
//	SysTickInterruptEnable();//CPU被唤醒后,要打开系统滴答时钟中断
}

//函数功能:采用WFE_CMD进入睡眠模式,如果SEVONPEND=1,则任何中断都可以唤醒;
void Enter_SleepMode0_Use_WFE_CMD(void)
{
	SysTickInterruptDisable();//CPU进入睡眠前,需要关闭系统滴答时钟中断
	rcu_periph_clock_enable(RCU_PMU);//使能RCU_PMU外设时钟
	system_lowpower_set(SCB_LPM_WAKE_BY_ALL_INT);//设置SEVONPEND=1
	SleepModeFlag=1;
	pmu_to_sleepmode(WFE_CMD);
	pmu_to_sleepmode(WFE_CMD);
	//执行两次WFE指令(有点奇怪,实测如此,不清楚原因),命令CPU进入深度睡眠模式。
	//调用ARM内核指令,进入睡眠
	//SLEEPDEEP=0,使用WFE命令使CPU进入睡眠模式,仅关闭CPU时钟
  //唤醒:若通过WFE进入,则任何事件(或SEVONPEND=1时的中断)均可唤醒,本程序使用USART0接收中断;
}

//函数功能:采用WFE_CMD进入睡眠模式,如果SEVONPEND=0,则任何事件产生中断都可以唤醒;
void Enter_SleepMode1_Use_WFE_CMD(void)
{
	SysTickInterruptDisable();//CPU进入睡眠前,需要关闭系统滴答时钟中断
	rcu_periph_clock_enable(RCU_PMU);//使能RCU_PMU外设时钟
	system_lowpower_reset(SCB_LPM_WAKE_BY_ALL_INT);//设置SEVONPEND=0
	SleepModeFlag=2;
	pmu_to_sleepmode(WFE_CMD);
	pmu_to_sleepmode(WFE_CMD);
	//执行两次WFE指令(有点奇怪,实测如此,不清楚原因),命令CPU进入深度睡眠模式。
	//调用ARM内核指令,进入睡眠
	//SLEEPDEEP=0,使用WFE命令使CPU进入睡眠模式,仅关闭CPU时钟
  //唤醒:若通过WFE进入,则任何事件(或SEVONPEND=1时的中断)均可唤醒,本程序使用外部事件唤醒;
}

//函数功能:配置中断发生后,执行完当前中断立即进入睡眠
//EXTI3中断后,进入睡眠
//EXTI7中断后,取消设置"退出中断后立即进入睡眠",同时打开系统滴答时钟中断
//测试OK
void Enter_SLEEP_After_Interrupt(void)
{
	SysTickInterruptDisable();//CPU进入睡眠前,需要关闭系统滴答时钟中断
	SleepModeFlag=3;
	rcu_periph_clock_enable(RCU_PMU);//使能"电源管理单元时钟"
	system_lowpower_set(SCB_LPM_SLEEP_EXIT_ISR);
	//SCB_LPM_SLEEP_EXIT_ISR允许"退出中断后立即进入睡眠"
	//本程序用:等待EXTI3中断后,进入睡眠
	//本程序用:等待EXTI7中断后,取消设置"退出中断后立即进入睡眠",同时打开系统滴答时钟中断
}
#include "KEY.h"
#include "SleepMode.h"
#include "delay.h"

/*
GD32F103VE外部中断线线0~15,对应外部IO口的输入中断。
它有7个中断向量,外部中断线0 ~ 4分别对应EXTI0_IRQn ~ EXTI4_IRQn中断向量;
外部中断线 5 ~ 9 共用一个 EXTI9_5_IRQn中断向量;外部中断线10~15 共用一个EXTI15_10_IRQn中断向量。
7个中断向量:EXTI0_IRQn,EXTI1_IRQn,EXTI2_IRQn, EXTI3_IRQn, EXTI4_IRQn,EXTI9_5_IRQn和EXTI15_10_IRQn。
这7个中断向量对应7个中断服务函数:
EXTI0_IRQHandler();
EXTI1_IRQHandler();
EXTI2_IRQHandler();
EXTI3_IRQHandler();
EXTI4_IRQHandler();
EXTI9_5_IRQHandler();
EXTI15_10_IRQHandler();
*/

void ExternalInterrupt3_Init(void);
void ExternalInterrupt7_Init(void);

//函数功能:初始化ExternalInterrupt3
void ExternalInterrupt3_Init(void)
{
	//NVIC_PRIGROUP_PRE4_SUB0:抢占优先级为4bit(取值为0~15),子优先级为0bit(没有响应优先级)
	//NVIC_PRIGROUP_PRE3_SUB1:抢占优先级为3bit(取值为0~7),子优先级为1bit(取值为0~1)
	//NVIC_PRIGROUP_PRE2_SUB2:抢占优先级为2bit(取值为0~3),子优先级为2bit(取值为0~3)
	//NVIC_PRIGROUP_PRE1_SUB3:抢占优先级为1bit(取值为0~1),子优先级为3bit(取值为0~7)
	//NVIC_PRIGROUP_PRE0_SUB4:抢占优先级为0bit(没有抢占优先级),子优先级为3bit(取值为0~15)
	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);//设置系统中断优先级"抢占优先级为4bit,子优先级为0bit"
  nvic_irq_enable(EXTI3_IRQn, 2U, 0U);//设置EXTI3_IRQn的中断优先级,抢占优先级为2,子优先级为0

	rcu_periph_clock_enable(RCU_GPIOE);//使能GPIOE时钟,enable GPIO clock
	rcu_periph_clock_enable(RCU_AF);   //外部中断,需要使能复用功能时钟

	gpio_init(GPIOE, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3);//将GPIOE3设置为浮空输入

	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOE, GPIO_PIN_SOURCE_3);
	//设置GE3引脚为外部中断源,select GPIO pin exti sources
  exti_init(EXTI_3, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
	//配置外部中断线使用外部中断3(EXTI_3)
	//中断模式为外部中断(EXTI_INTERRUPT)
	//中断触发方式为下降沿中断(EXTI_TRIG_FALLING)
	exti_interrupt_flag_clear(EXTI_3);//清除外部中断3标志
	exti_interrupt_enable(EXTI_3);//使能外部中断3(EXTI_3)
	exti_event_enable(EXTI_3);//使能外部事件3(EXTI_3)
}

//函数功能:初始化ExternalInterrupt7
void ExternalInterrupt7_Init(void)
{
	rcu_periph_clock_enable(RCU_GPIOE);//使能GPIOE时钟,enable GPIO clock
	rcu_periph_clock_enable(RCU_AF);//使能复用功能时钟

	gpio_init(GPIOE, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_7);//将GPIOE7设置为浮空输入

	nvic_irq_enable(EXTI5_9_IRQn, 2U, 0U);//设置EXTI5_9_IRQn的中断优先级,抢占优先级为2,子优先级为0
	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOE, GPIO_PIN_SOURCE_7);
	//设置GE7引脚为外部中断源,select GPIO pin exti sources
  exti_init(EXTI_7, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
	//配置外部中断线使用外部中断7(EXTI_7)
	//中断模式为外部中断(EXTI_INTERRUPT)
	//中断触发方式为下降沿中断(EXTI_TRIG_FALLING)
	exti_interrupt_flag_clear(EXTI_7);//清除外部中断7标志
	exti_interrupt_enable(EXTI_7);//使能外部中断7(EXTI_7)
	exti_event_enable(EXTI_7);//使能外部事件7(EXTI_7)
}

//函数功能:外部中断3的中断服务函数,外部中断0~外部中断4具有独立的中断入口地址
void EXTI3_IRQHandler(void)
{
	FlagStatus ret;

	ret=exti_interrupt_flag_get(EXTI_3);
	//读取外部中断3(EXTI_3)的中断标志
	//get EXTI lines flag when the interrupt flag is set
	if(RESET != ret)
	{
	}
	exti_interrupt_flag_clear(EXTI_3);//清除外部中断3标志
}

//this function handles external lines 5 to 9 interrupt request
//函数功能:外部中断5~外部中断9的中断服务函数
void EXTI5_9_IRQHandler(void)
{
	FlagStatus ret;

	ret=exti_interrupt_flag_get(EXTI_7);
	//读取外部中断7(EXTI_7)的中断标志
	//get EXTI lines flag when the interrupt flag is set
	if(RESET != ret)
	{
		if(SleepModeFlag==0)
		{
			SysTickInterruptEnable();//CPU被唤醒后,要打开系统滴答时钟中断
		}
		if(SleepModeFlag==1)
		{
			SysTickInterruptEnable();//CPU被唤醒后,要打开系统滴答时钟中断
		}
		if(SleepModeFlag==2)
		{
			SysTickInterruptEnable();//CPU被唤醒后,要打开系统滴答时钟中断
		}
		if(SleepModeFlag==3)
		{
			rcu_periph_clock_enable(RCU_PMU);//使能"电源管理单元时钟"
		  system_lowpower_reset(SCB_LPM_SLEEP_EXIT_ISR);
			//取消设置"退出中断后立即进入睡眠",
		}

	}
	exti_interrupt_flag_clear(EXTI_7);//清除外部中断7标志
}
#include "UART3.h"
#include "stdio.h"  //使能printf(),sprintf()

void GD32F103_UART3_Init(unsigned int bound);

//函数功能:初始化串口3,这个和STM32F103VET6的UART4兼容
void GD32F103_UART3_Init(unsigned int bound)
{
	rcu_periph_clock_enable(RCU_GPIOC); //使能GPIOC时钟,enable GPIO clock 
	rcu_periph_clock_enable(RCU_UART3); //使能UART3时钟,enable USART clock

	gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
	//将GPIOC10设置为AFIO口(复用IO口),输出上拉

	gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
	//将GPIOC11设置为浮空输入口

	usart_deinit(UART3);                         //复位UART3,USART configure

	usart_baudrate_set(UART3, bound);            //设置UART3的波特率
	usart_word_length_set(UART3, USART_WL_8BIT); //设置UART3数据传输格式为8位
	usart_stop_bit_set(UART3, USART_STB_1BIT);   //设置UART3停止位为1位
	usart_parity_config(UART3, USART_PM_NONE);   //设置UART3无需奇偶校验
	usart_hardware_flow_rts_config(UART3, USART_RTS_DISABLE); //设置不使能UART3的RTS引脚功能
	usart_hardware_flow_cts_config(UART3, USART_CTS_DISABLE); //设置不使能UART3的CTS引脚功能
	usart_receive_config(UART3, USART_RECEIVE_DISABLE);   //不使能UART3接收
	usart_transmit_config(UART3, USART_TRANSMIT_ENABLE); //使能UART3发送

//	usart_interrupt_enable(UART3, USART_INT_RBNE);
	//根据USART_INT_RBNE指定,使能串口接收寄存区为非空时产生中断
	//read data buffer not empty interrupt and overrun error interrupt
	//enable UART3 receive interrupt

/在串口中断服务函数中发送数据配置开始//
//	usart_interrupt_disable(UART3, USART_INT_TBE);
	//根据USART_INT_TBE指定,不使能串口发送缓冲区为空中断
	//Disnables Transmit Data Register empty interrupt
//	usart_interrupt_enable(UART3, USART_INT_TC);
	//根据USART_INT_TC指定,使能串口发送完成中断
	//transmission complete interrupt
/在串口中断服务函数中发送数据配置结束//

	usart_enable(UART3); //使能UART3
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
	usart_data_transmit(UART3, (uint8_t) ch);
	while( RESET == usart_flag_get(UART3, USART_FLAG_TBE) )
	{//等待串口0发送结束
	}

	return ch;
}
#include "delay.h"
// 	 
//如果需要使用OS,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS == 1
#include "FreeRTOS.h"					//FreeRTOS使用		  
#include "task.h"
#else
  #define configTICK_RATE_HZ  (1000)  //时钟节拍频率,这里设置为1000,周期就是1ms
#endif

static u8  fac_us=0;							//us延时倍乘数
#if SYSTEM_SUPPORT_OS	== 1
static u16 fac_ms=0;							//ms延时倍乘数,在ucos下,代表每个节拍的ms数
#endif	

/函数声明开始//
void delay_init(void);
void delay_ms(u32 nms);
void delay_us(u32 nus);
void delay_xms(u32 nms);
/函数声明结束//

extern void xPortSysTickHandler(void); //引用外部函数

//函数功能:SystemTimer中断服务函数,使用ucos时用到
void SysTick_Handler(void)
{
#if SYSTEM_SUPPORT_OS	== 1
    if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
    {
        xPortSysTickHandler();	
    }
#endif
}
		   
//初始化延迟函数
//SystemTimer的时钟固定为AHB时钟,这里为了兼容FreeRTOS,所以将SystemTimer的时钟频率改为AHB的频率!
//SystemTimer是一个24位的定时器
void delay_init()
{
	u32 reload;

//SystemCoreClock=108000000
	fac_us=SystemCoreClock/1000000;				//不论是否使用OS,fac_us都需要使用

	reload=SystemCoreClock/1000000;				//每秒钟需要计数的次数 
	reload*=1000000/configTICK_RATE_HZ;		//根据configTICK_RATE_HZ设定溢出时间
												//reload为24位寄存器,最大值:16777216,在108MHz下,约合0.155s左右

#if SYSTEM_SUPPORT_OS	== 1	
	fac_ms=1000/configTICK_RATE_HZ;				//代表OS可以延时的最少单位	   
#endif

  SysTick->LOAD  = reload; //每1/configTICK_RATE_HZ秒中断一次
	SysTick->VAL   = 0;      //设置SysTick计数器器初始值为0,Load the SysTick Counter Value

  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1 );
	//SysTick_IRQn=-1,设置的是Cortex-M系统中断优先级 set Priority for Systick Interrupt
	//设置SYSTICK的优先级为15

  SysTick->CTRL  |= SysTick_CTRL_CLKSOURCE_Msk; //选择内核时钟FCLK为时钟源(GD32的FCLK为108MHz)
  SysTick->CTRL  |= SysTick_CTRL_TICKINT_Msk;   //开启SysTick中断
  SysTick->CTRL  |= SysTick_CTRL_ENABLE_Msk;    //使能SysTick工作
/*	
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | //选择内核时钟FCLK为时钟源(GD32的FCLK为108MHz)
                   SysTick_CTRL_TICKINT_Msk   | //开启SysTick中断
                   SysTick_CTRL_ENABLE_Msk;     //使能SysTick工作
*/
  //NVIC_SetPriority(SysTick_IRQn, 0x00U);
	//当IRQn<0时,设置的是Cortex-M系统中断优先级
	//设置SYSTICK的优先级为0
}								    


//函数功能:精确延时延时nus微妙
//nus:要延时的us数.	
//nus:0~204522252(最大值即2^32/fac_us@fac_us=168)	    								   
void delay_us(u32 nus)
{		
	u32 ticks;
	u32 told,tnow,tcnt=0;
	u32 reload=SysTick->LOAD;	//LOAD的值	    	 
	ticks=nus*fac_us; 				//需要的节拍数 
	told=SysTick->VAL;        //刚进入时的计数器值

	while(1)
	{
		tnow=SysTick->VAL;	
		if(tnow!=told)
		{	    
			if(tnow<told)tcnt+=told-tnow;	//这里注意一下SYSTICK是一个递减的计数器就可以了.
			else tcnt+=reload-tnow+told;	    
			told=tnow;
			if(tcnt>=ticks)break;			//时间超过/等于要延迟的时间,则退出.
		}  
	}										    
}

//函数功能:精确延时nms毫秒
//nms:要延时的ms数
//nms:0~65535
void delay_ms(u32 nms)
{
#if SYSTEM_SUPPORT_OS	== 1
	if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
	{		
		if(nms>=fac_ms)						//延时的时间大于OS的最少时间周期 
		{
	    vTaskDelay(nms/fac_ms);	 		//FreeRTOS延时
		}
		nms%=fac_ms;						//OS已经无法提供这么小的延时了,采用普通方式延时    
	}
#endif
	delay_us((u32)(nms*1000));//普通方式延时
}

//函数功能:延时nms,不会引起任务调度
//nms:要延时的ms数
void delay_xms(u32 nms)
{
	u32 i;
	for(i=0;i<nms;i++) delay_us(1000);
}
#ifndef __DELAY_H
#define __DELAY_H 			   
#include "sys.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t,bool

#define SysTickInterruptEnable() SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;   //开启SysTick中断
#define SysTickInterruptDisable() SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; //关闭SysTick中断
extern void delay_init(void);
extern void delay_ms(u32 nms);
extern void delay_us(u32 nus);
extern void delay_xms(u32 nms);

#endif

main.c如下:

#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "delay.h"
#include "UART3.h"
#include "stdio.h"  //使能printf(),sprintf()

#include "KEY.h"
#include "SleepMode.h"

const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";
//PC13仅可以作为RTC功能引脚
//PC14和PC15可以作为通用I/O口或外部32.768KHz低速晶振引脚
int main(void)
{
	//MySystemClockInit(1,1);

	//NVIC_PRIGROUP_PRE4_SUB0:抢占优先级为4bit(取值为0~15),子优先级为0bit(没有响应优先级)
	//NVIC_PRIGROUP_PRE3_SUB1:抢占优先级为3bit(取值为0~7),子优先级为1bit(取值为0~1)
	//NVIC_PRIGROUP_PRE2_SUB2:抢占优先级为2bit(取值为0~3),子优先级为2bit(取值为0~3)
	//NVIC_PRIGROUP_PRE1_SUB3:抢占优先级为1bit(取值为0~1),子优先级为3bit(取值为0~7)
	//NVIC_PRIGROUP_PRE0_SUB4:抢占优先级为0bit(没有抢占优先级),子优先级为3bit(取值为0~15)
	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);//设置系统中断优先级"抢占优先级为4bit,子优先级为0bit"

  INTX_ENABLE();//开启所有中断
	GD32F103_UART3_Init(115200);//初始化UART3
	printf("%s",CPU_Reset_REG);//调试串口输出"\r\nCPU reset!\r\n"


	delay_init();//系统时钟配置

	ExternalInterrupt7_Init();//初始化ExternalInterrupt7

  Enter_SleepMode0_Use_WFE_CMD();//Cortex-M3核停止工作
//	Enter_SleepMode1_Use_WFE_CMD();//Cortex-M3核停止工作
//  Enter_SleepMode_Use_WFI_CMD();//Cortex-M3核停止工作
	while(1)//唤醒后,则执行打印
	{
	  delay_ms(500);
		printf("\r\nCortex-M3");
	}

	ExternalInterrupt3_Init();//初始化ExternalInterrupt3
  Enter_SLEEP_After_Interrupt();
//配置中断发生后,执行完当前中断立即进入睡眠
//EXTI3中断后,进入睡眠
//EXTI7中断后,取消设置"退出中断后立即进入睡眠",同时打开系统滴答时钟中断
	while(1)//唤醒后,则执行打印
	{
	  delay_ms(500);
		printf("\r\nCortex-M3");
	}
}

 

 执行两次WFE指令,有点奇怪,实测如此,不清楚原因,有知道的,请留言。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值