单片机低功耗实验

单片机 :STM32F407

开发板:DMF407电机开发板

平台:keil V5.31

HSE 为8MHZ

HSI为16MHZ

一、PVD电压电压检测实验

主函数:

复制代码
int main(void)
{
    uint8_t t = 0;
    
    HAL_Init();                             /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7);     /* 设置时钟,168Mhz */
    delay_init(168);                        /* 延时初始化 */
    usart_init(115200);                     /* 串口初始化为115200 */
    led_init();                             /* 初始化LED */
    lcd_init();                             /* 初始化LCD */
    pwr_pvd_init(PWR_PVDLEVEL_7);           /* PVD 2.9V检测 */
    
    lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "PVD TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    /* 默认LCD显示电压正常 */
    lcd_show_string(30, 110, 200, 16, 16, "PVD Voltage OK! ", BLUE);
    
    while (1)
    {
        if ((t % 20) == 0)
        {
            LED0_TOGGLE();      /* 每200ms,翻转一次LED0 */
        }

        delay_ms(10);
        t++;
    }
}

配置:

复制代码
/**
 * @brief       初始化PVD电压监视器
 * @param       pls: 电压等级(PWR_PVD_detection_level)
 *   @arg       PWR_PVDLEVEL_0,2.2V;
 *   @arg       PWR_PVDLEVEL_1,2.3V;
 *   @arg       PWR_PVDLEVEL_2,2.4V;
 *   @arg       PWR_PVDLEVEL_3,2.5V;
 *   @arg       PWR_PVDLEVEL_4,2.6V;
 *   @arg       PWR_PVDLEVEL_5,2.7V;
 *   @arg       PWR_PVDLEVEL_6,2.8V;
 *   @arg       PWR_PVDLEVEL_7,2.9V;
 * @retval      无
 */
void pwr_pvd_init(uint32_t pls)
{
    PWR_PVDTypeDef pvd_handle = {0};

    __HAL_RCC_PWR_CLK_ENABLE();

    pvd_handle.PVDLevel = pls;
    pvd_handle.Mode = PWR_PVD_MODE_IT_RISING_FALLING;
    HAL_PWR_ConfigPVD(&pvd_handle);

    HAL_NVIC_SetPriority(PVD_IRQn, 3, 3);       /* 抢占优先级3,子优先级3 */
    HAL_NVIC_EnableIRQ(PVD_IRQn);
    HAL_PWR_EnablePVD();
}

/**
 * @brief       PVD中断服务函数
 * @param       无
 * @retval      无
 */
void PVD_IRQHandler(void)
{
    HAL_PWR_PVD_IRQHandler();
}

/**
 * @brief       PVD/AVD中断服务回调函数
 * @param       无
 * @retval      无
 */
void HAL_PWR_PVDCallback(void)
{
    if (__HAL_PWR_GET_FLAG(PWR_FLAG_PVDO))   /* 电压比PLS所选电压还低 */
    {
        lcd_show_string(30, 130, 200, 16, 16, "PVD Low Voltage!", RED); /* LCD显示电压低 */
        LED1(0);    /* 点亮绿灯, 表明电压低了 */
    }
    else
    {
        lcd_show_string(30, 130, 200, 16, 16, "PVD Voltage OK! ", BLUE);/* LCD显示电压正常 */
        LED1(1);    /* 灭掉绿灯 */
    }
}

测试结果:

二、睡眠模式实验

主函数:

配置:

复制代码
/**
 * @brief       低功耗模式下的按键初始化(用于唤醒睡眠模式/停止模式/待机模式)
 * @param       无
 * @retval      无
 */
void pwr_key_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    
    PWR_KEY1_GPIO_CLK_ENABLE();     /* KEY1时钟使能 */

    gpio_init_struct.Pin = PWR_KEY1_GPIO_PIN;               /* KEY1唤醒按键引脚 */
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;           /* 中断,上升沿 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 下拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
    HAL_GPIO_Init(PWR_KEY1_GPIO_PORT, &gpio_init_struct);   /* 引脚初始化 */

    HAL_NVIC_SetPriority(PWR_KEY1_INT_IRQn, 2, 2); /* 抢占优先级2,子优先级2 */
    HAL_NVIC_EnableIRQ(PWR_KEY1_INT_IRQn); 
}

/**
 * @brief      KEY1按键 外部中断服务程序
 * @param       无
 * @retval      无
 */
void PWR_KEY1_INT_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(PWR_KEY1_GPIO_PIN);
}

/**
 * @brief       进入CPU睡眠模式
 * @param       无
 * @retval      无
 */
void pwr_enter_sleep(void)
{
    HAL_SuspendTick();  /* 暂停滴答时钟,防止通过滴答时钟中断唤醒 */
    
    HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); /* 执行WFI指令, 进入待机模式 */
}

/**
 * @brief       外部中断回调函数
 * @param       GPIO_Pin:中断线引脚
 * @note        此函数会被PWR_WKUP_INT_IRQHandler()调用
 * @retval      无
 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == PWR_KEY1_GPIO_PIN)
    {
        /* HAL_GPIO_EXTI_IRQHandler()函数已经为我们清除了中断标志位,所以我们进了回调函数可以不做任何事 */
    }
}

实验结果:

按下按键0,进入睡眠模式,绿灯常亮;按下按键1,退出睡眠,绿灯灭,红灯闪烁。

三、停止模式实验:

主函数:

配置:

复制代码
void pwr_enter_stop(void)
{
    __HAL_RCC_PWR_CLK_ENABLE();
    HAL_SuspendTick();  /* 暂停滴答时钟,防止通过滴答时钟中断唤醒 */
    /* 当SVOS3进入停止模式时,设置稳压器为低功耗模式,等待中断唤醒 */
    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}

实验结果:

按下按键0进入停止模式,按下按键1退出。

四、待机模式实验

主函数:

配置:

复制代码
/**
 * @brief       低功耗模式下的按键初始化(用于唤醒睡眠模式/停止模式/待机模式)
 * @param       无
 * @retval      无
 */
void pwr_key_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    
    PWR_KEY1_GPIO_CLK_ENABLE();     /* KEY1时钟使能 */

    gpio_init_struct.Pin = PWR_KEY1_GPIO_PIN;               /* KEY1唤醒按键引脚 */
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;           /* 中断,上升沿 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 下拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
    HAL_GPIO_Init(PWR_KEY1_GPIO_PORT, &gpio_init_struct);   /* 引脚初始化 */

    HAL_NVIC_SetPriority(PWR_KEY1_INT_IRQn, 2, 2); /* 抢占优先级2,子优先级2 */
    HAL_NVIC_EnableIRQ(PWR_KEY1_INT_IRQn); 
    
    PWR_WKUP_GPIO_CLK_ENABLE();     /* WKUP时钟使能 */

    gpio_init_struct.Pin = PWR_WKUP_GPIO_PIN;                 /* WK_UP引脚 */
    gpio_init_struct.Mode = GPIO_MODE_IT_RISING;              /* 中断,上升沿 */
    gpio_init_struct.Pull = GPIO_PULLDOWN;                    /* 下拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;            /* 高速 */
    HAL_GPIO_Init(PWR_WKUP_GPIO_PORT, &gpio_init_struct);     /* WK_UP引脚初始化 */

    HAL_NVIC_SetPriority(PWR_WKUP_INT_IRQn, 2, 2); /* 抢占优先级2,子优先级2 */
    HAL_NVIC_EnableIRQ(PWR_WKUP_INT_IRQn); 
}

/**
 * @brief       进入待机模式
 * @param       无
 * @retval      无
 */
void pwr_enter_standby(void)
{
    __HAL_RCC_AHB1_FORCE_RESET();       /* 复位所有IO口 */

    while(WKUP_KD);                     /* 等待WK_UP按键松开(在有RTC中断时,必须等WK_UP松开再进入待机) */

    __HAL_RCC_PWR_CLK_ENABLE();         /* 使能PWR时钟 */
    __HAL_RCC_BACKUPRESET_FORCE();      /* 复位备份区域 */
    HAL_PWR_EnableBkUpAccess();         /* 后备区域访问使能 */  

    /* STM32F4,当开启了RTC相关中断后,必须先关闭RTC中断,再清中断标志位,然后重新设置 */
    /* RTC中断,再进入待机模式才可以正常唤醒,否则会有问题. */
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
    __HAL_RTC_WRITEPROTECTION_DISABLE(&g_rtc_handle);   /* 关闭RTC写保护 */

    /* 关闭RTC相关中断,可能在RTC实验打开了 */
    __HAL_RTC_WAKEUPTIMER_DISABLE_IT(&g_rtc_handle, RTC_IT_WUT);
    __HAL_RTC_TIMESTAMP_DISABLE_IT(&g_rtc_handle, RTC_IT_TS);
    __HAL_RTC_ALARM_DISABLE_IT(&g_rtc_handle, RTC_IT_ALRA|RTC_IT_ALRB);

    /* 清除RTC相关中断标志位 */
    __HAL_RTC_ALARM_CLEAR_FLAG(&g_rtc_handle, RTC_FLAG_ALRAF|RTC_FLAG_ALRBF);
    __HAL_RTC_TIMESTAMP_CLEAR_FLAG(&g_rtc_handle, RTC_FLAG_TSF); 
    __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&g_rtc_handle, RTC_FLAG_WUTF);

    __HAL_RCC_BACKUPRESET_RELEASE();                    /* 备份区域复位结束 */
    __HAL_RTC_WRITEPROTECTION_ENABLE(&g_rtc_handle);    /* 使能RTC写保护 */
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);                  /* 清除Wake_UP标志 */

    HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);           /* 设置WKUP用于唤醒 */
    HAL_PWR_EnterSTANDBYMode();                         /* 进入待机模式 */
}

测试结果:

按下按键0,进入待机模式,LCD灭;

按下按键1,无反应。

将PA0接5.0V,启动,容易死机。

相关推荐
周周记笔记1 小时前
【元器件专题】PNP三极管如何搭建开关电路
单片机·嵌入式硬件
不脱发的程序猿2 小时前
如何创建一个标准Skill,让嵌入式经验真正复用起来
人工智能·单片机·嵌入式硬件·嵌入式·skill
czhaii2 小时前
STC8H8K32U工控板运行程序标志位显示
单片机·嵌入式硬件
BT-BOX2 小时前
基于STM32物联网WiFi云平台温湿度烟雾报警器设计
stm32·嵌入式硬件·物联网
小慧10242 小时前
STM 32 TIM定时器(1)
单片机·嵌入式硬件
崇山峻岭之间13 小时前
单片机LCD实验
单片机·嵌入式硬件
m0_3771081414 小时前
STM32-adc
stm32·单片机·嵌入式硬件
【云轩】15 小时前
如何设计一台能模拟电机的电子负载:一个硬件工程师的实战笔记
笔记·嵌入式硬件
SmartRadio15 小时前
STM32WLE5 LoRa Smart TDMA 完整协议栈实现(工程级可直接编译)-【1】
javascript·stm32·单片机·嵌入式硬件·lora·自组网·smart tdma