火柴棍

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
火柴棍 门户 博客 STM32 MCU 查看内容

STM32L4 运行FreeRTOS之STOP2低功耗模式

2020-6-7 23:34| 发布者: admin| 查看: 1891| 评论: 0|原作者: 火柴棍

摘要: STM32L4 STOP FreeRTOS 低功耗

    最近做一个物联网的项目,由于功能比较多,为了简化程序逻辑,所以使用了FreeRTOS操作系统,MCU为STM32L431。FreeRTOS的源码只实现了sleep级别低功耗模式(需要定义#define configUSE_TICKLESS_IDLE                  1),此模式只有CPU停止运行,功耗有几个mA电流。STOP模式2是MCU能被一些外设唤醒的最低功耗模式。但是MCU一但进入STOP模式2,只有LSI和LSE时钟能开启,其余时钟均关闭,FreeRTOS时间片管理所使用的SYSTICK定时器使用的时钟为系统时钟或者系统时钟的8分频,在STOP2模式下系统时钟是关闭的,所以SYSTICK在STOP2模式下会停止运行,那么FreeRTOS的时间片管理会出错。

    大部分所采用的方法是将FreeRTOS时间片管理使用的SYSTICK定时器改为RTC Timer或Lp Timer实现,因为RTC AWU Timer和Lp Timer可选择LSE或LSI作为时钟源,在STOP2模式下依然可以运行,这样就能保证FreeRTOS的时间片管理不会出错。我刚开始尝试使用RTC AWU Timer替换SYSTICK Timer,但是发现操作RTC AWU Timer的寄存器步骤繁琐,操作之前需要失能保护,操作之后需要使能保护,还有其它一些繁琐的操作,我就想改为由Lp Timer实现,操作相对简单一些。在我修改时,我也在翻看STM32Cube_FW_L4_V1.13.0\Projects中的例程,打开了B-L475E-IOT01A文件夹,接着又点开了Applications看到了FreeRTOS,我点开了FreeRTOS文件夹看到了FreeRTOS_LowPower_LPTIM文件名,顿时有种想哭的感觉,也好后悔没有早点看到这个例程,这不正是我想要的吗?在低功耗模式下通过Lp Timer来实现FreeRTOS的时间片管理,然后我打开工程仔细研究了一番,此例程的FreeRTOS API封装是CMSIS_V1版本,低功耗模式为STOP1,使用了LPTIM1作为FreeRTOS的时间片管理定时器,选择LSE(32.768kHz)作为时钟源,1分频,系统的Tick周期为1ms,LPTIM1的自动重装周期值设为32即可,并且HAL库的HAL_IncTick()也是通过LPTIM1来实现。有一个关键点需要了解一下,FreeRTOS系统进入Sleep模式的最大Tick数(xMaximumPossibleSuppressedTicks),换言之FreeRTOS最多睡多久就必须被唤醒,根据定义:

static const uint32_t ulReloadValueForOneSec = LSE_VALUE;

xMaximumPossibleSuppressedTicks = (portMAX_16_BIT_NUMBER * configTICK_RATE_HZ) / ulReloadValueForOneSec;

LSE_ALUE的值为32768U,那么xMaximumPossibleSuppressedTicks=(0xFFFF*1000)/32768=1999,最多1999个Tick,1个Tick的周期为1ms,那就是1.999秒,那么FreeRTOS一次最多睡1.999秒就会被唤醒然后重装LPTIM1的计数值。如果需要让FreeRTOS一次睡的时间更久,可以修改void InitTick (uint32_t TickPriority)函数中LptimHandle.Init.Clock.Prescaler 的值,分频越大xMaximumPossibleSuppressedTicks越大,不能操作LPTIM_PRESCALER_DIV16,不然Tick周期会超过1ms。如果修改了LptimHandle.Init.Clock.Prescaler的值,那么需要修改以下4个定义值:

#define PeriodValue             (uint32_t) (32)

#define PulseValue              (uint32_t) (16)

static const uint32_t ulReloadValueForOneTick = (LSE_VALUE / configTICK_RATE_HZ);

static const uint32_t ulReloadValueForOneSec = LSE_VALUE;

几分频就再除以几,xMaximumPossibleSuppressedTicks的最终值就是1999*分频数。

移植说明:

如果工程使用的FreeRTOS API封装为CMSIS_V1版本,那么将以下文件移到工程:

low_power_tick_management_LPTIM.c

stm32l4xx_timebase_lptim.c

stm32l4xx_timebase_lptim.h

并定义定义#define configUSE_TICKLESS_IDLE                  2

如果要进入STOP2模式,可修改void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )函数中的HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);为HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);

我的项目使用的FreeRTOS API封装为CMSIS_V2,移植时除了以上几点,还需要修改一些内容。

low_power_tick_management_LPTIM.c

可参考如下代码:

/**
  ******************************************************************************
  * @file    FreeRTOS\FreeRTOS_LowPower_LPTIM\Src\low_power_tick_management_LPTIM.c
  * @author  MCD Application Team
  * @brief   RTOS Low power tick management using LPTIM peripheral.    
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************  
  */


#include "cmsis_os2.h"
#include "FreeRTOS.h"
#include "task.h"
#include "stm32l4xx_hal.h"
#include "stm32l4xx_timebase_lptim.h"

#define portMAX_16_BIT_NUMBER	       ( 0xffffUL )

extern LPTIM_HandleTypeDef             LptimHandle;

extern void EntryStopMode( void );
extern void ExitStopMode( void );

void vPortSetupTimerInterrupt( void );

#if( configUSE_TICKLESS_IDLE == 2 )

/*
 * Override the default definition of vPortSuppressTicksAndSleep() that is
 * weakly defined in the FreeRTOS Cortex-M port layer with a version that
 * manages the LPTIM clock, as the tick is generated from the low power LPTIM
 * and not the SysTick as would normally be the case on a Cortex-M.
 */
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );


/*-----------------------------------------------------------*/

/* Calculate how many clock increments make up a single tick period. */
//static const uint32_t ulReloadValueForOneTick = (LSI_VALUE / configTICK_RATE_HZ);

//static const uint32_t ulReloadValueForOneSec = LSI_VALUE;

static const uint32_t ulReloadValueForOneTick = (LSI_VALUE /2 / configTICK_RATE_HZ);

static const uint32_t ulReloadValueForOneSec = LSI_VALUE/2;

/* Will hold the maximum number of ticks that can be suppressed. */
static uint32_t xMaximumPossibleSuppressedTicks = 0;

/* Flag set from the tick interrupt to allow the stop processing to know if
stop mode was exited because of a timer interrupt or a different interrupt. */
volatile BaseType_t ulTickFlag = pdFALSE;

#endif


/*-----------------------------------------------------------*/

void vPortSetupTimerInterrupt( void )
{
  InitTick(configLIBRARY_LOWEST_INTERRUPT_PRIORITY);
	
#if( configUSE_TICKLESS_IDLE == 2 )

	/* The maximum number of ticks that can be suppressed depends on the clock
	frequency. */
	xMaximumPossibleSuppressedTicks = (portMAX_16_BIT_NUMBER * configTICK_RATE_HZ) / ulReloadValueForOneSec;
#endif	/* ( configUSE_TICKLESS_IDLE == 2 ) */
}



#if( configUSE_TICKLESS_IDLE == 2 )
/*-----------------------------------------------------------*/

void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
{
  uint32_t ulReloadValue, ulCompleteTickPeriods, ulCount;
  eSleepModeStatus eSleepAction;
	TickType_t xModifiableIdleTime;

	/* THIS FUNCTION IS CALLED WITH THE SCHEDULER SUSPENDED. */

	/* Make sure the LPTIM reload value does not overflow the counter. */
	if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
	{
		xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
	}

	/* Calculate the reload value required to wait xExpectedIdleTime tick periods. */
  ulReloadValue = (ulReloadValueForOneSec * (xExpectedIdleTime - 1UL))/configTICK_RATE_HZ;
	
	ulCount = HAL_LPTIM_ReadCounter(&LptimHandle);
	
	HAL_LPTIM_PWM_Stop_IT(&LptimHandle);

	/* Enter a critical section but don't use the taskENTER_CRITICAL() method as
	that will mask interrupts that should exit sleep mode. */
	__asm volatile ( "cpsid i" );
	__asm volatile( "dsb" );
	__asm volatile( "isb" );

	/* The tick flag is set to false before sleeping.  If it is true when sleep
	mode is exited then sleep mode was probably exited because the tick was
	suppressed for the entire xExpectedIdleTime period. */
	ulTickFlag = pdFALSE;

	/* If a context switch is pending then abandon the low power entry as the
	context switch might have been pended by an external interrupt that	requires
	processing. */
	eSleepAction = eTaskConfirmSleepModeStatus();
	if( eSleepAction == eAbortSleep )
	{
		/* Restart tick and continue counting to complete the current time
		slice. */
                __HAL_LPTIM_ENABLE_IT(&LptimHandle, LPTIM_IT_ARRM);
                __HAL_LPTIM_ENABLE(&LptimHandle);
                __HAL_LPTIM_AUTORELOAD_SET(&LptimHandle, ulCount);
                __HAL_LPTIM_COMPARE_SET(&LptimHandle, (ulCount/2));
                __HAL_LPTIM_START_CONTINUOUS(&LptimHandle);
         
		/* Re-enable interrupts  */
		__asm volatile ( "cpsie i" );
	}
	else
	{		
		
    /* Strat LPTIM Timeout wake up based on expected idle time */
    HAL_LPTIM_TimeOut_Start_IT(&LptimHandle, 0xFFFF, ulReloadValue);
		
		/* A user definable macro that allows application code to be inserted
		here.  Such application code can be used to minimise power consumption
		further by turning off IO, peripheral clocks, the Flash, etc. */
//		configPRE_STOP_PROCESSING();
		xModifiableIdleTime = xExpectedIdleTime;
//		PreSleepProcessing( &xModifiableIdleTime );
		EntryStopMode();

		/* There are no running state tasks and no tasks that are blocked with a
		time out.  Assuming the application does not care if the tick time slips
		with respect to calendar time then enter a deep sleep that can only be
		woken by (in this demo case) the user button being pushed on the
		STM32L discovery board.  If the application does require the tick time
		to keep better track of the calender time then the LPTIM peripheral can be
		used to make rough adjustments. */
                
    /* Enter STOP 1 mode */
//    HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);
		/* Enter STOP 1 mode */
		HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
                
		/* A user definable macro that allows application code to be inserted
		here.  Such application code can be used to reverse any actions taken
		by the configPRE_STOP_PROCESSING().  In this demo
		configPOST_STOP_PROCESSING() is used to re-initialise the clocks that
		were turned off when STOP mode was entered. */
//		configPOST_STOP_PROCESSING();
//		PostSleepProcessing( &xExpectedIdleTime );
		ExitStopMode();
		
		ulCount = HAL_LPTIM_ReadCounter(&LptimHandle);

                HAL_LPTIM_TimeOut_Stop_IT(&LptimHandle);

		/* Re-enable interrupts */
                __asm volatile ( "cpsie i" );
		
                if( ulTickFlag != pdFALSE )
		{
			ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
                        
                        __HAL_LPTIM_ENABLE_IT(&LptimHandle, LPTIM_IT_ARRM);
                        __HAL_LPTIM_ENABLE(&LptimHandle);
                        __HAL_LPTIM_AUTORELOAD_SET(&LptimHandle, ulReloadValueForOneTick);
                        __HAL_LPTIM_COMPARE_SET(&LptimHandle, (ulReloadValueForOneTick/2));
                        __HAL_LPTIM_START_CONTINUOUS(&LptimHandle);
                        
		}
		else
		{
			ulCompleteTickPeriods = (ulCount * configTICK_RATE_HZ)/ ulReloadValueForOneSec;
			ulReloadValue = (ulReloadValueForOneTick - ( ulCompleteTickPeriods % ulReloadValueForOneTick ));
                        
                        __HAL_LPTIM_ENABLE_IT(&LptimHandle, LPTIM_IT_ARRM);
                        __HAL_LPTIM_ENABLE(&LptimHandle);
                        __HAL_LPTIM_AUTORELOAD_SET(&LptimHandle, ulReloadValue);
                        __HAL_LPTIM_COMPARE_SET(&LptimHandle, (ulReloadValue/2));
                        __HAL_LPTIM_START_CONTINUOUS(&LptimHandle);                  
                        
		}
		
                /* update HAL base time */
                uwTick += ulCompleteTickPeriods;
                
		/* Wind the tick forward by the number of tick periods that the CPU
		remained in a low power state. */
		vTaskStepTick( ulCompleteTickPeriods );
	}
}
#endif /* ( configUSE_TICKLESS_IDLE == 2 ) */
	

stm32l4xx_timebase_lptim.c

可参考如下代码:

/**
  ******************************************************************************
  * @file    stm32l47xx_os_timebase_lptim.c 
  * @author  MCD Application Team
  * @brief   RTOS and HAL time base based on LPTIM.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_hal.h"
#include "FreeRTOS.h"
#include "task.h"
#include "stm32l4xx_timebase_lptim.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* Set the Maximum value of the counter (Auto-Reload) that defines the Period */
//#define PeriodValue             (uint32_t) (32)
#define PeriodValue             (uint32_t) (16)

/* Set the Compare value that defines the duty cycle */
//#define PulseValue              (uint32_t) (16)
#define PulseValue              (uint32_t) (8)

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* LPTIM handle declaration */
LPTIM_HandleTypeDef             LptimHandle;

__IO uint32_t ulTickInit = 0;

/* Clocks structure declaration */
RCC_PeriphCLKInitTypeDef        RCC_PeriphCLKInitStruct;

#if( configUSE_TICKLESS_IDLE == 2 )
extern uint32_t ulTickFlag;
#endif

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  This function configures the LPTIM to generate an interrupt each 1ms. 
  * @param  TickPriority: Tick interrupt priority.
  * @retval HAL status
*/
void InitTick (uint32_t TickPriority)
{
  RCC_OscInitTypeDef RCC_OscInitStruct;
  
  if(ulTickInit == 0)
  {
    /* Enable LSE clock */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
    RCC_OscInitStruct.LSIState = RCC_LSI_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
    
    /* ### - 1 - Re-target the LSE to Clock the LPTIM Counter ################# */
    /* Select the LSE clock as LPTIM peripheral clock */
    RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1;
    RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSI;  
    HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
    
    /* ### - 2 - Initialize LPTIM peripheral ################################## */
    /*
    *  Instance        = LPTIM1
    *  Clock Source    = APB or LowPowerOSCillator (in this example LSE is
    *                    already selected from the RCC stage)
    *  Clock prescaler = 1 (No division)
    *  Counter source  = Internal event.   
    *  Counter Trigger = Software trigger
    *  Output Polarity = High
    *  Update mode     = Immediate (Registers are immediately updated after any
    *                    write access) 
    */
    
    LptimHandle.Instance = LPTIM1;
    
    LptimHandle.Init.Clock.Source    = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
//    LptimHandle.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
		LptimHandle.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV2;
    LptimHandle.Init.CounterSource   = LPTIM_COUNTERSOURCE_INTERNAL;  
    LptimHandle.Init.Trigger.Source  = LPTIM_TRIGSOURCE_SOFTWARE; 
    LptimHandle.Init.OutputPolarity  = LPTIM_OUTPUTPOLARITY_HIGH;
    LptimHandle.Init.UpdateMode      = LPTIM_UPDATE_IMMEDIATE;
    LptimHandle.Init.Input1Source    = LPTIM_INPUT1SOURCE_GPIO;
    LptimHandle.Init.Input2Source    = LPTIM_INPUT2SOURCE_GPIO;
    
    /* Initialize LPTIM peripheral according to the passed parameters */
    if (HAL_LPTIM_Init(&LptimHandle) != HAL_OK)
    {
      while(1);
    }	
    
    /* Enable LPTIM NVIC Interrupt */
    HAL_NVIC_SetPriority(LPTIM1_IRQn, TickPriority, 0U);
    HAL_NVIC_EnableIRQ(LPTIM1_IRQn);
    
    /* ### - 3 - Start generating the PWM signal ############################## */
    /*
    *  Period = 31
    *  Pulse  = 15
    *  According to this configuration, the duty cycle will be equal to 50%
    */
    __HAL_LPTIM_ENABLE_IT(&LptimHandle, LPTIM_IT_ARRM);
    __HAL_LPTIM_ENABLE(&LptimHandle);
    __HAL_LPTIM_AUTORELOAD_SET(&LptimHandle, PeriodValue);
    __HAL_LPTIM_COMPARE_SET(&LptimHandle, PulseValue);
    __HAL_LPTIM_START_CONTINUOUS(&LptimHandle);  
    
    ulTickInit = 1;
  }
}

/**
  * @brief This function configures the source of the time base. 
  *        The time source is configured  to have 1ms time base with a dedicated 
  *        Tick interrupt priority. 
  * @param TickPriority: Tick interrupt priority.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority)
{
  InitTick(TickPriority);
	
  return HAL_OK;
}


void HAL_LPTIM_CompareMatchCallback(LPTIM_HandleTypeDef *hlptim)
{  
#if( configUSE_TICKLESS_IDLE == 2 )
  ulTickFlag = pdTRUE;
#endif
}

/*************************** Additional specific APIs to Free RTOS ************/
/**
* @brief  Handles the tick increment
* @param  none.
* @retval none.
*/
void osSystickHandler(void)
{

#if (INCLUDE_xTaskGetSchedulerState  == 1 )
  if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
  {
#endif  /* INCLUDE_xTaskGetSchedulerState */  
    xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState  == 1 )
  }
#endif  /* INCLUDE_xTaskGetSchedulerState */  
}

/**
  * @brief  Autoreload match callback in non blocking mode 
  * @param  hlptim : LPTIM handle
  * @retval None
  */
void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim)
{
  if (HAL_LPTIM_ReadAutoReload(hlptim) != PeriodValue)
  {
    __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_ARRM);
    __HAL_LPTIM_ENABLE(hlptim);
    __HAL_LPTIM_AUTORELOAD_SET(hlptim, PeriodValue);
    __HAL_LPTIM_COMPARE_SET(hlptim, (PulseValue));
    __HAL_LPTIM_START_CONTINUOUS(hlptim);  
  } 
  
  HAL_IncTick();
  osSystickHandler();
}

/**
  * @brief  This function handles  WAKE UP TIMER  interrupt request.
  * @param  None
  * @retval None
  */
void LPTIM1_IRQHandler(void)
{
  /* Compare match interrupt */
  if(__HAL_LPTIM_GET_FLAG(&LptimHandle, LPTIM_FLAG_CMPM) != RESET)
  {
      /* Clear Compare match flag */
      __HAL_LPTIM_CLEAR_FLAG(&LptimHandle, LPTIM_FLAG_CMPM);
      
      /* Compare match Callback */
      HAL_LPTIM_CompareMatchCallback(&LptimHandle);  
  }
  
  if(__HAL_LPTIM_GET_FLAG(&LptimHandle, LPTIM_FLAG_ARRM) != RESET)
  {
      /* Clear ARRM flag */
      __HAL_LPTIM_CLEAR_FLAG(&LptimHandle, LPTIM_FLAG_ARRM);
      
      /* ARRM Callback */
      HAL_LPTIM_AutoReloadMatchCallback(&LptimHandle);  
  }
  
}

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

stm32l4xx_timebase_lptim.h

可参考如下代码:

/**
  ******************************************************************************
  * @file    stm32l4xx_os_timebase_lptim.h 
  * @author  MCD Application Team
  * @brief   RTOS and HAL time base based on LPTIM header file.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2017 STMicroelectronics International N.V. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without 
  * modification, are permitted, provided that the following conditions are met:
  *
  * 1. Redistribution of source code must retain the above copyright notice, 
  *    this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright notice,
  *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
  * 3. Neither the name of STMicroelectronics nor the names of other 
  *    contributors to this software may be used to endorse or promote products 
  *    derived from this software without specific written permission.
  * 4. This software, including modifications and/or derivative works of this 
  *    software, must execute solely and exclusively on microcontroller or
  *    microprocessor devices manufactured by or for STMicroelectronics.
  * 5. Redistribution and use of this software other than as permitted under 
  *    this license is void and will automatically terminate your rights under 
  *    this license. 
  *
  * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" 
  * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT 
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
  * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
  * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT 
  * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */

#ifndef __RTOS_LPTIM_BASE_TIME_H
#define __RTOS_LPTIM_BASE_TIME_H

#ifdef __cplusplus
 extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_hal.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void InitTick (uint32_t TickPriority);
void LPTIM1_IRQHandler(void);
  
#ifdef __cplusplus
}
#endif

#endif /* */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

我的项目LPTIM1的时钟源为LSI,二分频。

STM32Cube_FW_L4_V1.13.0网盘链接:链接:https://pan.baidu.com/s/1FmC5umQaWGGC9iA4vT6IxA 
提取码:lax5 


技术交流群

STM32MP1:861926625

ESP8266:476685983


路过

雷人

握手

鲜花

鸡蛋

最新评论

QQ|Archiver|手机版|小黑屋|火柴棍 ( 蜀ICP备16031705号-1 )

GMT+8, 2023-2-1 13:22 , Processed in 0.134193 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

返回顶部