9、定时器TIM

目录

0x01、基本定时器简介

0x0001、时钟源

0x0002、计数器时钟

0x0003、计数器

0x0004、自动重装载寄存器

0x0005、定时时间的计算

0x02、定时器初始化结构体详解

0x03、库函数

0x0001、初始化函数

0x0002、初始化TIMx外设为默认重置值函数

0x0003、是否允许改变定时器计数值。

0x0004、配置TIMx预分频器。

0x0005、中断使能函数

0x0006、定时器使能函数

0x0007、定时器中断判断函数

0x0008、清除中断标志位

0x0009、定时器计数值设定函数

0x04、编写函数

0x05、源程序下载地址


STM32系列芯片具有多个定时器供使用者选择,其中包括TIM1和TIM8等高级定时器,TIM2到TIM5等通用定时器,还有TIM6和TIM7等基本定时器。定时器在单片机系统中地位十分重要,本文中可能无法全面展开。

基本定时器TIM6 和TIM7 是一个16 位的只能向上计数的定时器,只能定时,没有外部IO

通用定时器TIM2/3/4/5 是一个16 位的可以向上/下计数的定时器,可以定时,可以输出比较,
可以输入捕捉,每个定时器有四个外部IO

高级定时器TIM1/8 是一个16 位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,还可以有三相电机互补输出信号,每个定时器有8 个外部IO

介绍,我们先做一个基本了解,日后笔者可能还会有定时器相关的内容呈现给大家。所以,本文以通用定时器作为引导,大致了解一下STM32的定时器系统。

0x01、基本定时器简介

0x0001、时钟源

定时器时钟TIMxCLK,即内部时钟CK_INT,经APB1 预分频器后分频提供,如果APB1 预分频
系数等于1,则频率不变,否则频率乘以2,库函数中APB1 预分频的系数是2,即PCLK1=36M,
所以定时器时钟TIMxCLK=36*2=72M。

0x0002、计数器时钟

定时器时钟经过PSC 预分频器之后,即CK_CNT,用来驱动计数器计数。PSC 是一个16 位的预
分频器,可以对定时器时钟TIMxCLK 进行1~65536 之间的任何一个数进行分频。具体计算方式
为:CK_CNT=TIMxCLK/(PSC+1)。

0x0003、计数器

计数器CNT 是一个16 位的计数器,只能往上计数,最大计数值为65535。当计数达到自动重装
载寄存器的时候产生更新事件,并清零从头开始计数。

0x0004、自动重装载寄存器

自动重装载寄存器ARR 是一个16 位的寄存器,这里面装着计数器能计数的最大数值。当计数到
这个值的时候,如果使能了中断的话,定时器就产生溢出中断。

0x0005、定时时间的计算

定时器的定时时间等于计数器的中断周期乘以中断的次数。计数器在CK_CNT 的驱动下,计一
个数的时间则是CK_CLK 的倒数,等于:1/(TIMxCLK/(PSC+1)),产生一次中断的时间则等于:1/(CK_CLK * ARR)。如果在中断服务程序里面设置一个变量time,用来记录中断的次数,那么就可以计算出我们需要的定时时间等于:1/CK_CLK* (ARR+1)*time。

0x02、定时器初始化结构体详解

typedef struct
{
    uint16_t TIM_Prescaler;         // 预分频器
    uint16_t TIM_CounterMode;       // 计数模式
    uint16_t TIM_Period;            // 定时器周期
    uint16_t TIM_ClockDivision;     // 时钟分频
    uint8_t TIM_RepetitionCounter;  // 重复计算器
} TIM_TimeBaseInitTypeDef;

(1) TIM_Prescaler:定时器预分频器设置,时钟源经该预分频器才是定时器时钟,它设定TIMx_PSC寄存器的值。可设置范围为0 至65535,实现1 至65536 分频。
(2) TIM_CounterMode:定时器计数方式,可是在为向上计数、向下计数以及三种中心对齐模式。
基本定时器只能是向上计数,即TIMx_CNT 只能从0 开始递增,并且无需初始化。
(3) TIM_Period:定时器周期,实际就是设定自动重载寄存器的值,在事件生成时更新到影子寄
存器。可设置范围为0 至65535。
(4) TIM_ClockDivision:时钟分频,设置定时器时钟CK_INT 频率与数字滤波器采样时钟频率分
频比,基本定时器没有此功能,不用设置。
(5) TIM_RepetitionCounter:重复计数器,属于高级控制寄存器专用寄存器位,利用它可以非常容
易控制输出PWM 的个数。这里不用设置。

虽然定时器基本初始化结构体有5 个成员,但对于基本定时器只需设置其中两个就可以,想想使
用基本定时器就是简单。

0x03、库函数

由于定时器相关的寄存器数量众多,介绍复杂,所以这里我们就不详细介绍了,具体的可以查看官方文档。

定时器设置的一般步骤可以总结为以下几步:

1、定时器时钟使能

2、初始化定时器,设置自动重装值,分频系数,计数方式等

3、允许更新中断

4、设置定时器中断优先级

5、使能定时器

6、编写中断服务函数

0x0001、初始化函数

void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)

函数功能:根据TIM_TimeBaseInitStruct中指定的参数初始化定时器外围设备。

     参数1:TIM_TypeDef* TIMx                                                     —> 选择TIM外围设备。

     参数2:TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct  —> 指向包含指定TIM外围设备的配置信息的TIM_TimeBaseInitTypeDef结构体的指针。

    返回值:无

0x0002、初始化TIMx外设为默认重置值函数

void TIM_DeInit(TIM_TypeDef* TIMx)

函数功能:将TIMx外围寄存器反初始化为其默认重置值。

     参数1:TIM_TypeDef* TIMx                                                     —> 选择TIM外围设备。

    返回值:无

0x0003、是否允许改变定时器计数值。

void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState)

函数功能:启用或禁用ARR上的TIMx外围预加载寄存器。

     参数1:TIM_TypeDef* TIMx                                            —> 选择TIM外围设备。

     参数2:FunctionalState NewState                                   —>TIMx外围预加载寄存器的新状态

    返回值:无

这个函数要重点说一下,如果我们不需要在程序运行中改变定时器的计数值,我们可以不用该函数,如果需要在程序运行中改变定时器的定时时间,我们可以使用该函数开启该功能。然后通过TIM_PrescalerConfig函数重新配置定时器。

0x0004、配置TIMx预分频器。

void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode)

函数功能:配置TIMx预分频器。 

     参数1:TIM_TypeDef* TIMx                         —> 选择TIM外围设备。

     参数2:Prescaler                                          —> 指定预分频器寄存器值

     参数3:TIM_PSCReloadMode                     —> 指定预分频器重新加载模式

此参数可以是以下值之一:

TIM_PSCReloadMode_Update: 预分频器在更新事件中加载。

TIM_PSCReloadMode_Immediate: 预分频器立即加载。

    返回值:无

0x0005、中断使能函数

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)

函数功能:启用或禁用指定的TIM中断。

     参数1:TIM_TypeDef* TIMx           —> 选择TIM外围设备。

     参数2:uint16_t TIM_IT                  —>指定TIM中断要启用或禁用的源。

     参数3:FunctionalState NewState  —>定时器中断的新状态

    返回值:无

0x0006、定时器使能函数

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)

函数功能:启用或禁用指定的TIM外围设备。

     参数1:TIM_TypeDef* TIMx           —> 选择TIM外围设备。

     参数2:FunctionalState NewState  —>定时器的新状态

    返回值:无

0x0007、定时器中断判断函数

ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)

函数功能:检查TIM中断是否发生。

     参数1:TIM_TypeDef* TIMx     —> 选择TIM外围设备。

     参数2:uint16_t TIM_IT            —> 指定要检查的TIM中断源。

    返回值:定时器中断的新状态

0x0008、清除中断标志位

void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)

函数功能:检查TIM中断是否发生。

     参数1:TIM_TypeDef* TIMx     —> 选择TIM外围设备。

     参数2:uint16_t TIM_IT            —> 指定要清除的TIM中断源。

    返回值:无

0x0009、定时器计数值设定函数

void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter)

函数功能:设定计数器的计数值

     参数1:TIM_TypeDef* TIMx     —> 选择TIM外围设备。

     参数2:uint16_t TIM_IT            —> 指定计数器寄存器的新值。

    返回值:无

0x04、编写函数

/**
  *@brief   TIM6定时器1s定时
  *@param   无
  *@return  无
  */
void TIM6_Init(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef         NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);             // 使能定时器6时钟

    // 定时器6初始化 TIM2频率为72MHz
    TIM_TimeBaseStructure.TIM_Period        = 9999;                  // 定时时间为计数1000次,即1s
    TIM_TimeBaseStructure.TIM_Prescaler     = 7199;                  // 分频系数7200,频率为72000000/7200 = 10000,即每秒计数10000次
    TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);                  // 初始化定时器

    /* 使能TIM6全局中断 */
    NVIC_InitStructure.NVIC_IRQChannel                   = TIM6_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);


    TIM_ClearFlag(TIM6, TIM_FLAG_Update);                            // 清除溢出中断标志位
    TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);                       // 定时器6溢出中断开启
    TIM_Cmd(TIM6, ENABLE);                                           // 定时器6使能
}
/**
  *@brief   TIM6中断函数
  *@param   无
  *@return  无
  */
void TIM6_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(TIM6, TIM_FLAG_Update);               // 清除定时器T6溢出中断标志位
        if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_10) == 1)
        {
            GPIO_ResetBits(GPIOC,GPIO_Pin_10);
        }
        else
        {
            GPIO_SetBits(GPIOC,GPIO_Pin_10);
        }
    }
}

0x05、源程序下载地址

该程序利用定时器6产生1S定时,是led灯每隔1s翻转一次

STM32定时器源程序-单片机文档类资源-CSDN下载

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值