TIM1 简介
高级控制定时器(TIM1)由一个 16 位的自动装载计数器组成,它由一个可编程的预分频器驱动。它适合多种用途,包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、PWM、嵌入死区时间的互补 PWM 等)。
使用定时器预分频器和 RCC 时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节
TIM1 主要特性
TIM1 定时器的功能包括:
⚫ 16 位向上、向下、向上/向下自动装载计数器
⚫ 16 位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为 1~65535 之间的任意数值
⚫
多达 4 个独立通道:
- 输入捕获
- 输出比较
- PWM 生成(边缘或中间对齐模式)
- 单脉冲模式输出
⚫ 死区时间可编程的互补输出
⚫ 使用外部信号控制定时器和定时器互联的同步电路
⚫ 允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器
⚫ 刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态
⚫ 如下事件发生时产生中断:
- 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
- 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
- 输入捕获
- 输出比较
- 刹车信号输入
⚫ 支持针对定位的增量(正交)编码器和霍尔传感器电路
⚫ 触发输入作为外部时钟或者按周期的电流管理
/********************************************************************************
* @file bsp_tim.c
* @author jianqiang.xue
* @Version V1.0.0
* @Date 2021-04-19
* @brief
********************************************************************************/
/* Private includes ----------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include "cx32l003_hal.h"
#include "bsp_gpio.h"
#include "bsp_tim.h"
#include "business_gpio.h"
#include "business_function.h"
/* Private define ------------------------------------------------------------*/
#define TIM1_EN BS_TIM1_EN
#define TIM1_PRESCALER BS_TIM1_PRESCALER
#define TIM1_PERIOD BS_TIM1_PERIOD
#define TIM1_CH1_PIN BS_TIM1_CH1_PIN
#define TIM1_CH1_GPIO_PORT BS_TIM1_CH1_GPIO_PORT
#define TIM1_CH1_GPIO_CLK_ENABLE() BS_TIM1_CH1_GPIO_CLK_ENABLE()
#define TIM1_CH1_GPIO_CLK_DISABLE() BS_TIM1_CH1_GPIO_CLK_DISABLE()
#define TIM1_CH2_PIN BS_TIM1_CH2_PIN
#define TIM1_CH2_GPIO_PORT BS_TIM1_CH2_GPIO_PORT
#define TIM1_CH2_GPIO_CLK_ENABLE() BS_TIM1_CH2_GPIO_CLK_ENABLE()
#define TIM1_CH2_GPIO_CLK_DISABLE() BS_TIM1_CH2_GPIO_CLK_DISABLE()
#define TIM1_CH3_PIN BS_TIM1_CH3_PIN
#define TIM1_CH3_GPIO_PORT BS_TIM1_CH3_GPIO_PORT
#define TIM1_CH3_GPIO_CLK_ENABLE() BS_TIM1_CH3_GPIO_CLK_ENABLE()
#define TIM1_CH3_GPIO_CLK_DISABLE() BS_TIM1_CH3_GPIO_CLK_DISABLE()
#define TIM1_CH4_PIN BS_TIM1_CH4_PIN
#define TIM1_CH4_GPIO_PORT BS_TIM1_CH4_GPIO_PORT
#define TIM1_CH4_GPIO_CLK_ENABLE() BS_TIM1_CH4_GPIO_CLK_ENABLE()
#define TIM1_CH4_GPIO_CLK_DISABLE() BS_TIM1_CH4_GPIO_CLK_DISABLE()
#define PWM0_EN BS_PWM0_EN
#define PWM1_EN BS_PWM1_EN
#define PWM2_EN BS_PWM2_EN
#define PWM3_EN BS_PWM3_EN
#if TIM1_EN
TIM_HandleTypeDef tim1_handle_t;
TIM_OC_InitTypeDef tim1_oc_init_handle_t;
#endif
/* Private typedef -----------------------------------------------------------*/
void bsp_tim_pwm_init(void)
{
#if TIM1_EN
memset(&tim1_handle_t, 0, sizeof(TIM_HandleTypeDef));
memset(&tim1_oc_init_handle_t, 0, sizeof(TIM_OC_InitTypeDef));
__HAL_RCC_TIM1_CLK_ENABLE();
/* Set TIMx instance */
tim1_handle_t.Instance = TIM1;
tim1_handle_t.Init.Period = TIM1_PERIOD; // 重装载值
tim1_handle_t.Init.Prescaler = TIM1_PRESCALER; // 预分频
tim1_handle_t.Init.ClockDivision = 0; // CKD 时钟分频因子(Clock division)
tim1_handle_t.Init.CounterMode = TIM_COUNTERMODE_UP; // 边沿对齐模式 计数器向上计数
tim1_handle_t.Init.RepetitionCounter = 0; // TIM1_RCR 重复计数器的值
tim1_handle_t.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; // 禁止自动重装载
HAL_TIM_PWM_Init(&tim1_handle_t);
#if PWM0_EN
bsp_gpio_init_tim(TIM1_CH1_GPIO_PORT, TIM1_CH1_PIN, GPIO_AF1_TIM1_CH1);
tim1_oc_init_handle_t.OCMode = TIM_OCMODE_PWM1; // PWM模式1 TIM1_CCMR1
tim1_oc_init_handle_t.Pulse = TIM1_PERIOD; // CCR 捕获/比较通道
HAL_TIM_PWM_ConfigChannel(&tim1_handle_t, &tim1_oc_init_handle_t, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&tim1_handle_t, TIM_CHANNEL_1);
#endif
#if PWM1_EN
bsp_gpio_init_tim(TIM1_CH2_GPIO_PORT, TIM1_CH2_PIN, GPIO_AF1_TIM1_CH2);
tim1_oc_init_handle_t.OCMode = TIM_OCMODE_PWM1; // PWM模式1 TIM1_CCMR1
tim1_oc_init_handle_t.Pulse = TIM1_PERIOD; // CCR 捕获/比较通道
HAL_TIM_PWM_ConfigChannel(&tim1_handle_t, &tim1_oc_init_handle_t, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&tim1_handle_t, TIM_CHANNEL_2);
#endif
#if PWM2_EN
bsp_gpio_init_tim(TIM1_CH3_GPIO_PORT, TIM1_CH3_PIN, GPIO_AF1_TIM1_CH3);
tim1_oc_init_handle_t.OCMode = TIM_OCMODE_PWM1; // PWM模式1 TIM1_CCMR1
tim1_oc_init_handle_t.Pulse = TIM1_PERIOD; // CCR 捕获/比较通道
HAL_TIM_PWM_ConfigChannel(&tim1_handle_t, &tim1_oc_init_handle_t, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&tim1_handle_t, TIM_CHANNEL_3);
#endif
#if PWM3_EN
bsp_gpio_init_tim(TIM1_CH4_GPIO_PORT, TIM1_CH4_PIN, GPIO_AF1_TIM1_CH4);
tim1_oc_init_handle_t.OCMode = TIM_OCMODE_PWM1; // PWM模式1 TIM1_CCMR1
tim1_oc_init_handle_t.Pulse = TIM1_PERIOD; // CCR 捕获/比较通道
HAL_TIM_PWM_ConfigChannel(&tim1_handle_t, &tim1_oc_init_handle_t, TIM_CHANNEL_4);
HAL_TIM_PWM_Start(&tim1_handle_t, TIM_CHANNEL_4);
#endif
#endif
}
void bsp_tim_pwm_deinit(void)
{
#if TIM1_EN
#if PWM0_EN
HAL_TIM_PWM_Stop(&tim1_handle_t, TIM_CHANNEL_1);
bsp_gpio_deinit(TIM1_CH1_GPIO_PORT, TIM1_CH1_PIN);
#endif
#if PWM1_EN
HAL_TIM_PWM_Stop(&tim1_handle_t, TIM_CHANNEL_2);
bsp_gpio_deinit(TIM1_CH2_GPIO_PORT, TIM1_CH2_PIN);
#endif
#if PWM2_EN
HAL_TIM_PWM_Stop(&tim1_handle_t, TIM_CHANNEL_3);
bsp_gpio_deinit(TIM1_CH3_GPIO_PORT, TIM1_CH3_PIN);
#endif
#if PWM3_EN
HAL_TIM_PWM_Stop(&tim1_handle_t, TIM_CHANNEL_4);
bsp_gpio_deinit(TIM1_CH4_GPIO_PORT, TIM1_CH4_PIN);
#endif
HAL_TIM_PWM_DeInit(&tim1_handle_t);
__HAL_RCC_TIM1_CLK_DISABLE();
#endif
}
/********************************************************************************
* @file bsp_tim.h
* @author jianqiang.xue
* @Version V1.0.0
* @Date 2021-04-19
* @brief NULL
********************************************************************************/
#ifndef __BSP_TIM_H
#define __BSP_TIM_H
#include <stdint.h>
typedef enum
{
BSP_TIM_0 = 0,
BSP_TIM_1
} bsp_tim_t;
void bsp_tim_pwm_init(void);
void bsp_tim_pwm_deinit(void);
#endif