精华内容
下载资源
问答
  • USART从低功耗模式唤醒STM32F0

    千次阅读 2018-08-04 00:25:32
    STM32F0的低功耗模式 在STM32应用中,为了降低功耗共有以下三种工作模式: Sleep mode (CPU clock off, all peripherals including ARM® Cortex®-M0 core peripherals like NVIC, SysTick, etc. are kept ...

    STM32F0的低功耗模式

    详细内容见参考手册—Power control (PWR)

    在STM32应用中,为了降低功耗共有以下三种工作模式:

    • Sleep mode
      CPU clock off, all peripherals including ARM® Cortex®-M0 core peripherals like NVIC, SysTick, etc. are kept running..
      In Sleep mode, only the CPU is stopped. All peripherals continue to operate and can wake up the CPU when an interrupt/event occurs.
    • Stop mode
      all clocks are stopped
      (Stop mode achieves very low power consumption while retaining the content of SRAM and registers. All clocks in the 1.8 V domain are stopped, the PLL, the HSI RC and the HSE crystal oscillators are disabled. The voltage regulator can also be put either in normal or in low power mode.
      The device can be woken up from Stop mode by any of the EXTI lines. The EXTI line source can be one of the 16 external lines and RTC.)
    • Standby mode
      1.8V domain powered-off
      The Standby mode is used to achieve the lowest power consumption. The internal
      voltage regulator is switched off so that the entire 1.8 V domain is powered off. The
      PLL, the HSI RC and the HSE crystal oscillators are also switched off. After entering Standby mode, SRAM and register contents are lost except for registers in the RTC domain and Standby circuitry.
      The device exits Standby mode when an external reset (NRST pin), an IWDG reset, a rising edge on the WKUP pins, or an RTC event occurs.

    备注:
    The RTC, the IWDG, and the corresponding clock sources are not stopped by entering Stop or Standby mode.

    另外,在正常工作模式(Run mode)下,可以通过以下方法有效降低功耗:

    • 降低系统时钟(system clocks)

    • 关闭不需要的APB和AHB外设时钟

    三种低功耗模式对比
    Low-power mode summary

    官网参考资料

    STM32F0-参考手册–>6 Power control (PWR)
    RM0360 Reference manual STM32F030x4/x6/x8/xC and STM32F070x6/xB
    STM32F0-数据手册–>3.5 Power management
    DS9773 STM32F030x4 STM32F030x6 STM32F030x8
    STM32F0-编程手册–>2.5 Power management
    PM0215 STM32F0xxx单片机编程手册
    STM32F0-应用笔记
    如何使用USART或LPUART从低功耗模式唤醒STM32F0 / F3 / L0 / L4微控制器

    官方参考代码

    应用平台:STM32F030

    main.c

    #include "stm32f0xx.h"
    /* Private variables ---------------------------------------------------------*/
    uint8_t DataReceived = 0;
    extern __IO uint8_t InterruptCounter;
    /* Private function prototypes -----------------------------------------------*/
    static void USART_Config(void);
    static void WakeUp_StartBitMethod(void);
    static void RestoreConfiguration(void);
    
    /**
      * @brief   Main program
      * @param  None
      * @retval None
      */
    int main(void)
    {    
      /* Initialize LEDs available  ***********************************************/
      STM_EVAL_LEDInit(LED);
    
      /* USART configuration */
      USART_Config();
    
      /* Wake up from USART STOP mode by Start bit Method */
      WakeUp_StartBitMethod();
    
      /* Configure SystemClock*/
      RestoreConfiguration();
    
      /* Configure and enable the systick timer to generate an interrupt each 1 ms */
      SysTick_Config((SystemCoreClock / 1000));
    
      while (1)
      {}
    }
    
    /**
      * @brief  Start Bit Method to Wake Up USART from Stop mode Test.
      * @param  None
      * @retval None
      */
    static void WakeUp_StartBitMethod(void)
    { 
      /* Configure the wake up Method = Start bit */ 
      USART_StopModeWakeUpSourceConfig(USART1, USART_WakeUpSource_StartBit);
    
      /* Enable USART1 */ 
      USART_Cmd(USART1, ENABLE);
    
      /* Before entering the USART in STOP mode the REACK flag must be checked to ensure the USART RX is ready */
      while(USART_GetFlagStatus(USART1, USART_FLAG_REACK) == RESET)
      {}
    
      /* Enable USART STOP mode by setting the UESM bit in the CR1 register.*/
      USART_STOPModeCmd(USART1, ENABLE);
    
      /* Enable the wake up from stop Interrupt */ 
      USART_ITConfig(USART1, USART_IT_WU, ENABLE);   
    
      /* Enable PWR APB clock */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
    
      /* Enter USART in STOP mode with regulator in low power mode */
      PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
    
      /* Waiting Wake Up interrupt */
      while(InterruptCounter == 0x00)
      {}
    
      /* Disable USART peripheral in STOP mode */ 
      USART_STOPModeCmd(USART1, DISABLE);
    
      while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
      {}
      DataReceived = USART_ReceiveData(USART1);
    
      /* Clear the TE bit (if a transmission is on going or a data is in the TDR, it will be sent before efectivelly disabling the transmission) */
      USART_DirectionModeCmd(USART1, USART_Mode_Tx, DISABLE);
    
      /* Check the Transfer Complete Flag */
      while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
      {}
    
      /* USART Disable */
      USART_Cmd(USART1, DISABLE);
    }
    
    /**
      * @brief Configure the USART Device
      * @param  None
      * @retval None
      */
    static void USART_Config(void)
    { 
      USART_InitTypeDef USART_InitStructure;
      GPIO_InitTypeDef GPIO_InitStructure; 
      NVIC_InitTypeDef NVIC_InitStructure;
    
      /* Enable GPIO&USART clock */
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA , ENABLE);  
      RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    
      /* Configure the HSI as USART clock */
      RCC_USARTCLKConfig(RCC_USART2CLK_HSI);
    
      /* USARTx Pins configuration **************************************************/  
      /* Connect pin to Periph */
      GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);    
      GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); 
    
      /* Configure pins as AF pushpull */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
      GPIO_Init(GPIOA, &GPIO_InitStructure); 
    
      /* USARTx configured as follow:
      - BaudRate = 115200 baud  
      - Word Length = 8 Bits
      - Stop Bit = 1 Stop Bit
      - Parity = No Parity
      - Hardware flow control disabled (RTS and CTS signals)
      - Receive and transmit enabled
      */
    
      USART_DeInit(USART1);
      USART_InitStructure.USART_BaudRate = 115200;
      USART_InitStructure.USART_WordLength = USART_WordLength_8b;
      USART_InitStructure.USART_StopBits = USART_StopBits_1;
      USART_InitStructure.USART_Parity = USART_Parity_No;
      USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
      USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
      USART_Init(USART1, &USART_InitStructure);
    
      /* USART2 IRQ Channel configuration */
      NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPriority = 0x01;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);
    }
    
    /**
      * @brief  Restore peripheral config before entering STOP mode.
      * @param  None
      * @retval None
      */
    static void RestoreConfiguration(void)
    {
      __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
    
      /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/    
      /* Enable HSE */    
      RCC_HSEConfig(RCC_HSE_ON);
    
      /* Wait till HSE is ready and if Time out is reached exit */
      HSEStatus = RCC_WaitForHSEStartUp();
    
      if (HSEStatus == (uint32_t)0x01)
      {
        /* Enable Prefetch Buffer */
        FLASH_SetLatency(FLASH_Latency_1);
    
        /* HCLK = SYSCLK */
        RCC_HCLKConfig(RCC_SYSCLK_Div1); 
    
        /* PCLK = HCLK */
        RCC_PCLKConfig(RCC_HCLK_Div1);
    
        /*  PLL configuration:  = HSE *  6 = 48 MHz */
        RCC_PREDIV1Config(RCC_PREDIV1_Div1);
        RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_CFGR_PLLMULL6);
    
        /* Enable PLL */
        RCC_PLLCmd(ENABLE);
    
        /* PLL as system clock source */
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
      } 
    }

    stm32f0xx_it.c

    /* Includes ------------------------------------------------------------------*/
    #include "stm32f0xx_it.h"
    /* Private variables ---------------------------------------------------------*/
    __IO uint8_t InterruptCounter = 0x00;
    __IO uint8_t Counter = 0;
    
    /**
      * @brief  This function handles SysTick Handler.
      * @param  None
      * @retval None
      */
    void SysTick_Handler(void)
    {  
      if (Counter == 20)
      {
        /* Toggle LED's */
        STM_EVAL_LEDToggle(LED);
    
        /* Reset Counter */
        Counter = 0;
      }
      else
      {
        /* increment Counter */
        Counter++; 
      }
    }
    
    /**
    * @brief  This function handles USART interrupt request.
    * @param  None
    * @retval None
    */
    void USART1_IRQHandler(void)
    {
      if (USART_GetITStatus(USART1, USART_IT_WU) == SET)
      { 
        /* Clear The USART WU flag */  
        USART_ClearITPendingBit(USART1, USART_IT_WU);
        InterruptCounter = 0x01;
      }
    }

    实际参考代码

    然而,在STM32F030中不能配置为USART的start位唤醒。

    #define USART_IT_WU ((uint32_t)0x00140316) /*!< Not available for STM32F030 devices */

    解决办法,配置USART的接收非空中断:USART_IT_RXNE
    这里写图片描述

    展开全文
  • 在ST的单片机中,一般低功耗模式都有stop(停机)模式和standby(待机)模式两种,这篇博客主要是分享一下standby模式,并且通过RTC实时时钟的闹钟将单片机从低功耗模式唤醒的方法。为了方便演示,实验流程是,通过...

    STM32CubeMX低功耗模式——待机模式(standby)RTC唤醒


    在ST的单片机中,一般低功耗模式都有stop(停机)模式和standby(待机)模式两种,这篇博客主要是分享一下standby模式,并且通过RTC实时时钟的闹钟将单片机从低功耗模式中唤醒的方法。为了方便演示,实验流程是,通过串口命令来设置单片机进入低功耗模式,再通过RTC的闹钟将单片机从低功耗状态唤醒,进入正常模式。

    使用CubeMX生成工程

    1.根据使用的单片机来配置生成工程,我使用的是NUCLEO-F303RE来做实验
    2.配置需要使用到的外设
    在这里插入图片描述
    首先要设置单片机的时钟源,在这里我是用的是内部高速时钟源和外部的低速时钟源。因为RTC需要使用一个低速时钟源。
    在这里插入图片描述激活RTC功能,并设置RTC的闹钟
    在这里插入图片描述
    第一步:配置数据格式为二进制格式(Binary data format),便于后期处理。
    第二步:自动异步分频使能,这里可以自动将RTC的时钟源分频成1HZ
    第三步:选择使能闹钟屏蔽标识,例如图中的参数设置,表示在秒相同的时候触发,也就是一分钟触发一次闹钟。同理,可以设置一秒触发,一天触发一次或者一周触发一次。
    在这里插入图片描述
    在这里我还设置了串口,用于在实验中显示输出。
    在这里插入图片描述
    最后使能相关的外设的中断。
    3.设置好工程名称和保存位置,选择自己用的开发工具和版本,然后生成工程代码

    代码处理

    首先引用和定义一些必要的头文件和参数

    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    
    #include "usart_user.h" 
    #include "string.h"
    
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    RTC_DateTypeDef gDateType;  //获取RTC日期
    RTC_TimeTypeDef gTimeType;  //获取RTC时间
    
    RTC_DateTypeDef sDateType;  //设置RTC日期
    RTC_TimeTypeDef sTimeType;  //设置RTC时间
    
    static char cmd_setTime[] = "AT+SETTIME";   //设置RTC时间命令
    static char cmd_standby[] = "AT+STANDBY";   //进入standby模式命令
    
    /* USER CODE END PTD */
    

    main函数循环中用于处理命令的部分

     /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    
          if(USART_RX_Finish)   //判断串口接收完成
          {
             USART_RX_Finish = 0;   //清除串口接收完成标识
             if(strncmp(USART_RX_BUF,cmd_setTime,strlen(cmd_setTime)) == 0) //判断命令,处理RTC时钟设置
             {
                sTimeType.Hours = (USART_RX_BUF[(strlen(cmd_setTime) + 1)]-'0')*10 +(USART_RX_BUF[(strlen(cmd_setTime) + 2)]-'0');
                sTimeType.Minutes = (USART_RX_BUF[(strlen(cmd_setTime) + 4)]-'0')*10 +(USART_RX_BUF[(strlen(cmd_setTime) + 5)]-'0');
                sTimeType.Seconds = (USART_RX_BUF[(strlen(cmd_setTime) + 7)]-'0')*10 +(USART_RX_BUF[(strlen(cmd_setTime) + 8)]-'0');
                printf("设置RTC时间为 %02d:%02d:%02d \r\n",sTimeType.Hours,sTimeType.Minutes,sTimeType.Seconds);
                if(HAL_RTC_SetTime(&hrtc,&sTimeType,RTC_FORMAT_BIN)!=HAL_OK)    //设置RTC时间
                {
                    printf("HAL_RTC_SetTime ERR \r\n");
                }
                printf("设置RTC时间成功!\r\n");
             }
            
             if(strncmp(USART_RX_BUF,cmd_standby,strlen(cmd_standby)) == 0) //判断命令,进入standby模式
             {
                 printf("Executing test (standby) \r\n");
                 
                 GPIO_AnalogState_Config(); //设置IO口为模拟输入状态
                 
                 __HAL_RCC_PWR_CLK_ENABLE();
                 
                 HAL_PWR_EnterSTANDBYMode();    //进入standby模式
                 
                 printf("进入待机模式失败\r\n");
                 
             }
           }
           if((PWR->CSR & PWR_CSR_WUF )== PWR_CSR_WUF)  //清除闹钟中断的标识
           {
              PWR->CR |= PWR_CR_CWUF;
           }
           HAL_Delay(200);
           HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);   //翻转LD2,显示单片机处于正常工作状态
      }
      /* USER CODE END 3 */
    

    获取RTC时间和日期的函数,以及RTC的闹钟中断回调函数

    /* USER CODE BEGIN 4 */
    
    /*获取RTC的时钟和日期*/
    void get_date (RTC_DateTypeDef *sDateStruc,RTC_TimeTypeDef *sTimeStruc)
    {
        
        if(HAL_RTC_GetTime(&hrtc,sTimeStruc,RTC_FORMAT_BIN) != HAL_OK)
        {
            printf("HAL_RTC_GetTime ERR \r\n");
        }
        
        if(HAL_RTC_GetDate(&hrtc,sDateStruc,RTC_FORMAT_BIN) != HAL_OK)
        {
            printf("HAL_RTC_GetDate ERR \r\n");
        }
        
    }
    
    /*RTC闹钟的回调函数*/
    void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc)
    {
        
        get_date(&gDateType,&gTimeType);
        printf("当前RTC时间为 %02d:%02d:%02d \r\n",gTimeType.Hours,gTimeType.Minutes,gTimeType.Seconds);
        
    }
    
    /* USER CODE END 4 */
    

    设置IO口为模拟输入状态的函数,这个函数主要是为了在低功耗状态下,尽量控制IO上不必要的漏电流产生。

    /* USER CODE BEGIN 2 */
    
    void GPIO_AnalogState_Config(void)
    {
        GPIO_InitTypeDef GPIO_InitStruct;
        
        /*Set all GPIO in analog state to reduce power consumption*/
        
        __HAL_RCC_GPIOA_CLK_ENABLE();
        __HAL_RCC_GPIOB_CLK_ENABLE();
        __HAL_RCC_GPIOC_CLK_ENABLE();
        
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Pin = GPIO_PIN_All;
        
        HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
        HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
        HAL_GPIO_Init(GPIOC,&GPIO_InitStruct);
        
        __HAL_RCC_GPIOA_CLK_DISABLE();
        __HAL_RCC_GPIOB_CLK_DISABLE();
        __HAL_RCC_GPIOC_CLK_DISABLE();
    }
    
    /* USER CODE END 2 */
    

    到这里基本就已经实现了单片机的standby模式了,并且可以通过RTC的闹钟实现休眠一分钟后唤醒。但是每次唤醒后都会让RTC时钟的时间重置,所以最后我通过判断后备寄存器的方式,来保证RTC的时间参数在唤醒时不被重置。具体代码如下:

    void MX_RTC_Init(void)
    {
      RTC_TimeTypeDef sTime = {0};
      RTC_DateTypeDef sDate = {0};
      RTC_AlarmTypeDef sAlarm = {0};
    
      /** Initialize RTC Only 
      */
      hrtc.Instance = RTC;
      hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
      hrtc.Init.AsynchPrediv = 127;
      hrtc.Init.SynchPrediv = 255;
      hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
      hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
      hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
      if (HAL_RTC_Init(&hrtc) != HAL_OK)
      {
        Error_Handler();
      }
    
      /* USER CODE BEGIN Check_RTC_BKUP */
      
      if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1) != 0xA5A5) //判断后备寄存器是否被赋值
      {
          /* USER CODE END Check_RTC_BKUP */
    
          /** Initialize RTC and set the Time and Date 
          */
          sTime.Hours = 0;
          sTime.Minutes = 0;
          sTime.Seconds = 0;
          sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
          sTime.StoreOperation = RTC_STOREOPERATION_RESET;
          if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
          {
            Error_Handler();
          }
          sDate.WeekDay = RTC_WEEKDAY_MONDAY;
          sDate.Month = RTC_MONTH_JANUARY;
          sDate.Date = 1;
          sDate.Year = 0;
    
          if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
          {
            Error_Handler();
          }
    
          HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1, 0xA5A5); //为后备寄存器写入值
      }
    
      /** Enable the Alarm B 
      */
      sAlarm.AlarmTime.Hours = 0;
      sAlarm.AlarmTime.Minutes = 0;
      sAlarm.AlarmTime.Seconds = 0;
      sAlarm.AlarmTime.SubSeconds = 0;
      sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
      sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
      sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS
                                  |RTC_ALARMMASK_MINUTES;
      sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
      sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
      sAlarm.AlarmDateWeekDay = 1;
      sAlarm.Alarm = RTC_ALARM_B;
      if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
      {
        Error_Handler();
      }
    }
    

    到这里,待机模式(standby)下RTC唤醒就已经实现了。

    实验结果

    在这里插入图片描述
    在电路上,程序复位后,LD2会周期闪烁,然后再发送“AT+STANDBY”命令后,LD2熄灭,然后等待大概1分钟(时间和你发送进入待机模式的时间有关系),LD2重新开始周期闪烁。

    经过万用表测量,最后单片机的待机功耗为5.8uA
    在这里插入图片描述

    总结

    在利用RTC闹钟唤醒standby模式中,需要关注的问题有:
    1.关于功耗控制,需要对不使用的IO口进行漏电流的控制,因此,最好将没有使用的IO口都配置为模拟输入状态。
    2.利用RTC闹钟进行唤醒时,需要注意闹钟中断触发后,中断标识是否被清除,否则,standby模式很可能在进入后立马退出。
    3.如果要在退出standby模式后,RTC时钟需要继续按照设定的时间计时,需要通过后备寄存器来判断单片机是否是第一次启动。

    展开全文
  • 当freeRTOS各个应用任务全部挂起后或者阻塞后,会进入空闲任务,进入空闲任务后,首先会计算可以执行低功耗的最大时间,然后把低功耗的唤醒时间设置为这个求出的时间,到时间后系统会从低功耗模式唤醒,继续执行多...
    1. Tickless模式的理解:当freeRTOS各个应用任务全部挂起后或者阻塞后,会进入空闲任务,进入空闲任务后,首先会计算可以执行低功耗的最大时间,然后把低功耗的唤醒时间设置为这个求出的时间,到时间后系统会从低功耗模式唤醒,继续执行多任务。
    2. FreeRTOS的tickless低功耗模式的实现:
      (1) FreeRTOSConfig.h文件中配置宏定义configUSE_TICKLESS_IDLE为1。
      备注:#define configUSE_TICKLESS_IDLE 1 后低功耗模式已经开启。
      但进入低功耗模式有两个条件:
      I.当前空闲任务正在进行,所有其他任务处于挂起或阻塞状态
      II.根据用户配置的configEXPECTED_IDLE_TIME_BEFORE_SLEEP大小,只有当系统可运行于低功耗模式的时钟节拍数大于等于这个参数时,系统才可以进入低功耗模式。如下图所示,此参数已经默认在freeRTOS.h文件中定义了。
      在这里插入图片描述
      备注:configEXPECTED_IDLE_TIME_BEFORE_SLEEP默认定义大小为两个系统时钟节拍,如果用户自定义的话不能小于2个时钟节拍。
      (2) 在portmacro.h中的宏portSUPPRESS_TICKS_AND_SLEEP()是在freeRTOS中实现tickless模式的关键。
      在这里插入图片描述
      函数vPortSuppressTicksAndSleep( xExpectedIdleTime )是实际的低功耗执行代码,在port.c中定义。
      备注:xExpectedIdleTime是系统时钟节拍数
      (3) configPRE_SLEEP_PROCESSING()和configPOST_SLEEP_PROCESSING()
      这两个宏已经在port.c的函数vPortSuppressTicksAndSleep( xExpectedIdleTime )被调用。
      在这里插入图片描述
      该宏在FreeRTOS.h会被预编译

    在这里插入图片描述
    我们在使用该函数之前应该在FreeRTOSConfig.h中如下方式配置:
    extern void PreSleepProcessing(uint32_t ulExpectedIdleTime);
    extern void PostSleepProcessing(uint32_t ulExpectedIdleTime);
    //进入低功耗模式前要做的处理
    #define configPRE_SLEEP_PROCESSING presleepProcessing
    //退出低功耗模式后要做的处理
    #define configPOST_SLEEP_PROCESSING postSleepProcessing
    备注:函数PreSleepProcessing()和PostSleepProcessing()可以在任意一个C文件中编写,在函数中可以加入一些关闭GPIO口的指令。
    此处的一些详细用法可参见:https://blog.csdn.net/ZCShouCSDN/article/details/77879746?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

    展开全文
  • 正常情况下,STM32从低功耗模式唤醒时,都需要重新初始化时钟,但是如果LCD使用的时钟被初始化,则就会出现闪频的现象,只会闪一下,然后再迅速回复正常。解决办法,使用和RTC一样的时钟源,例如使用LSI,这样在...

    正常情况下,STM32从低功耗模式下唤醒时,都需要重新初始化时钟,但是如果LCD使用的时钟被初始化,则就会出现闪频的现象,只会闪一下,然后再迅速回复正常。解决办法,使用和RTC一样的时钟源,例如使用LSI,这样在唤醒时,不初始化LSI时钟,系统也能正常运行。

    展开全文
  • STM32F030F4P6从低功耗唤醒后,STM32默认的时钟为HSI,因此若要让STM32回到运行模式并正常工作一段时间,必须要注意STM32的时钟问题,按照实际情况选择是否将系统时钟恢复到停止模式前的时钟配置...
  • 使用实时时钟RTC的 WakeUpTimer定时器产生的中断将STM32STOP低功耗模式唤醒。 STOP模式: STM32低功耗运行模式之一,该模式下CPU会停止工作,但RAM中的数据仍然保留。待中断或事件触发后程序可以继续运行。 ...
  • STM32F103三种低功耗模式的区别

    千次阅读 2021-01-14 11:25:04
    STM32F103三种低功耗模式的区别STMF103的三种低功耗模式唤醒之后代码运行流程睡眠模式停机模式待机模式低功耗模式下GPIO的状态睡眠模式停机模式待机模式低功耗设计思路 STMF103的三种低功耗模式 睡眠模式(sleep_...
  • stm32低功耗模式

    2019-12-30 14:19:11
    stm32低功耗模式 stm32f103系列有3种低功耗模式: 睡眠模式 停止模式 待机模式 上往下功耗越低。 1. 睡眠模式 在睡眠模式中,仅关闭了内核时钟,内核停止运行,但其片上外设,CM3核心的外设全都还照常运行。...
  • stm32L0系列低功耗唤醒

    2020-07-14 15:21:37
    stm32低功耗模式唤醒后系统如何运行? 如果是stop或者休眠模式,那么唤醒后会继续休眠停止的位置继续开始执行程序,所有寄存器的值都保持不变。 如果是待机模式,那么想当于复位重启,程序重新执行,除了备份...
  • STM32低功耗模式

    千次阅读 2020-04-17 15:04:24
    STM32 的低功耗模式有 3种: 1)睡眠模式(CM3内核停止,外设仍然运行) 2)停止模式(所有时钟都停止) 3)待机(standby)模式(1.8V内核电源关闭) 待机模式唤醒后的代码执行等同于复位后的执行 进入Standby模式后...
  • 代码示例.................................................19D.1 CE219881 - PSoC 6 MCU 切换功耗模式..........19D.2 CE218129 - 使用低功耗比较器休眠状态唤醒PSoC 6 MCU .....................................
  • 三 stm32低功耗模式

    2019-02-24 15:59:24
    在做很多产品的时候,功耗是必须要考虑的一项因素,一定程度上决定了你的产品是否有竞争力,降低功耗可以硬件上和软件上进行处理,而软件上进入低功耗模式是降功耗很有效的一项措施。这里对stm32的三种低功耗模式...
  • 本人使用的是STM32F030F4P6进行...STM32F030F4P6有三个低功耗模式。待机模式下(standby)功耗最低但是需要wake_up引脚上升沿或者RTC闹钟才能进行唤醒,在硬件已经设计好的基础上不满足本次软件设计的需求。然后考...
  • 上电复位后 STM32 处于运行状态,当内核不需要继续运行,就可以选择进入后面的三种低功耗模式降低功耗,这三种模式中,电源消耗不同、唤醒时间不同、唤醒源不同,用户需要根据应用需求,选择的低功耗模式。...
  • stm32几种低功耗模式的实现和差别

    千次阅读 2019-08-20 09:29:55
    上电复位后 STM32 处于运行状态,当内核不需要继续运行,就可以选择进入后面的三种低功耗模式降低功耗,这三种模式中,电源消耗不同、唤醒时间不同、唤醒源不同,用户需要根据应用需求,选择最佳的低功耗模式。...
  • 最近用国产芯片AT32在做一个低功耗的项目,为了实现低功耗模式下的定时唤醒,我选择的是使用相对比较简单的看门狗来做,下面就分享一下使用过程~ 为了最大限度的降低功耗,我用的是待机模式,先看看几种低功耗模式...
  • 由于需要弄智能井盖,采集甲烷CH4传感器及水位信息等,通过蓝牙手机APP及4G模块将数据发送至...1.低功耗一定在设计之初考虑硬件,没有硬件的配合,再如何调试软件都是白塔的;(最初弄STM8的低功耗也是) 比如采...
  • msp430f149的低功耗模式

    2013-09-21 00:46:00
    430的低功耗确实很强啊,虽然和VR单片机比起来速度慢了好多。...一个中断事件可以将芯片五种低功耗模式中的任何一种唤醒,为请求服务并在中断程序返回时恢复低功耗模式。下面6种运算模式由软件配置。 ●...
  • stm32 3种低功耗模式

    万次阅读 2016-08-17 17:32:47
    低功耗模式有 3种: 1)睡眠模式(CM3内核停止,外设仍然运行) 2)停止模式(所有时钟都停止) 3)待机(standby)模式(1.8V内核电源关闭) 待机模式唤醒后的代码执行等同于复位后的执行 进入Standby模式后,只能...
  • 管脚中断能 使MCU空闲模式或掉电模式唤醒 可以通过外部中断使N76E003掉电模式唤醒。触发外部中断管脚会重启系统时钟,在振荡器 稳定后,设备执行外部中断对应的中断服务程序( ISR)。 ISR返回后,设备立...
  • 通过ucos起一个任务进行设备状态的监测,当监测到设备出现视屏的状态,进入低功耗模式-停止模式。 b.进入低功耗前关闭ADC(用的AD1),唤醒后初始化ADC,大概节省了3MA左右. c.其他的GPIO优化,这个优化之后发现,...
  • NB-Iot的低功耗模式PSM参数

    千次阅读 2019-11-19 11:06:47
    既然NB-Iot的一大亮点是低功耗,那么就必须了解下低功耗的原理和参数。 一、PSM状态 NB进入PSM状态。在此状态下NB的射频被关闭,相当于关机,但是核心网还保留着NB的信息,当NBPSM唤醒之后进入连接状态(不需要...
  • STM8L051低功耗模式测试文档

    千次阅读 2015-11-28 18:51:57
    STM8L051的五种低功耗模式wait ,low power run mode,low power wait mode,Ative-Halt mode,Halt mode。 WAIT mode  在等待模式,CPU的时钟是停止的,被选择的外设继续运行。WAIT mode 分为两...
  • STM32F103C8T6 Standby低功耗模式

    千次阅读 2012-11-19 14:37:58
    2. 低功耗模式简介 刚接触PWR的内容,使用手册说的不太能让我好理解。其实当你弄懂了以后再回去看使用手册还是能找到的,只是写的过于简略,对于初学者很多地方理解不到位。   这个小总结完全初学者...
  • STM32低功耗三种方式唤醒

    热门讨论 2014-04-16 10:42:56
    函数SYSCLKConfig_STOP用于当处理器停机模式唤醒之后,配置系统时钟、使能HSE和PLL,并以PLL作为系统时钟源。当处理器处理停机模式的时候,HSE、PLL是不可用的。 函数GPIO_Configuration用于配置GPIO的PC6、PC7、...
  • 描述 德州仪器(TI)MSP430系列超低功耗微控制器由多个器件组成,具有针对各种应用的不同外设集...数字控制振荡器(DCO)允许在不到1μs的时间内从低功耗模式唤醒到活动模式。 MSP430F20xx系列是一款超低功耗混合信...
  • 描述 TI MSP430系列超低功耗微控制器由多个器件组成,具有针对各种应用的不同外设集。...数字控制振荡器(DCO)允许器件在不到6μs的时间内从低功耗模式唤醒到工作模式。 品牌:TI 型号;MSP430FE427IPMR 封...
  • 一、低功耗模式简介 系统提供了多个低功耗模式...表中可以看到,这三种低功耗模式层层递进,运行的时钟或芯片功能越来越少,因而功耗越来越低。 模式名称 说明 进入方式 唤醒方式 对1.8V区域时钟的影响 对VDD区

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 196
精华内容 78
关键字:

从低功耗模式唤醒