STM32 TIM 定时器使用 - 用作定时、计时

说明:介绍使用STM32 定时器做计时和定时触发一些功能,如点灯。

测试平台:STM32G474RB

1.定时器定义、初始化、点灯

#define LED_GPIO                    GPIOA
#define LED_PIN                     GPIO_PIN_0

#define FAN_CTR_GPIO                GPIOB
#define FAN_CTR_PIN                 GPIO_PIN_6

/* step:1 定义定时器分频系数 */
#define HTIM5_PRESCALER    (SystemCoreClock /1000000 - 1)   /* 定时器的分频系数 */
#define HTIM5_PERIOD       (1000 - 1)                       /* 设置的定时器向上计数的最大值,达到最大值才会产生中断 */

/* step:2 配置定时器的优先级 */
#define HTIM2_NVIC_IRQChannelPreemptionPriority   0     /* 抢占优先级 */
#define HTIM2_NVIC_IRQChannelSubPriority          0     /* 从优先级 */

#define HTIM3_NVIC_IRQChannelPreemptionPriority   0     /* 抢占优先级 */
#define HTIM3_NVIC_IRQChannelSubPriority          0     /* 从优先级 */

#define HTIM4_NVIC_IRQChannelPreemptionPriority   0     /* 抢占优先级 */
#define HTIM4_NVIC_IRQChannelSubPriority          0     /* 从优先级 */

#define HTIM5_NVIC_IRQChannelPreemptionPriority   0     /* 抢占优先级 */
#define HTIM5_NVIC_IRQChannelSubPriority          0     /* 从优先级 */

/* step:3 定义定时器相关变量 */
uint32_t tim5_count = 0;  /* 定时器中断次数计数 */
TIM_HandleTypeDef htim5;  /* 定时器变量 */



/* 初始化定时器、开启定时器中断
 * TIM_TypeDef *TIM_X : 定时器 如 TIM5
 * TIM_HandleTypeDef *htim : 定时器变量指针 如 &htim5
 * uint32_t Prescaler : 分频系数
 * uint32_t Period : 中断周期 ,分频后达到这个计数周期后产生中断。
 * . 分频后频率 =  系统时钟 / 分频系数 = SystemCoreClock / Prescaler = SystemCoreClock / ((SystemCoreClock / 1000000) - 1)
 *
 * */
void Init_TIM_Basic(TIM_TypeDef *TIM_X,TIM_HandleTypeDef *htim ,uint32_t Prescaler ,uint32_t Period)
{
    TIM_HandleTypeDef TIM_HandleTypeDef_Structure;

	if (TIM_X == TIM2)
    {
        __HAL_RCC_TIM2_CLK_ENABLE();
    }
    else if (TIM_X == TIM3)
    {
        __HAL_RCC_TIM3_CLK_ENABLE();
    }
    else if (TIM_X == TIM4)
    {
        __HAL_RCC_TIM4_CLK_ENABLE();
    }
    else if (TIM_X == TIM5)
    {
        __HAL_RCC_TIM5_CLK_ENABLE();
    }
	
    TIM_HandleTypeDef_Structure.Instance = TIM_X;                                           /* 外设设备选择定时器 */
    //TIM_HandleTypeDef_Structure.Init.Prescaler = SystemCoreClock /1000000 - 1;            /* 设置定时器的分频系数 */
    //TIM_HandleTypeDef_Structure.Init.Period = 1000 - 1;                                   /* 设置的定时器向上计数的最大值,达到最大值才会产生中断 */

    TIM_HandleTypeDef_Structure.Init.Prescaler = Prescaler;                                 /* 设置定时器的分频系数 */
    TIM_HandleTypeDef_Structure.Init.Period = Period;                                       /* 设置的定时器向上计数的最大值,达到最大值才会产生中断 */

    TIM_HandleTypeDef_Structure.Init.CounterMode = TIM_COUNTERMODE_UP;                      /* 指向上计数 */
    TIM_HandleTypeDef_Structure.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;                /* 设置时钟分频系数,这里填写TIM_CLOCKDIVISION_DIV1是代表不分频。 */
    TIM_HandleTypeDef_Structure.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;     /* 定时器自动重装上限值 */

    HAL_TIM_Base_Init(&TIM_HandleTypeDef_Structure);
    __HAL_TIM_ENABLE(&TIM_HandleTypeDef_Structure);

    if (TIM_X == TIM2)
    {
        HAL_NVIC_SetPriority(TIM2_IRQn, HTIM2_NVIC_IRQChannelPreemptionPriority, HTIM2_NVIC_IRQChannelSubPriority);  /* 设置中断优先级 */
        HAL_NVIC_EnableIRQ(TIM2_IRQn);
    }
    else if (TIM_X == TIM3)
    {
        HAL_NVIC_SetPriority(TIM3_IRQn, HTIM3_NVIC_IRQChannelPreemptionPriority, HTIM3_NVIC_IRQChannelSubPriority);  /* 设置中断优先级 */
        HAL_NVIC_EnableIRQ(TIM3_IRQn);
    }
    else if (TIM_X == TIM4)
    {
        HAL_NVIC_SetPriority(TIM4_IRQn, HTIM4_NVIC_IRQChannelPreemptionPriority, HTIM4_NVIC_IRQChannelSubPriority);  /* 设置中断优先级 */
        HAL_NVIC_EnableIRQ(TIM4_IRQn);
    }
    else if (TIM_X == TIM5)
    {
        HAL_NVIC_SetPriority(TIM5_IRQn, HTIM5_NVIC_IRQChannelPreemptionPriority, HTIM5_NVIC_IRQChannelSubPriority);  /* 设置中断优先级 */
        HAL_NVIC_EnableIRQ(TIM5_IRQn);
    }

    *htim = TIM_HandleTypeDef_Structure;
    HAL_TIM_Base_Start_IT(htim);                 /* 打开定时器中断 */
}

/* step:4 中断服务函数 */
/* 定时器5中断服务函数 */
void TIM5_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&htim5);
}

/* step:5 中断回调函数中添加功能代码:如LED闪灯 */
/* 定时器中断更新回调函数 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == htim5.Instance)
    {
        ++tim5_count;
        if (tim5_count % 500 == 0)  
        {
            HAL_GPIO_TogglePin(LED_GPIO, LED_PIN);  /* LED 翻转 */
        }
        HAL_GPIO_TogglePin(FAN_CTR_GPIO, FAN_CTR_PIN);
    }
}

/* step:6 调用定时器初始化函数 */
Init_TIM_Basic(TIM5,&htim5,HTIM5_PRESCALER,HTIM5_PERIOD);       //初始化定时器5

2.定时器计时

定时器用作计时工,记录程序、函数运行时的耗时。

uint32_t time_count;
while (1)
{
	rt_thread_mdelay(1000);
	//htim5.Instance->CNT = 0; /* 清零定时器计数: 会多耗时一点 */
	TIM5->CNT = 0; /* 清零定时器计数: 速度更快,计时更准确 */
	HAL_GPIO_TogglePin(LED_GPIO, LED_PIN);
	//time_count = htim5.Instance->CNT;
	time_count = TIM5->CNT;  /* 记录中间的代码的耗时 */
	printf("tick_time = %d ,time_count = %d\r\n",  rt_tick_get(),time_count);
}

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值