1. 程式人生 > >STM32定時器 相關函式介紹

STM32定時器 相關函式介紹

相關具體內容參考 stm32f4xx_hal_time.h
幾種模式函式的型別都差不多,包括基本型別(Base),輸出比較(OC),輸入捕獲(IC),pwm(PWM),單脈衝(One_Pulse)和編碼器(Encoder)。

/******  xxx使用上述幾種模式的英文替換即可*******/
HAL_TIM_xxx_Init
HAL_TIM_xxx_DeInit

HAL_TIM_xxx_MspInit
HAL_TIM_xxx_MspDeInit
/*********輪詢方式啟動/停止******/
HAL_TIM_xxx_Start
HAL_TIM_xxx_Stop
/*********中斷方式啟動/停止******/
HAL_TIM_xxx_Start_IT
HAL_TIM_xxx_Stop_IT
/**********DMA方式啟動/停止******/
HAL_TIM_xxx_Start_DMA
HAL_TIM_xxx_Stop_DMA


定時器基本函式:

/* Time Base functions ********************************************************/
HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim);
HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim);
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim);
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim);
/* Blocking mode: Polling */
HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim);
HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim);
/* Non-Blocking mode: Interrupt */
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim);
/* Non-Blocking mode: DMA */
HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length);
HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim);



輸出比較模式:

/* Timer Output Compare functions **********************************************/
HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim);
HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim);
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim);
void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim);
/* Blocking mode: Polling  輪詢模式*/

HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
/* Non-Blocking mode: Interrupt 中斷模式 */

HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
/* Non-Blocking mode: DMA DMA模式*/

HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);


PWM模式:
/* Timer PWM functions *********************************************************/
HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim);
HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim);
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim);
void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim);
/* Blocking mode: Polling */
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
/* Non-Blocking mode: Interrupt */
HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
/* Non-Blocking mode: DMA */
HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);

輸入捕獲模式:
/* Timer Input Capture functions ***********************************************/
HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim);
HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim);
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim);
void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim);
/* Blocking mode: Polling */
HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
/* Non-Blocking mode: Interrupt */
HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
/* Non-Blocking mode: DMA */
HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
單脈衝模式:

/* Timer One Pulse functions ***************************************************/
HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode);
HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim);
void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim);
void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim);
/* Blocking mode: Polling */
HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel);

/* Non-Blocking mode: Interrupt */
HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel);



編碼器模式

/* Timer Encoder functions *****************************************************/
HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim,  TIM_Encoder_InitTypeDef* sConfig);
HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim);
void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim);
void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim);
 /* Blocking mode: Polling */
HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
/* Non-Blocking mode: Interrupt */
HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
/* Non-Blocking mode: DMA */
HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1, uint32_t *pData2, uint16_t Length);
HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
中斷處理函式:

/* Interrupt Handler functions  **********************************************/
void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim);

控制函式:
/* Control functions  *********************************************************/
HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef* sConfig, uint32_t Channel);//配置輸出比較通道
HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef* sConfig, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_IC_InitTypeDef* sConfig, uint32_t Channel);
HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef* sConfig, uint32_t OutputChannel,  uint32_t InputChannel);


HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim, TIM_ClearInputConfigTypeDef * sClearInputConfig, uint32_t Channel);
//時鐘源配置函式
HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, TIM_ClockConfigTypeDef * sClockSourceConfig);
    
HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection);
HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchronization(TIM_HandleTypeDef *htim, TIM_SlaveConfigTypeDef * sSlaveConfig);
HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchronization_IT(TIM_HandleTypeDef *htim, TIM_SlaveConfigTypeDef * sSlaveConfig);
HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc,  uint32_t  *BurstBuffer, uint32_t  BurstLength);
HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc);
HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc, uint32_t  *BurstBuffer, uint32_t  BurstLength);
HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc);


HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource);
uint32_t HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel);

回撥函式:

/* Callback in non blocking modes (Interrupt and DMA) *************************/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);//週期結束時呼叫。
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim); //CCR匹配即翻轉時,發生呼叫。
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim); 
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim);
void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim);
void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim);

狀態函式:

/* Peripheral State functions  就是獲取相應TIM_HandleTypeDef控制代碼結構的state成員**************************************************/
HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(TIM_HandleTypeDef *htim);
HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(TIM_HandleTypeDef *htim);
HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(TIM_HandleTypeDef *htim);
HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(TIM_HandleTypeDef *htim);
HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(TIM_HandleTypeDef *htim);
HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(TIM_HandleTypeDef *htim);
還有幾個巨集定義是為了獲取和設定計時器相關的暫存器的值(CCR ,CNT,ARR )

Capture Compare Register(CCR):
#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \
(*(__IO uint32_t *)(&((__HANDLE__)->Instance->CCR1) + ((__CHANNEL__) >> 2U)) = (__COMPARE__))

#define __HAL_TIM_GET_COMPARE(__HANDLE__, __CHANNEL__) \
  (*(__IO uint32_t *)(&((__HANDLE__)->Instance->CCR1) + ((__CHANNEL__) >> 2U)))
Counter Register(CNT):
#define __HAL_TIM_SET_COUNTER(__HANDLE__, __COUNTER__) ((__HANDLE__)->Instance->CNT = (__COUNTER__))
#define __HAL_TIM_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNT)
Autoreload Register(ARR):
#define __HAL_TIM_SET_AUTORELOAD(__HANDLE__, __AUTORELOAD__)                  \
                        do{                                                  \
                            (__HANDLE__)->Instance->ARR = (__AUTORELOAD__);  \
                            (__HANDLE__)->Init.Period = (__AUTORELOAD__);    \
                          } while(0U)
#define __HAL_TIM_GET_AUTORELOAD(__HANDLE__) ((__HANDLE__)->Instance->ARR)
TIM Clock Division value:
#define __HAL_TIM_GET_CLOCKDIVISION(__HANDLE__) ((__HANDLE__)->Instance->CR1 & TIM_CR1_CKD)

#define __HAL_TIM_SET_CLOCKDIVISION(__HANDLE__, __CKD__) \
                        do{                                                             \
                              (__HANDLE__)->Instance->CR1 &= (uint16_t)(~TIM_CR1_CKD);  \
                              (__HANDLE__)->Instance->CR1 |= (__CKD__);                 \
                              (__HANDLE__)->Init.ClockDivision = (__CKD__);             \
                          } while(0U)
TIM Input Capture prescaler:

#define __HAL_TIM_SET_ICPRESCALER(__HANDLE__, __CHANNEL__, __ICPSC__) \
                        do{                                                    \
                              TIM_RESET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__));  \
                              TIM_SET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__), (__ICPSC__)); \
                          } while(0U)

#define __HAL_TIM_GET_ICPRESCALER(__HANDLE__, __CHANNEL__)  \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC1PSC) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? (((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC2PSC) >> 8U) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC3PSC) :\
   (((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC4PSC)) >> 8U)
    

具體程式碼分析:

一、針對初始化函式  HAL_TIM_xxx_Init()

對於基本型別(Base),輸出比較(OC),輸入捕獲(IC),pwm(PWM)  四種基本型別,
HAL_TIM_xxx_Init函式具有相同的函式結構,下面以兩個例子說明
以IC模式的原始碼為例:
HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim)
{
  /* Check the TIM handle allocation */
  if(htim == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the parameters */
  assert_param(IS_TIM_INSTANCE(htim->Instance));
  assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
  assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); 

  if(htim->State == HAL_TIM_STATE_RESET)
  { 
    /* Allocate lock resource and initialize it */
    htim->Lock = HAL_UNLOCKED;
    /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
    HAL_TIM_XXX_MspInit(htim);          //這裡有區別
  }
  
  /* Set the TIM state */
  htim->State= HAL_TIM_STATE_BUSY;   
  
  /* Init the base time for the input capture */  
  TIM_Base_SetConfig(htim->Instance, &htim->Init);    //重要部分
   
  /* Initialize the TIM state*/
  htim->State= HAL_TIM_STATE_READY;
  
  return HAL_OK;
}
關鍵程式碼步驟說明:
(1)HAL_TIM_xxx_MspInit(htim)  
(2)將狀態設定為BUSY。  htim->State= HAL_TIM_STATE_BUSY;
(3)TIM_Base_SetConfig(htim->Instance, &htim->Init);              //主要函式

(4)將狀態設定為READYhtim->State= HAL_TIM_STATE_READY;

TIM_Base_SetConfig(htim->Instance, &htim->Init)函式功能:

(1)設定控制暫存器 CR1(包括計數方向、計數對齊模式、時鐘分頻三個)
(2)設定自動過載暫存器 ARR 。// TIMx->ARR = (uint32_t)Structure->Period ;
(3)設定預分頻暫存器 PSC
(4)設定重複計數器暫存器RCR
(5)觸發更新事件,載入預分頻器與重複計數器的值。TIMx->EGR = TIM_EGR_UG;


單脈衝(One_Pulse)和編碼器(Encoder)與上函式具有相似的結構,

對於單脈衝模式,初始化函式為:
HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode)
TIM_Base_SetConfig(htim->Instance, &htim->Init);相對於前面的基本函式,後面還需要加上一步
 /* Reset the OPM Bit */
  htim->Instance->CR1 &= ~TIM_CR1_OPM;
 /* Configure the OPM Mode */
  htim->Instance->CR1 |= OnePulseMode;
即設定CR1的第三位:
    OPM:單脈衝模式 (One pulse mode)
        0
:計數器在發生更新事件時不會停止計數

        1:計數器在發生下一更新事件時停止計數(將CEN位清零)
函式引數的第二個引數就是為了設定CR1的第三位。
可以使用的值為:

         #define TIM_OPMODE_SINGLE                    0x00001000U
         #define TIM_OPMODE_REPETITIVE              0x00000000U


對於編碼器模式,初始化函式為:
HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim,  TIM_Encoder_InitTypeDef* sConfig);
針對編碼器模式,相對於第一種簡單的初始化模式,還需要新增以下的初始化程式碼:
/*1、SMCR的SMS位來選擇編碼器模式*************************/	
/* Reset the SMS bits */
  htim->Instance->SMCR &= ~TIM_SMCR_SMS;
/* Get the TIMx SMCR register value */
  tmpsmcr = htim->Instance->SMCR;	
 /* Set the encoder Mode */
  tmpsmcr |= sConfig->EncoderMode;

/*2、通道對映    CC1通道為輸入,IC1對映到TI1上C2通道為輸入,IC2對映到TI2上*/
/* Get the TIMx CCMR1 register value */
tmpccmr1 = htim->Instance->CCMR1;
/* Select the Capture Compare 1 and the Capture Compare 2 as input */
 tmpccmr1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC2S);         //先清零

 tmpccmr1 |= (sConfig->IC1Selection | (sConfig->IC2Selection << 8U));     //通道對映

/* 3、設定預分頻和濾波  Set the Capture Compare 1 and the Capture Compare 2 prescalers and filters */
  tmpccmr1 &= ~(TIM_CCMR1_IC1PSC | TIM_CCMR1_IC2PSC);
  tmpccmr1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_IC2F);//後面6位全部清零

  tmpccmr1 |= sConfig->IC1Prescaler | (sConfig->IC2Prescaler << 8U);        //預分頻
  tmpccmr1 |= (sConfig->IC1Filter << 4U) | (sConfig->IC2Filter << 12U);     //無濾波
	
/* 4、Set the TI1 and the TI2 Polarities  設定極性  上升沿觸發*/
/* Get the TIMx CCER register value */
tmpccer = htim->Instance->CCER;
tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC2P);           //先清零
tmpccer &= ~(TIM_CCER_CC1NP | TIM_CCER_CC2NP);         //先清零

tmpccer |= sConfig->IC1Polarity | (sConfig->IC2Polarity << 4U);
  
/* Write to TIMx SMCR */
htim->Instance->SMCR = tmpsmcr;

/* Write to TIMx CCMR1 */
htim->Instance->CCMR1 = tmpccmr1;

/* Write to TIMx CCER */
htim->Instance->CCER = tmpccer;

暫存器的配置步驟如下:

(1)SMCR的SMS位來選擇編碼器模式   
               tmpsmcr |=  sConfig->EncoderMode;
(2)通道對映    CC1通道為輸入,IC1對映到TI1上  C2通道為輸入,IC2對映到TI2上 
               tmpccmr1 |= (sConfig->IC1Selection | (sConfig->IC2Selection << 8U));
                     
(3)設定預分頻和濾波
               tmpccmr1 |= sConfig->IC1Prescaler |(sConfig->IC2Prescaler << 8U);//預分頻
               tmpccmr1 |= (sConfig->IC1Filter << 4U) | (sConfig->IC2Filter << 12U);//無濾波
(4)設定觸發極性  上升沿觸發
               tmpccer |= sConfig->IC1Polarity | (sConfig->IC2Polarity << 4U);

(6)將配置好的引數寫入到暫存器中
上面引數的引數的傳遞是使用TIM_Encoder_InitTypeDef結構體(九個引數全部用到)。結構體的具體定義如下:

typedef struct
{
  uint32_t EncoderMode;   /*!< Specifies the active edge of the input signal.
                               This parameter can be a value of @ref TIM_Encoder_Mode */
                                  
  uint32_t IC1Polarity;   /*!< Specifies the active edge of the input signal.
                               This parameter can be a value of @ref TIM_Input_Capture_Polarity */

  uint32_t IC1Selection;  /*!< Specifies the input.
                               This parameter can be a value of @ref TIM_Input_Capture_Selection */

  uint32_t IC1Prescaler;  /*!< Specifies the Input Capture Prescaler.
                               This parameter can be a value of @ref TIM_Input_Capture_Prescaler */

  uint32_t IC1Filter;     /*!< Specifies the input capture filter.
                               This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
                                  
  uint32_t IC2Polarity;   /*!< Specifies the active edge of the input signal.
                               This parameter can be a value of @ref TIM_Input_Capture_Polarity */

  uint32_t IC2Selection;  /*!< Specifies the input.
                              This parameter can be a value of @ref TIM_Input_Capture_Selection */

  uint32_t IC2Prescaler;  /*!< Specifies the Input Capture Prescaler.
                               This parameter can be a value of @ref TIM_Input_Capture_Prescaler */

  uint32_t IC2Filter;     /*!< Specifies the input capture filter.
                               This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
} TIM_Encoder_InitTypeDef;

各種功能的配置只需要按照結構體結構來填充內容,然後呼叫相應的初始化函式即可。

二、針對輪詢啟動函式

1、對於基本模型,具體程式碼如下:

HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim)
{
  /* Check the parameters */
  assert_param(IS_TIM_INSTANCE(htim->Instance));
  
  /* Set the TIM state */
  htim->State= HAL_TIM_STATE_BUSY;
  
  /* Enable the Peripheral */
  __HAL_TIM_ENABLE(htim);
  
  /* Change the TIM state*/
  htim->State= HAL_TIM_STATE_READY;
  
   return HAL_OK;
}

 整個函式的核心程式碼只有一行 __HAL_TIM_ENABLE(htim);。 
  跳轉到__HAL_TIM_ENABLE函式的具體實現,可以看到函式其實是一個巨集定義:

#define __HAL_TIM_ENABLE(__HANDLE__)   ((__HANDLE__)->Instance->CR1|=(TIM_CR1_CEN))  //設定CR1的計數器使能位為1即可。
函式實現步驟__HAL_TIM_ENABLE(htim);   //計數器使能位為1即可

2、對於輸出比較模式
HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)

 TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
  
  if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET)  
  {
    /* Enable the main output */
    __HAL_TIM_MOE_ENABLE(htim);
  }
函式實現步驟
(1)使能定時器的輸出比較通道。  TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
(2)主輸出使能。    __HAL_TIM_MOE_ENABLE(htim);----針對高階計數器TIM1和TIM8。
(3)計數器使能位為1即可。 __HAL_TIM_ENABLE(htim);

3、對於PWM啟動函式與上相同。

HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);

4、對於輸入捕獲模式啟動函式比上面少一步。

HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);

函式實現步驟
(1)使能定時器的輸入捕獲通道。  TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
(2)計數器使能位為1即可。 __HAL_TIM_ENABLE(htim);


5、對於單脈衝模式,需要使能 兩個通道。

HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
模式說明:
(1)在OPM模式下,可以使用的兩個可能的通道是TIM_CHANNEL_1和TIM_CHANNEL_2。
(2)如果TIM_CHANNEL_1被用作輸出,TIM_CHANNEL_2將被用作輸入,並且如果TIM_CHANNEL_1被用作輸入,則TIM_CHANNEL_2將被用作所有組合的輸出,
(3)應同時使能TIM_CHANNEL_1和TIM_CHANNEL_2,無需啟用計數器,硬體會自動啟用該計數器。計數器會響應刺激而啟動並生成一個脈衝
函式實現步驟
(1)使能通道1。    TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); 
(2)使能通道2。     TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); 
(3)使能主輸出通道。      __HAL_TIM_MOE_ENABLE(htim);

6、對於編碼器需要根據編碼器計數的方式選擇使能合適的通道。

HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
(1)使能輸入輸出通道。使能一個或者兩個都使能。
    TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
     TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
(2)計數器使能位為1即可。 __HAL_TIM_ENABLE(htim);

二、針對中斷方式的啟動函式

各種模式的程式碼與上相同,只不過針對需要使能通道的中斷函式,
    對於基本函式,需要使能相應的更新中斷
    對於其他幾類模式,需要新增一個switch結構,使能相應通道的比較捕獲中斷
     即TIMx_DIER函式的各位置1即可,
switch (Channel)
 {case TIM_CHANNEL_1:
    {       
      /* Enable the TIM Capture/Compare 1 interrupt */
      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
    }
    break;
    
    case TIM_CHANNEL_2:
    {
      /* Enable the TIM Capture/Compare 2 interrupt */
      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
    }
    break;
    
    case TIM_CHANNEL_3:
    {
      /* Enable the TIM Capture/Compare 3 interrupt */
      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
    }
    break;
    
    case TIM_CHANNEL_4:
    {
      /* Enable the TIM Capture/Compare 4 interrupt */
      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
    }
    break;
    
    default:
    break;
  } 
這裡有一個大的前提,就是要在配置定時器的中斷。

  /* 配置定時器中斷優先順序並使能 */
  HAL_NVIC_SetPriority(STEPMOTOR_TIMx_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(STEPMOTOR_TIMx_IRQn);
在每次發生更新事件就會呼叫下面的回撥函式:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
在每次發生輸出翻轉是就會呼叫下面的回撥函式:
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
我們可以在中斷中對定時器的引數進行實時修改。