STM32F7xx —— Timer

STM32F7xx  —— Timer

 

目录

STM32F7xx  —— Timer

一、基础定时器配置

二、带回调定时器


 

 

作用:输出PWM,测量脉冲长度,定时等。

一、基础定时器配置

// 基本定时器
#define TIMER_CHANNEL             TIM3
#define TIMER_PREEMPT_PRIO        TIM_PRIORITY
#define TIMER_RCC_FUNC            __HAL_RCC_TIM3_CLK_ENABLE
#define TIMER_IRQ                 TIM3_IRQn
#define TIMER_IRQ_FUNC            TIM3_IRQHandler
#define TIMER_DIV                 (10800 - 1)
#define TIMER_PERIOD              (100 - 1)

static TIM_HandleTypeDef timer_handler;     // 定时器操作句柄

// Period:自动重装值。 Prescaler:时钟预分频数
// 定时器溢出时间计算方法:Tout=((Period+1)*(Prescaler+1))/Ft us.
// Ft=定时器工作频率,单位:Mhz
void TimerInit(void)
{
  timer_handler.Instance = TIMER_CHANNEL;
  timer_handler.Init.Prescaler = TIMER_DIV;
  timer_handler.Init.CounterMode = TIM_COUNTERMODE_UP;
  timer_handler.Init.Period = TIMER_PERIOD;
  timer_handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_Base_Init(&timer_handler);
  HAL_TIM_Base_Start_IT(&timer_handler);
}

// 定时器底层驱动 开启时钟 设置中断优先级
// 此函数会被 HAL_TIM_Base_Init()函数调用
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *timer)
{
  TIMER_RCC_FUNC();
  HAL_NVIC_SetPriority(TIMER_IRQ, TIM_PRIORITY, 1);
  HAL_NVIC_EnableIRQ(TIMER_IRQ);
}


void TIMER_IRQ_FUNC(void)
{
  HAL_TIM_IRQHandler(&timer_handler);
}

// 中断服务函数调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *timer)
{
  if(timer == (&timer_handler))
  {
     // do something
  }
}

 

二、带回调定时器

使用回调函数,以链表的方式管理所有的定时器。检测时间到,执行回调函数。TimerRun定时运行,TimerCreate创建一个定时器,TimerStart开启定时器。这里只是写了一个比较简单的定时器,操作系统里面也有类似的定时接口。

#define TIMER_CHANNEL             TIM3
#define TIMER_PREEMPT_PRIO        TIM_PRIORITY
#define TIMER_RCC_FUNC            __HAL_RCC_TIM3_CLK_ENABLE
#define TIMER_IRQ                 TIM3_IRQn
#define TIMER_IRQ_FUNC            TIM3_IRQHandler
#define TIMER_DIV                 (10800 - 1)
#define TIMER_PERIOD              (100 - 1)

static struct
{
  timer_t *next;
} timer_run;

static volatile uint32_t timer_ticks;
static uint32_t timer_ticks_run;

static TIM_HandleTypeDef timer_handler;     // 定时器操作句柄

// Period:自动重装值。 Prescaler:时钟预分频数
// 定时器溢出时间计算方法:Tout=((Period+1)*(Prescaler+1))/Ft us.
// Ft=定时器工作频率,单位:Mhz
void TimerInit(void)
{
  timer_run.next = NULL;

  timer_handler.Instance = TIMER_CHANNEL;
  timer_handler.Init.Prescaler = TIMER_DIV;
  timer_handler.Init.CounterMode = TIM_COUNTERMODE_UP;
  timer_handler.Init.Period = TIMER_PERIOD;
  timer_handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_Base_Init(&timer_handler);
  HAL_TIM_Base_Start_IT(&timer_handler);
}

// 定时器底层驱动 开启时钟 设置中断优先级
// 此函数会被 HAL_TIM_Base_Init()函数调用
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *timer)
{
  TIMER_RCC_FUNC();
  HAL_NVIC_SetPriority(TIMER_IRQ, TIM_PRIORITY, 1);
  HAL_NVIC_EnableIRQ(TIMER_IRQ);
}


void TIMER_IRQ_FUNC(void)
{
  HAL_TIM_IRQHandler(&timer_handler);
}

// 中断服务函数调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *timer)
{
  if(timer == (&timer_handler))
  {
    ++timer_ticks;
  }
}

//======================================================================================================
void TimerRun(void)
{
  timer_t *timer;
  timer_t *timer_done;

  timer_done = NULL;

  while(timer_ticks_run != timer_ticks)
  {
    timer = timer_run.next;

    if(timer)
    {
      if(timer->ticks)
      {
        ++timer_ticks_run;
        timer->ticks--;
      }
      // 将后续超时的定时器都移除
      while(timer && (0 == timer->ticks))
      {
        timer_run.next = timer->next;
        timer->next = timer_done;
        timer_done = timer;
        timer = timer_run.next;
      }
    }
    else
    {
      ++timer_ticks_run;
    }
  }

  while(timer_done)
  {
    timer = timer_done;
    timer_done = timer->next;
    timer->next = NULL;
    timer->handler(timer->param);
  }
}

void TimerCreate(timer_t *timer, timer_cb_t handler, void *param)
{
  timer->handler = handler;
  timer->param = param;
}

void TimerStart(timer_t *timer, uint32_t timeout)
{
  timer_t *p;
  uint32_t ticks = (timeout + 9) / 10;

  TimerCancel(timer);

  p = (timer_t *)&timer_run;

  while(p->next)
  {
    if(ticks <= p->next->ticks)
    {
      p->next->ticks -= ticks;
      break;
    }
    else
    {
      ticks -= p->next->ticks;  // ticks 有可能为 0
    }
    p = p->next;
  }
  timer->ticks = ticks;
  timer->next = p->next;
  p->next = timer;
}

void TimerCancel(timer_t *timer)
{
  timer_t *p;

  if(NULL == timer)
  {
    return;
  }

  p = (timer_t *)&timer_run;

  while(p->next)
  {
    if(p->next == timer)
    {
      if(timer->next)
      {
        timer->next->ticks += timer->ticks;
      }
      p->next = timer->next;
      timer->next = NULL;
      break;
    }
    p = p->next;
  }
}
static timer_t timer;
static void handler(void *param)
{
  TimerStart(&timer, 1000);

  printf("TimerStart\r\n"); 
}


  TimerCreate(&timer, handler, NULL);
  TimerStart(&timer, 1000);

  TimerRun(); // 放在10ms任务中运行

 

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值