RLT8762D Timer模块

发布时间:2024年01月12日

0 Preface/Foreword

TIM:Timer

1 Data struct

1.1?TIM_TimeBaseInitTypeDef

/**
?* \brief ? ? ? TIM init structure definition
?*
?* \ingroup ? ? TIM_Exported_Types
?*/
typedef struct
{
? ? uint16_t TIM_ClockSrc; ? ? ? ? ?/*!< <b>Deprecated</b> use RCC instead.*/
? ? uint16_t TIM_DIV; ? ? ? ? ? ? ? /*!< Clock fix at 40Mhz,add this parameter div the clock*/
? ? uint16_t TIM_SOURCE_DIV; ? ? ? ?/*!< Specifies the clock source div.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref TIM_Clock_Divider*/
? ? uint16_t TIM_SOURCE_DIV_En; ? ? /*!< Timer source clock div enable. */
? ? uint16_t TIM_Mode; ? ? ? ? ? ? ?/*!< Specifies the counter mode.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref TIM_Mode. */
? ? uint16_t TIM_PWM_En; ? ? ? ? ? ?/*!< Specifies the PWM mode.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of DISABLE or ENABLE */
? ? uint32_t TIM_Period; ? ? ? ? ? ?/*!< Specifies the period value to be loaded into the active
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Auto-Reload Register at the next update event.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter must range from 0x0000 to 0xFFFFFFFF. */
? ? uint32_t TIM_PWM_High_Count; ? ?/*!< Specifies the PWM High Count.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter must range from 0x0000 to 0xFFFFFFFF. */
? ? uint32_t TIM_PWM_Low_Count; ? ? /*!< Specifies the PWM Low Count.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter must range from 0x0000 to 0xFFFFFFFF. */
? ? uint32_t TIM_EventMode; ? ? ? ? /*!< Specifies the TIM event mode. */
? ? uint32_t TIM_EventIndex; ? ? ? ?/*!< Specifies the TIM event index. */
? ? uint32_t TIM_EventDuration; ? ? /*!< Specifies the TIM event duration.*/
? ? uint8_t ?ClockDepend; ? ? ? ? ? /*!< Specifies TIM Source depend.timer3 depend timer2 ,timer5 depend timer4, timer7 depend timer6.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of ENABLE or DISABLE */
? ? uint32_t PWM_Deazone_Size; ? ? ?/*!<Size of deadzone time, DeadzoneTime=deadzonesize/32000 or 32768.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter must range from 1 to 0xffffffff. */
? ? uint16_t PWMDeadZone_En; ? ? ? ?/*!<PWM Deadzone enable, pwm0_pn: timer2, pwm1_pn:timer3
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of ENABLE or DISABLE. */
? ? uint16_t PWM_Stop_State_P; ? ? ?/*!< Specifies the PWM P stop state.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref PWMDeadZone_Stop_state. */
? ? uint16_t PWM_Stop_State_N; ? ? ?/*!< Specifies the PWM N stop state.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref PWMDeadZone_Stop_state. */
} TIM_TimeBaseInitTypeDef;

1.2?TIM_TypeDef

/**
? * @brief TIM
? */
typedef struct
{
? ? __IO uint32_t LoadCount; ? ? ? ?/*!< 0x00*/
? ? __I ?uint32_t CurrentValue; ? ? /*!< 0x04*/
? ? __IO uint32_t ControlReg; ? ? ? /*!< 0x08*/
? ? __I ?uint32_t EOI; ? ? ? ? ? ? ?/*!< 0x0C*/
? ? __I ?uint32_t IntStatus; ? ? ? ?/*!< 0x10*/
} TIM_TypeDef;

2 Code analysis

2.1?TIM_StructInit

/**
?* \brief ? Fills each TIM_InitStruct member with its default value.
?* \param[in] TIM_TimeBaseInitStruct: Pointer to a TIM_TimeBaseInitTypeDef structure which will be initialized.
?* \return ?None.
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void driver_timer_init(void)
?* {
?* ? ? RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
?*
?* ? ? TIM_TimeBaseInitTypeDef TIM_InitStruct;
?* ? ? TIM_StructInit(&TIM_InitStruct);
?*
?* ? ? TIM_InitStruct.TIM_PWM_En = PWM_DISABLE;
?* ? ? TIM_InitStruct.TIM_Period = 1000000 - 1;
?* ? ? TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
?* ? ? TIM_TimeBaseInit(TIM6, &TIM_InitStruct);
?* }
?* \endcode
?*/
void TIM_StructInit(TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct);

/**
? * @brief ?Fills each TIM_InitStruct member with its default value.
? * @param ?TIM_InitStruct : pointer to a TIM_InitTypeDef structure which will be initialized.
? * @retval None
? */
void TIM_StructInit(TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct)
{
? ? TIM_TimeBaseInitStruct->TIM_Mode = TIM_Mode_UserDefine;
? ? TIM_TimeBaseInitStruct->TIM_Period = 0xfff;
? ? TIM_TimeBaseInitStruct->TIM_SOURCE_DIV = TIM_CLOCK_DIVIDER_1;
? ? TIM_TimeBaseInitStruct->ClockDepend = false;
? ? TIM_TimeBaseInitStruct->TIM_PWM_En = PWM_DISABLE;
? ? TIM_TimeBaseInitStruct->PWM_Stop_State_P = PWM_STOP_AT_LOW;
? ? TIM_TimeBaseInitStruct->PWM_Stop_State_N = PWM_STOP_AT_HIGH;
? ? TIM_TimeBaseInitStruct->PWMDeadZone_En = DEADZONE_DISABLE;
}

2.2?TIM_TimeBaseInit

/**
?* \brief ? Initialize the TIMx time base unit peripheral according to
?* ? ? ? ? ?the specified parameters in TIM_TimeBaseInitStruct.
?* \param[in] TIMx: where x can be 0 to 7 to select the TIM peripheral.
?* \param[in] TIM_TimeBaseInitStruct: Pointer to a TIM_TimeBaseInitTypeDef
?* ? ? ? ? ? ?structure that contains the configuration information for the selected TIM peripheral.
?* \return ?None.
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void driver_timer_init(void)
?* {
?* ? ? RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
?*
?* ? ? TIM_TimeBaseInitTypeDef TIM_InitStruct;
?* ? ? TIM_StructInit(&TIM_InitStruct);
?*
?* ? ? TIM_InitStruct.TIM_PWM_En = PWM_DISABLE;
?* ? ? TIM_InitStruct.TIM_Period = 1000000 - 1 ;
?* ? ? TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
?* ? ? TIM_TimeBaseInit(TIMER_NUM, &TIM_InitStruct);
?* }
?* \endcode
?*/
void TIM_TimeBaseInit(TIM_TypeDef *TIMx, TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct);

/**
? * @brief ?Initializes the TIMx Time Base Unit peripheral according to
? * ? ? ? ? the specified parameters in the TIM_TimeBaseInitStruct.
? * @param ?TIMx: where x can be 0 to 7 to select the TIM peripheral.
? * @param ?TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef
? * ? ? ? ? structure that contains the configuration information for the
? * ? ? ? ? specified TIM peripheral.
? * @retval None
? */
void TIM_TimeBaseInit(TIM_TypeDef *TIMx, TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct)
{
? ? uint32_t timerid = 0;
? ? uint32_t tempreg = 0;
? ? volatile uint32_t *count2_address;

? ? /* Check the parameters */
? ? assert_param(IS_TIM_ALL_PERIPH(TIMx));
? ? assert_param(IS_TIM_MODE(TIM_TimeBaseInitStruct->TIM_Mode));
? ? assert_param(IS_TIM_PWM_DeadZone_En(TIM_TimeBaseInitStruct->PWMDeadZone_En));

? ? /* Select clock source which can be system clock or 40 MHz ?or pll*/
? ? tempreg = (uint32_t)TIMx;
? ? timerid = (tempreg - TIM0_REG_BASE) / 20;

? ? /*div the clock source,actually it need enable TIM_SOURCE_CLOCK_DIV_EN*/
? ? TIMER_CLK_SOURCE_REG_360 |= BIT9;

? ? if (TIMER_CLK_SOURCE_REG_360 & BIT(10))
? ? {
? ? ? ? TIMER_CLK_SOURCE_REG_360 &= ~(BIT(10));
? ? }

? ? if (timerid < 2)
? ? {
? ? ? ? TIMER_CLK_SOURCE_REG_360 &= ~(0x7 << (timerid * 3));
? ? ? ? TIMER_CLK_SOURCE_REG_360 |= ((TIM_TimeBaseInitStruct->TIM_SOURCE_DIV) << (timerid * 3));
? ? }
? ? else if ((timerid >= 2) && (timerid < 8))
? ? {
? ? ? ? TIMER_CLK_SOURCE_REG_360 &= ~(0x7 << (((timerid - 2) * 3) + 13));
? ? ? ? TIMER_CLK_SOURCE_REG_360 |= ((TIM_TimeBaseInitStruct->TIM_SOURCE_DIV) << (((
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?timerid - 2) * 3) + 13));
? ? }

? ? if (timerid == 3 || timerid == 5 || timerid == 7)
? ? {
? ? ? ? if (TIM_TimeBaseInitStruct->ClockDepend == true)
? ? ? ? {
? ? ? ? ? ? TIMER_CLK_SOURCE_REG_35C |= BIT(((timerid - 1) >> 1) - 1);
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? TIMER_CLK_SOURCE_REG_35C &= ~BIT(((timerid - 1) >> 1) - 1);
? ? ? ? }
? ? }

? ? /* set timer mode and mask interrupt */
? ? if (TIM_TimeBaseInitStruct->TIM_PWM_En == PWM_DISABLE)
? ? {
? ? ? ? TIMx->ControlReg = (TIM_TimeBaseInitStruct->TIM_Mode << 1) | BIT(2);
? ? ? ? /* set timer period */
? ? ? ? TIMx->LoadCount = TIM_TimeBaseInitStruct->TIM_Period;
? ? }
? ? else
? ? {
? ? ? ? TIMx->ControlReg = (TIM_TimeBaseInitStruct->TIM_Mode << 1) | BIT(2) | BIT(3);
? ? ? ? count2_address = &TIMER0_LOAD_COUNT2;
? ? ? ? count2_address = count2_address + timerid;
? ? ? ? *count2_address = TIM_TimeBaseInitStruct->TIM_PWM_High_Count ;
? ? ? ? /* set timer period */
? ? ? ? TIMx->LoadCount = TIM_TimeBaseInitStruct->TIM_PWM_Low_Count;
? ? }

? ? /* set pwm deadzone mode, pwm0_pn based on timer2, and pwm1_pn based on timer3 */
? ? if (TIM_TimeBaseInitStruct->PWMDeadZone_En == ENABLE)
? ? {
? ? ? ? if (timerid ?== 2)
? ? ? ? {
? ? ? ? ? ? /* set pwm deadzone time */
? ? ? ? ? ? TIMER_PWM0_CR = ((TIM_TimeBaseInitStruct->PWM_Deazone_Size) \
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| (TIM_TimeBaseInitStruct->PWM_Stop_State_N << 9) \
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| (TIM_TimeBaseInitStruct->PWM_Stop_State_P << 10) \
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| BIT12 | BIT17 | BIT18);
? ? ? ? }
? ? ? ? else if (timerid == 3)
? ? ? ? {
? ? ? ? ? ? /* set pwm deadzone time */
? ? ? ? ? ? TIMER_PWM1_CR = ((TIM_TimeBaseInitStruct->PWM_Deazone_Size) \
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| (TIM_TimeBaseInitStruct->PWM_Stop_State_N << 9) \
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| (TIM_TimeBaseInitStruct->PWM_Stop_State_P << 10) \
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| BIT12 | BIT17 | BIT18);
? ? ? ? }
? ? }
? ? else
? ? {
? ? ? ? if (timerid == 2)
? ? ? ? {
? ? ? ? ? ? /*disable pwm0 deadzone mode*/
? ? ? ? ? ? TIMER_PWM0_CR &= ~(BIT12 | BIT17 | BIT18);
? ? ? ? }
? ? ? ? else if (timerid == 3)
? ? ? ? {
? ? ? ? ? ? /*disable pwm1 deadzone mode*/
? ? ? ? ? ? TIMER_PWM1_CR &= ~(BIT12 | BIT17 | BIT18);
? ? ? ? }
? ? }

? ? /* Clear the IT status */
? ? TIMx->EOI;
}
?

2.3?TIM_ClearINT

/**
?* \brief ? Clear TIM interrupt.
?* \param[in] ? TIMx: Where x can be 0 to 7 to select the TIMx peripheral.
?* \return ?None.
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void timer_demo(void)
?* {
?* ? ? TIM_ClearINT(TIM6);
?* }
?* \endcode
?*/
__STATIC_INLINE void TIM_ClearINT(TIM_TypeDef *TIMx)
{
? ? /* Check the parameters */
? ? assert_param(IS_TIM_ALL_PERIPH(TIMx));
? ? /* Clear the IT */
? ? TIMx->EOI;
}

2.4?TIM_INTConfig


/**
?* \brief ? Enables or disables the specified TIMx interrupt.
?* \param[in] ? TIMx: Where x can be 0 to 7 to select the TIMx peripheral.
?* \param[in] ? NewState: New state of the TIMx peripheral.
?* ? ? ?This parameter can be: ENABLE or DISABLE.
?* \return ?None.
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void driver_timer_init(void)
?* {
?* ? ? RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
?*
?* ? ? TIM_TimeBaseInitTypeDef TIM_InitStruct;
?* ? ? TIM_StructInit(&TIM_InitStruct);
?*
?* ? ? TIM_InitStruct.TIM_PWM_En = PWM_DISABLE;
?* ? ? TIM_InitStruct.TIM_Period = 1000000 - 1;
?* ? ? TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
?* ? ? TIM_TimeBaseInit(TIM6, &TIM_InitStruct);
?* ? ? TIM_ClearINT(TIM6);
?* ? ? TIM_INTConfig(TIM6, ENABLE);
?*/
void TIM_INTConfig(TIM_TypeDef *TIMx, FunctionalState NewState);

/**
? * @brief ?Enables or disables the specified TIMx interrupt.
? * @param ?TIMx: where x can be 0 to 7 to select the TIMx peripheral.
? * @param ?NewState: new state of the TIMx peripheral.
? * ? This parameter can be: ENABLE or DISABLE.
? * @retval None
? */
void TIM_INTConfig(TIM_TypeDef *TIMx, FunctionalState NewState)
{
? ? /* Check the parameters */
? ? assert_param(IS_TIM_ALL_PERIPH(TIMx));

? ? if (NewState != DISABLE)
? ? {
? ? ? ? /* Enable the Interrupt sources */
? ? ? ? TIMx->ControlReg &= ~(BIT(2));
? ? }
? ? else
? ? {
? ? ? ? /* Disable the Interrupt sources */
? ? ? ? TIMx->ControlReg |= BIT(2);
? ? }
}

2.5?TIM_Cmd

?/**
?* \brief ? Enables or disables the specified TIM peripheral.
?* \param[in] TIMx: Where x can be 0 to 7 to select the TIMx peripheral.
?* \param[in] NewState: New state of the TIMx peripheral.
?* ? ? ?This parameter can be: ENABLE or DISABLE.
?* \return ?None.
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void driver_timer_init(void)
?* {
?* ? ? RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);
?*
?* ? ? TIM_TimeBaseInitTypeDef TIM_InitStruct;
?* ? ? TIM_StructInit(&TIM_InitStruct);
?*
?* ? ? TIM_InitStruct.TIM_PWM_En = PWM_DISABLE;
?* ? ? TIM_InitStruct.TIM_Period = 1000000 - 1;
?* ? ? TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
?* ? ? TIM_TimeBaseInit(TIM6, &TIM_InitStruct);
?* ? ? TIM_Cmd(TIM6, ENABLE);
?* }
?* \endcode
?*/
void TIM_Cmd(TIM_TypeDef *TIMx, FunctionalState NewState);

/**
? * @brief ?Enables or disables the specified TIM peripheral.
? * @param ?TIMx: where x can be 0 to 7 to select the TIMx peripheral.
? * @param ?NewState: new state of the TIMx peripheral.
? * ? This parameter can be: ENABLE or DISABLE.
? * @retval None
? */
void TIM_Cmd(TIM_TypeDef *TIMx, FunctionalState NewState)
{
? ? /* Check the parameters */
? ? assert_param(IS_TIM_ALL_PERIPH(TIMx));
? ? assert_param(IS_FUNCTIONAL_STATE(NewState));

? ? if (NewState != DISABLE)
? ? {
? ? ? ? /* Enable the TIM Counter */
? ? ? ? TIMx->ControlReg |= BIT(0);
? ? }
? ? else
? ? {
? ? ? ? /* Disable the TIM Counter */
? ? ? ? TIMx->ControlReg &= ~(BIT(0));
? ? }
}

2.6?TIM_ChangePeriod

/**
?* \brief ? Change TIM period value.
?* \param[in] ? TIMx: Where x can be 0 to 7 to select the TIMx peripheral.
?* \param[in] ? period: Period value to be changed.
?* \return ?None.
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void timer_demo(void)
?* {
?* ? ? uint32_t new_period = 1000000 - 1;
?* ? ? TIM_Cmd(TIM6, DISABLE);
?* ? ? TIM_ChangePeriod(TIM6, new_period);
?*
?* }
?* \endcode
?*/
void TIM_ChangePeriod(TIM_TypeDef *TIMx, uint32_t period);?

/**
? * @brief ?change TIM period value.
? * @param ?TIMx: where x can be 0 to 7 to select the TIMx peripheral.
? * @retval The new state of success or not ?(SET or RESET).
? */
void TIM_ChangePeriod(TIM_TypeDef *TIMx, uint32_t period)
{
? ? /* Check the parameters */
? ? assert_param(IS_TIM_ALL_PERIPH(TIMx));

? ? TIMx->LoadCount = period;

? ? return;
}

3 Example

3.1 定时器使用方法?

启动定时器前

  • 清理中断标志位
  • 使能中断
  • 使能定时器

进入定时器处理程序

  • ?清理中断标志位
  • 关闭定时器
  • 处理自己事情
  • 使能定时器
文章来源:https://blog.csdn.net/yanlaifan/article/details/135542790
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。