STM32F030低功耗之停机模式的进入和唤醒

本人使用的是STM32F030F4P6进行从机低功耗的设计。设计需求是和主机进行状态同步,主机超时不从串口给回馈(主机关机了)从机进入停机模式等待串口来数据进行唤醒(主机开机了)。

1.停机模式介绍

STM32F030F4P6有三个低功耗模式。待机模式下(standby)功耗最低但是需要wake_up引脚上升沿或者RTC闹钟才能进行唤醒,在硬件已经设计好的基础上不满足本次软件设计的需求。然后考虑功耗第二低的停机模式(stop),刚好停机模式能够被任一外部中断包括串口中断进行唤醒。

STM32F030低功耗之停机模式的进入和唤醒_第1张图片

2.停机模式的进入

停机模式的进入由数据手册可知,需要将SLEEPDEEP寄存器置1,PDDS寄存器置0,还要设置PWR->CR位。这些操作在库函数的PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);里面已经封装好了,直接调用即可。调用该函数时需要选择是WFI模式还是WFE模式,关于这两个模式的区别在数据手册中有介绍,个人理解的是WFI模式进入之后如果需要串口唤醒则需要将串口接收引脚配置为外部中断(之前是串口中断)。

STM32F030低功耗之停机模式的进入和唤醒_第2张图片

封装的进入停机模式的函数,调用即可进入停机模式。

void enter_stop_mode(void)//进入停止模式
{
	EXIT_UART_Init();//RX引脚配置为外部中断
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR , ENABLE);//开电源管理时钟
	PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);//进入停机模式
}

配置串口RX引脚为外部中断,若没有此配置,串口中断将无法唤醒单片机。

void EXIT_UART_Init(void)
{
	GPIO_InitTypeDef   GPIO_InitStructure; 
    USART_InitTypeDef  USART_InitStruct;
    NVIC_InitTypeDef   NVIC_InitStructure;
	EXTI_InitTypeDef EXTI_InitStruct;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入模式
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 
    GPIO_Init(GPIOA, &GPIO_InitStructure);

	NVIC_InitStructure.NVIC_IRQChannel = EXTI4_15_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource10);
	EXTI_InitStruct.EXTI_Line = EXTI_Line10;
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿中断
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStruct); 
}

3.停机模式的唤醒

停机模式下中断唤醒的程序入口在EXTI4_15_IRQHandler();函数里面。中断唤醒之后系统默认使用内部时钟,没有经过倍频,串口波特率也不正常,若唤醒之后希望程序继续运行需要重新初始化系统时钟和串口。本设计需要和主机保持状态一致,停机模式的唤醒都是因为主机开机了,从机也需要重启一下。所以一旦发生停机唤醒事件,直接软件复位,重新开始程序。

void EXTI4_15_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line10) != RESET)
  {
    EXTI_ClearITPendingBit(EXTI_Line7);
	NVIC_SystemReset();//复位重启
  }
}

总结一下,如果需要使用串口唤醒停机模式,一定注意以下两点!

1.进入停机模式时一定需要将串口接收引脚定义为外部中断。

2.停机唤醒之后需要重新配置时钟和初始化串口。

你可能感兴趣的:(STM32F030低功耗之停机模式的进入和唤醒)