STM32硬件层HAL库TIM应用HAL篇8


配置TIM

  • 打开CUBE工程

Timers->TIM6配置

  • 选择Activated
  • Parameter Settings配置
  • 配置预分频器72分频——71,自动重载数值——999,计数模式——UP,自动重载预装载——Disable
  • NVIC Settings使能中断

生成代码

  • 点击GENERATE CODE自动生成代码
  • 等待生成完成

TIM函数

TIM结构体分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
  * @brief  TIM Time Base Handle Structure definition
  */
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
typedef struct __TIM_HandleTypeDef
#else
typedef struct
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
{
  TIM_TypeDef                 *Instance;     /*!< Register base address             */
  TIM_Base_InitTypeDef        Init;          /*!< TIM Time Base required parameters */
  HAL_TIM_ActiveChannel       Channel;       /*!< Active channel                    */
  DMA_HandleTypeDef           *hdma[7];      /*!< DMA Handlers array
                                                  This array is accessed by a @ref DMA_Handle_index */
  HAL_LockTypeDef             Lock;          /*!< Locking object                    */
  __IO HAL_TIM_StateTypeDef   State;         /*!< TIM operation state               */

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  void (* Base_MspInitCallback)(struct __TIM_HandleTypeDef *htim);              /*!< TIM Base Msp Init Callback                              */
  void (* Base_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);            /*!< TIM Base Msp DeInit Callback                            */
  void (* IC_MspInitCallback)(struct __TIM_HandleTypeDef *htim);                /*!< TIM IC Msp Init Callback                                */
  void (* IC_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);              /*!< TIM IC Msp DeInit Callback                              */
  void (* OC_MspInitCallback)(struct __TIM_HandleTypeDef *htim);                /*!< TIM OC Msp Init Callback                                */
  void (* OC_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);              /*!< TIM OC Msp DeInit Callback                              */
  void (* PWM_MspInitCallback)(struct __TIM_HandleTypeDef *htim);               /*!< TIM PWM Msp Init Callback                               */
  void (* PWM_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);             /*!< TIM PWM Msp DeInit Callback                             */
  void (* OnePulse_MspInitCallback)(struct __TIM_HandleTypeDef *htim);          /*!< TIM One Pulse Msp Init Callback                         */
  void (* OnePulse_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);        /*!< TIM One Pulse Msp DeInit Callback                       */
  void (* Encoder_MspInitCallback)(struct __TIM_HandleTypeDef *htim);           /*!< TIM Encoder Msp Init Callback                           */
  void (* Encoder_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);         /*!< TIM Encoder Msp DeInit Callback                         */
  void (* HallSensor_MspInitCallback)(struct __TIM_HandleTypeDef *htim);        /*!< TIM Hall Sensor Msp Init Callback                       */
  void (* HallSensor_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);      /*!< TIM Hall Sensor Msp DeInit Callback                     */
  void (* PeriodElapsedCallback)(struct __TIM_HandleTypeDef *htim);             /*!< TIM Period Elapsed Callback                             */
  void (* PeriodElapsedHalfCpltCallback)(struct __TIM_HandleTypeDef *htim);     /*!< TIM Period Elapsed half complete Callback               */
  void (* TriggerCallback)(struct __TIM_HandleTypeDef *htim);                   /*!< TIM Trigger Callback                                    */
  void (* TriggerHalfCpltCallback)(struct __TIM_HandleTypeDef *htim);           /*!< TIM Trigger half complete Callback                      */
  void (* IC_CaptureCallback)(struct __TIM_HandleTypeDef *htim);                /*!< TIM Input Capture Callback                              */
  void (* IC_CaptureHalfCpltCallback)(struct __TIM_HandleTypeDef *htim);        /*!< TIM Input Capture half complete Callback                */
  void (* OC_DelayElapsedCallback)(struct __TIM_HandleTypeDef *htim);           /*!< TIM Output Compare Delay Elapsed Callback               */
  void (* PWM_PulseFinishedCallback)(struct __TIM_HandleTypeDef *htim);         /*!< TIM PWM Pulse Finished Callback                         */
  void (* PWM_PulseFinishedHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Pulse Finished half complete Callback           */
  void (* ErrorCallback)(struct __TIM_HandleTypeDef *htim);                     /*!< TIM Error Callback                                      */
  void (* CommutationCallback)(struct __TIM_HandleTypeDef *htim);               /*!< TIM Commutation Callback                                */
  void (* CommutationHalfCpltCallback)(struct __TIM_HandleTypeDef *htim);       /*!< TIM Commutation half complete Callback                  */
  void (* BreakCallback)(struct __TIM_HandleTypeDef *htim);                     /*!< TIM Break Callback                                      */
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
} TIM_HandleTypeDef;
  • TIM寄存器基本地址Instance

可选参数:TIM1 TIM2 TIM3 TIM4 TIM5 TIM6 TIM7 TIM8

  • TIM初始化结构体Init
  • 通道Channel
1
2
3
4
5
6
7
8
9
10
11
/**
  * @brief  HAL Active channel structures definition
  */
typedef enum
{
  HAL_TIM_ACTIVE_CHANNEL_1        = 0x01U,    /*!< The active channel is 1     *///通道1
  HAL_TIM_ACTIVE_CHANNEL_2        = 0x02U,    /*!< The active channel is 2     *///通道2
  HAL_TIM_ACTIVE_CHANNEL_3        = 0x04U,    /*!< The active channel is 3     *///通道3
  HAL_TIM_ACTIVE_CHANNEL_4        = 0x08U,    /*!< The active channel is 4     *///通道4
  HAL_TIM_ACTIVE_CHANNEL_CLEARED  = 0x00U     /*!< All active channels cleared *///清除有效通道
} HAL_TIM_ActiveChannel;
  • DMA数组hdma[7]
1
2
3
4
5
6
7
8
9
10
/** @defgroup DMA_Handle_index TIM DMA Handle Index
  * @{
  */
#define TIM_DMA_ID_UPDATE                ((uint16_t) 0x0000)       /*!< Index of the DMA handle used for Update DMA requests */
#define TIM_DMA_ID_CC1                   ((uint16_t) 0x0001)       /*!< Index of the DMA handle used for Capture/Compare 1 DMA requests */
#define TIM_DMA_ID_CC2                   ((uint16_t) 0x0002)       /*!< Index of the DMA handle used for Capture/Compare 2 DMA requests */
#define TIM_DMA_ID_CC3                   ((uint16_t) 0x0003)       /*!< Index of the DMA handle used for Capture/Compare 3 DMA requests */
#define TIM_DMA_ID_CC4                   ((uint16_t) 0x0004)       /*!< Index of the DMA handle used for Capture/Compare 4 DMA requests */
#define TIM_DMA_ID_COMMUTATION           ((uint16_t) 0x0005)       /*!< Index of the DMA handle used for Commutation DMA requests */
#define TIM_DMA_ID_TRIGGER               ((uint16_t) 0x0006)       /*!< Index of the DMA handle used for Trigger DMA requests */
  • Lock
  • TIM状态State
1
2
3
4
5
6
7
8
9
10
11
/**
  * @brief  HAL State structures definition
  */
typedef enum
{
  HAL_TIM_STATE_RESET             = 0x00U,    /*!< Peripheral not yet initialized or disabled  *///没有初始化
  HAL_TIM_STATE_READY             = 0x01U,    /*!< Peripheral Initialized and ready for use    *///初始化完成和准备好
  HAL_TIM_STATE_BUSY              = 0x02U,    /*!< An internal process is ongoing              *///在忙
  HAL_TIM_STATE_TIMEOUT           = 0x03U,    /*!< Timeout state                               *///超时
  HAL_TIM_STATE_ERROR             = 0x04U     /*!< Reception process is ongoing                *///错误
} HAL_TIM_StateTypeDef;
  • 各种回调函数

TIM初始化结构体分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
  * @brief  TIM Time base Configuration Structure definition
  */
typedef struct
{
  uint32_t Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.
                                   This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */

  uint32_t CounterMode;       /*!< Specifies the counter mode.
                                   This parameter can be a value of @ref TIM_Counter_Mode */

  uint32_t Period;            /*!< Specifies the period value to be loaded into the active
                                   Auto-Reload Register at the next update event.
                                   This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF.  */

  uint32_t ClockDivision;     /*!< Specifies the clock division.
                                   This parameter can be a value of @ref TIM_ClockDivision */

  uint32_t RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounter
                                    reaches zero, an update event is generated and counting restarts
                                    from the RCR value (N).
                                    This means in PWM mode that (N+1) corresponds to:
                                        - the number of PWM periods in edge-aligned mode
                                        - the number of half PWM period in center-aligned mode
                                     GP timers: this parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF.
                                     Advanced timers: this parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */

  uint32_t AutoReloadPreload;  /*!< Specifies the auto-reload preload.
                                   This parameter can be a value of @ref TIM_AutoReloadPreload */
} TIM_Base_InitTypeDef;
  • 预分频因子Prescaler

可设置范围为0 至65535,实现1 至65536 分频

  • 计数模式CounterMode
1
2
3
4
5
6
7
8
/** @defgroup TIM_Counter_Mode TIM Counter Mode
  * @{
  */
#define TIM_COUNTERMODE_UP                 0x00000000U   /*!< Counter used as up-counter   *///向上计数
#define TIM_COUNTERMODE_DOWN               TIM_CR1_DIR   /*!< Counter used as down-counter *///向下计数
#define TIM_COUNTERMODE_CENTERALIGNED1     TIM_CR1_CMS_0 /*!< Center-aligned mode 1        *///中心对齐,只在计数器向下计数时被设置
#define TIM_COUNTERMODE_CENTERALIGNED2     TIM_CR1_CMS_1 /*!< Center-aligned mode 2        *///中心对齐,只在计数器向上计数时被设置
#define TIM_COUNTERMODE_CENTERALIGNED3     TIM_CR1_CMS   /*!< Center-aligned mode 3        *///中心对齐,在计数器向上和向下计数时均被设置
  • 定时器周期Period

可设置范围为0 至65535,实现1 至65536 计数

  • 时钟分频ClockDivision 设置定时器时钟CK_INT 频率与死区发生器以及数字滤波器采样时钟频率分频比。可以选择1、2、4 分频
1
2
3
4
5
6
/** @defgroup TIM_ClockDivision TIM Clock Division
  * @{
  */
#define TIM_CLOCKDIVISION_DIV1             0x00000000U                          /*!< Clock division: tDTS=tCK_INT   *///不分频
#define TIM_CLOCKDIVISION_DIV2             TIM_CR1_CKD_0                        /*!< Clock division: tDTS=2*tCK_INT *///2分频
#define TIM_CLOCKDIVISION_DIV4             TIM_CR1_CKD_1                        /*!< Clock division: tDTS=4*tCK_INT *///4分频
  • 重复计数器RepetitionCounter

只在高级定时器使用,高级定时器发生上溢或下溢事件是递减重复计数器的值,只有当重复计数器为0 时才会生成更新事

  • 自动重载预装载AutoReloadPreload
1
2
3
4
5
/** @defgroup TIM_AutoReloadPreload TIM Auto-Reload Preload
  * @{
  */
#define TIM_AUTORELOAD_PRELOAD_DISABLE                0x00000000U               /*!< TIMx_ARR register is not buffered *///TIMx_ARR寄存器没有缓冲
#define TIM_AUTORELOAD_PRELOAD_ENABLE                 TIM_CR1_ARPE              /*!< TIMx_ARR register is buffered *///TIMx_ARR寄存器具有缓冲

TIM主模式结构体分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
  * @brief  TIM Master configuration Structure definition
  */
typedef struct
{
  uint32_t  MasterOutputTrigger;   /*!< Trigger output (TRGO) selection
                                        This parameter can be a value of @ref TIM_Master_Mode_Selection */
  uint32_t  MasterSlaveMode;       /*!< Master/slave mode selection
                                        This parameter can be a value of @ref TIM_Master_Slave_Mode
                                        @note When the Master/slave mode is enabled, the effect of
                                        an event on the trigger input (TRGI) is delayed to allow a
                                        perfect synchronization between the current timer and its
                                        slaves (through TRGO). It is not mandatory in case of timer
                                        synchronization mode. */
} TIM_MasterConfigTypeDef;
  • 主模式同步信息选择MasterOutputTrigger
1
2
3
4
5
6
7
8
9
10
11
/** @defgroup TIM_Master_Mode_Selection TIM Master Mode Selection
  * @{
  */
#define TIM_TRGO_RESET            0x00000000U                                      /*!< TIMx_EGR.UG bit is used as trigger output (TRGO)              */
#define TIM_TRGO_ENABLE           TIM_CR2_MMS_0                                    /*!< TIMx_CR1.CEN bit is used as trigger output (TRGO)             */
#define TIM_TRGO_UPDATE           TIM_CR2_MMS_1                                    /*!< Update event is used as trigger output (TRGO)                 */
#define TIM_TRGO_OC1              (TIM_CR2_MMS_1 | TIM_CR2_MMS_0)                  /*!< Capture or a compare match 1 is used as trigger output (TRGO) */
#define TIM_TRGO_OC1REF           TIM_CR2_MMS_2                                    /*!< OC1REF signal is used as trigger output (TRGO)                */
#define TIM_TRGO_OC2REF           (TIM_CR2_MMS_2 | TIM_CR2_MMS_0)                  /*!< OC2REF signal is used as trigger output(TRGO)                 */
#define TIM_TRGO_OC3REF           (TIM_CR2_MMS_2 | TIM_CR2_MMS_1)                  /*!< OC3REF signal is used as trigger output(TRGO)                 */
#define TIM_TRGO_OC4REF           (TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0)  /*!< OC4REF signal is used as trigger output(TRGO)                 */
  • 主从模式MasterSlaveMode
1
2
3
4
5
/** @defgroup TIM_Master_Slave_Mode TIM Master/Slave Mode
  * @{
  */
#define TIM_MASTERSLAVEMODE_ENABLE         TIM_SMCR_MSM /*!< No action */
#define TIM_MASTERSLAVEMODE_DISABLE        0x00000000U /*!< Master/slave mode is selected */

常用库函数解析

  • 获取标志位__HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__)
  • 清除标志位__HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__)

可选标志位: TIM_FLAG_UPDATE——TIM更新标志位 TIM_FLAG_CC1——捕获/比较1中断标志位 TIM_FLAG_CC2——捕获/比较2中断标志位 TIM_FLAG_CC3——捕获/比较3中断标志位 TIM_FLAG_CC4——捕获/比较4中断标志位 TIM_FLAG_COM——COM中断标记 TIM_FLAG_TRIGGER——触发器中断标记 TIM_FLAG_BREAK——刹车中断标记 TIM_FLAG_CC1OF——捕获/比较1重复捕获标记 TIM_FLAG_CC2OF——捕获/比较2重复捕获标记 TIM_FLAG_CC3OF——捕获/比较3重复捕获标记 TIM_FLAG_CC4OF——捕获/比较4重复捕获标记

  • 使能中断__HAL_TIM_ENABLE_IT(__HANDLE__, __INTERRUPT__)
  • 清除中断标志位__HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__)

可选标志位: TIM_IT_UPDATE——TIM更新中断 TIM_IT_CC1——捕获/比较1中断 TIM_IT_CC2——捕获/比较2中断 TIM_IT_CC3——捕获/比较3中断 TIM_IT_CC4——捕获/比较4中断 TIM_IT_COM——COM中断 TIM_IT_TRIGGER——触发器中断 TIM_IT_BREAK——刹车中断

  • 设置自动重载值__HAL_TIM_SET_AUTORELOAD(__HANDLE__, __AUTORELOAD__)
  • 设置通道比较值__HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__)

  • 计时器启动无中断HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim)
  • 计时器关闭HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim)

  • 计时器启动有中断HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)

调用延时完成回调

  • 计时器关闭HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim)

  • 计时器DMA启动HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length)

DMA设置必须设置成存储器到外设,每更新一次DMA向ARR传输一次,每次的延时时间为 $ \sum_{i=0}^{Length}{pData[i]} $ ,DMA传输完成调用延时完成回调

  • 计时器DMA关闭HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim)

代码移植

定时器应用

  • main.c文件添加变量
1
__IO uint32_t time;
  • 在主函数初始化添加TIM启动
1
HAL_TIM_Base_Start_IT(&htim6);
  • 主循环添加时间处理
1
2
3
4
5
6
7
8
9
        if(time>=1000)
        {
            time=0;
            LED1_TOGGLE;
            LED2_TOGGLE;
            printf( "\r\n The IC current tem= %.2fC\r\n", temp);
            printf( "\r\n The IC current VDDA= %.2fV\r\n", VREF);
            printf( "\r\n The IC current ADC= %.2fV\r\n", adcValue);
        }
  • 添加回调函数
1
2
3
4
5
6
7
8
9
10
11
12
/**
  * @brief  Period elapsed callback in non-blocking mode
  * @param  htim TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM6)
    {
        time++;
    }
}

下载调试

  • 编译之后下载到开发板
  • 连接开发板串口
  • 打开串口助手
  • 可以看到串口每1秒接收到数据,开发板上LED在1s间隔闪烁
  • 和SPL库结果一致