stm32的TIM定时器HAL库函数的使用

相关具体内容参考 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)将状态设置为READY。htim->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_PeriodEla相关具体内容参考 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)将状态设置为READY。htim->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)
我们可以在中断中对定时器的参数进行实时修改。


作者:luowei_memory
来源:CSDN
原文:https://blog.csdn.net/qq_30567891/article/details/78994480
版权声明:本文为博主原创文章,转载请附上博文链接!psedCallback(TIM_HandleTypeDef *htim);
在每次发生输出翻转是就会调用下面的回调函数:
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
我们可以在中断中对定时器的参数进行实时修改。


作者:luowei_memory
来源:CSDN
原文:https://blog.csdn.net/qq_30567891/article/details/78994480
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 46
    点赞
  • 246
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值