STM32低功耗模式测试

stm32单片机低功耗模式共有3种,下来对3种低功耗进行分析测试。
先看手册上相关低功耗资料介绍:
在这里插入图片描述
先来分析睡眠模式:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
进入睡眠模式比较简单,只需一条指令即可。唤醒睡眠模式,我们使用串口中断来唤醒,通过对串口发送数据。利用串口RXD引脚来唤醒睡眠模式,代码如下:

//进入睡眠模式 任意中断唤醒  WKUP不能唤醒
void sleep_mode_wfi(void)
{
    __WFI();													//WFI指令进入睡眠
}
//进入睡眠模式 唤醒事件唤醒  WKUP 不能唤醒
void sleep_mode_wfe(void)
{
    __WFE();
}

通过调用这两个函数就可以直接进入睡眠模式,给串口发送数据可以退出睡眠模式。睡眠模式退出后,程序会从进入睡眠模式的下一行代码继续执行。相当于程序被暂停了。
下来看停止模式:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
停止模式通过调用库函数PWR_EnterSTOPMode(),可进入停止模式,停止模式唤醒需要用外部中断,将串口的RXT引脚设置为外部中断,上升沿触发,这样当串口接收到数据时,就会触发RXD引脚的外部中断。这样可通过串口直接唤醒停止模式。相关代码如下:

void EXIT_UART_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource10);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    EXTI_InitStructure.EXTI_Line = EXTI_Line10;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

}
void EXTI15_10_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line10) != RESET)
    {
        EXTI_ClearITPendingBit(EXTI_Line10);
        __set_FAULTMASK(1);	 //关闭所有中断
        NVIC_SystemReset();  //系统复位
    }

}

//进入停止模式   任意外部中断唤醒  WKUP不能唤醒
void enter_stop_mode(void)
{
    EXIT_UART_Init();											//RX引脚配置为外部中断
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 		//开电源管理时钟

    PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);		//进入停机模式
}

进入停止模式后,所有IO口保持为当前状态。当退出停止模式后,HSI RC振荡器会被选为系统时钟,而开发版用的是外部时钟,需要重新设置系统时钟。为了避免重新设置时钟的麻烦,在中断程序中,直接执行系统软件复位命令。直接对系统重新进行复位。如果在实际项目中需要外部IO口状态保持不变,就不能用系统复位命令,需要自己重新配置系统时钟和其他外设的时钟。

下来看待机模式:
在这里插入图片描述
在这里插入图片描述
进入待机模式后系统功耗最低,外部IO口都会处于高阻状态。退出待机模式后,系统会重新初始化,相当于按下了复位按键。相关代码如下:

void Sys_Standby(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 		//使能PWR外设时钟
    PWR_WakeUpPinCmd(ENABLE); 								 	//使能唤醒管脚功能  WKUP
    PWR_EnterSTANDBYMode();   									//进入待机(standby)模式
}

//系统进入待机模式   WKUP引脚上升沿、RTC脑子、NRST复位、IWDG复位 唤醒  中断不能唤醒
void Sys_Enter_Standby(void)
{
    RCC_APB2PeriphResetCmd(0X01FC, DISABLE); 					//复位所有IO口,屏蔽这条语句也没有看到什么影响
    Sys_Standby();
}

为了方便测试,用了WKUP唤醒。进入低功耗模式后,按下WKUP按键,系统会被唤醒,唤醒后系统复位,程序重新开始执行。
主函数测试代码如下:

int main(void)
{
    u8 i = 0, j = 0;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    delay_init();       										//延时函数初始化
    LED_Init();         										//初始化与LED连接的硬件接口
    KEY_Init();
    uart_init(9600);

    LED = 1;
    delay_ms(500);
    printf("low power test! \r\n\r\n");
    while(1)
    {
        i =  KEY_Scan(1);

        switch(i)
        {
        case 0:
            break;
        case 1:
            printf("进入停机模式\r\n\r\n");
            enter_stop_mode();									//唤醒后从程序开始位置执行
            printf("退出停机模式\r\n\r\n");              		//执行不到这块
            break;
        case 2:
            printf("进入待机模式\r\n\r\n");				
            Sys_Enter_Standby();						 		//唤醒后从程序开始位置执行
            printf("退出待机模式\r\n\r\n");				 		//执行不到这块
            break;
        case 3:
            printf("进入睡眠模式 中断唤醒 \r\n\r\n");
            sleep_mode_wfi();									//唤醒后接着下一条语句执行
            printf("退出睡眠模式 中断唤醒 \r\n\r\n");     		//唤醒后执行当前语句
            break;
        case 4:
            printf("进入睡眠模式 事件唤醒 \r\n\r\n");
            sleep_mode_wfe();									//唤醒后接着下一条语句执行
            printf("退出睡眠模式 事件唤醒 \r\n\r\n");				//唤醒后执行当前语句
            break;
        }

        j++;
        if(j > 5)
        {
            j = 0;
            LED = !LED;
        }

        delay_ms(10);

    }
}

通过LED闪烁指示程序执行状态,进入低功耗模式后,LED灯停止闪烁。退出低功耗模式后,LED灯继续闪烁,用串口输出相关信息,便于观察。

发布了76 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_20222919/article/details/100203870
今日推荐