TIM基本定时器

TIM基本定时器

1.定时器的分类

以STM32F1系列为例,它的定时器可以根据其特性和功能被分为三大类:

  1. 基本定时器

    • 包括:TIM6和TIM7。
    • 特点:基本定时器是16位,只能向上计数的定时器,通常用于简单的定时操作。它们没有外部触发输入和输出比较功能,因此不能直接生成PWM信号或用于输入捕获等复杂应用。基本定时器的时钟只能来源于内部时钟。
  2. 通用定时器

    • 包括:TIM2至TIM5。
    • 特点:通用定时器也是16位,但相比基本定时器,它们更加灵活,具有更多的功能,如可以向下计数、有多个外部触发输入和输出比较通道,能够用于生成PWM信号、输入捕获、输出比较等。这些定时器的时钟源既可以是内部时钟,也可以是外部时钟。
  3. 高级定时器

    • 包括:TIM1和TIM8。
    • 特点:高级定时器是最复杂且功能最丰富的定时器类型,在STM32F1系列中,它们能够提供更多的功能,如更多的输出比较通道(可达7路PWM输出),支持更复杂的定时器链路、死区生成、刹车输入等高级控制功能,非常适合电机控制、电源管理等需要精确控制的场合。这些定时器同样具有向上/向下计数能力,并且可以使用内部或外部时钟源。

    如下图:

    在这里插入图片描述

2.定时器运行流程

基本定时器的框图如下:
在这里插入图片描述

主要特性:

16位递增计数器(计数值:0~65535)

16位预分频器(分频系数:1~65536)

定时器主要分为时钟源,控制单元和计数部分,基本定时器的时钟源只能来自芯片内部时钟。其中在计数部分,预分频器和自动重装载寄存器具有影子寄存器,定时器的运行流程为:

  1. 初始化配置

    • 时钟使能:首先,需要通过系统时钟控制器(RCC)使能给定基本定时器的时钟。
    • 配置预分频器(PSC):设置预分频寄存器的值,以降低定时器时钟频率到所需范围。例如,若APB1总线时钟为72MHz,可以通过设置PSC来分频得到较低的计数频率。
    • 设置自动重载值(ARR):在自动重载寄存器中设置一个值,当计数器达到这个值时将产生更新事件并重置计数器。这决定了定时器的周期。
  2. 启动定时器

    • 控制寄存器设置:通过设置定时器控制寄存器(如TIMx_CR1),启用定时器的计数器(使能计数EN位)。
  3. 计数过程

    • 一旦定时器被启动,其计数器(CNT)从0开始递增,每次递增都是基于预分频后的时钟频率。
    • 当CNT的值与ARR中的预设值相匹配时,会发生一个更新事件(Update Event)。
    • 更新事件会自动将CNT寄存器复位为0,并且如果配置了中断或DMA请求,这些请求也会在此时被触发。
  4. 影子寄存器的作用

    • 我们通常配置的是“可见”的寄存器(预加载寄存器)ARR和PSC,这些配置在适当的时机(更新事件)才会反映到实际控制定时器运行的“不可见”寄存器,即影子寄存器中。影子寄存器确保了在计数过程中参数的平滑过渡,避免了在计数周期内因参数突变而引起的不连续或错误行为。
  5. 中断处理(可选):

    • 如果在控制寄存器中设置了中断允许位,那么在更新事件发生时,CPU会接收到中断请求,并执行对应的中断服务程序(ISR)。在ISR中,用户可以执行特定的任务,如数据处理、状态改变等。
  6. 关闭定时器(可选):

    • 如果不再需要定时器,可以通过清除控制寄存器中的使能位来停止定时器的计数。

3.基本定时器的配置流程

	TIM_TimeBaseInitTypeDef TIM_BaseInitStu;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6 | RCC_APB1Periph_TIM7, ENABLE);	
	
	TIM_BaseInitStu.TIM_Prescaler =7200 - 1;    //预分频值  TIM_Period x TIM_Prescaler / 时钟频率
	TIM_BaseInitStu.TIM_Period = 10000 - 1;    //自动装载值
	TIM_TimeBaseInit(TIM6,&TIM_BaseInitStu);
	TIM_TimeBaseInit(TIM7,&TIM_BaseInitStu);
	TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
	TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
	TIM_Cmd(TIM6, DISABLE);
	TIM_Cmd(TIM7, DISABLE);
  1. TIM_TimeBaseInitTypeDef TIM_BaseInitStu;
    定义了一个定时器基础初始化结构体变量,用于存储定时器初始化的相关配置。

  2. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6 | RCC_APB1Periph_TIM7, ENABLE);
    通过RCC(Reset and Clock Control)外设时钟控制函数,使能了APB1总线下TIM6和TIM7定时器的时钟。这是配置任何外设之前必须的步骤。

3-4.

  • TIM_BaseInitStu.TIM_Prescaler = 7200 - 1;
    设置TIM6和TIM7的预分频器值为7199(因为预分频值是从0开始计数,所以7200-1=7199)。这表示定时器时钟将被分频7199次,具体分频效果取决于TIM6和TIM7所连接的时钟频率。
  • TIM_BaseInitStu.TIM_Period = 10000 - 1;
    配置自动重载寄存器(ARR)的值为9999,意味着当计数器从0计数到9999时,将产生一个更新事件并重置计数器。

5-6.

  • TIM_TimeBaseInit(TIM6, &TIM_BaseInitStu);
    使用之前配置的结构体TIM_BaseInitStu来初始化TIM6定时器的基础计时功能。
  • TIM_TimeBaseInit(TIM7, &TIM_BaseInitStu);
    同样地,初始化TIM7定时器。

7-8.

  • TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
    允许TIM6在更新事件发生时产生中断(即计数器达到ARR值时)。
  • TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
    同样为TIM7配置更新中断。

9-10.

  • TIM_Cmd(TIM6, DISABLE);
    禁止TIM6定时器开始计时。
  • TIM_Cmd(TIM7, DISABLE);
    同样禁止TIM7定时器开始计时。

我们把定时器设置自动重装载寄存器 ARR 的值为 10000,设置时钟预分频器为 7199, 则驱动计数器的时钟:CK_CNT = CK_INT / (7199+1)=0.01M, 则计数器计数一次的时间等于:1/CK_CNT=100us,当计数器计数到 ARR 的值 10000时, 产生一次中断,则中断一次的时间为:1/CK_CNT*ARR=1s。

4.中断配置

	NVIC_InitTypeDef NVIC_InitStu;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	NVIC_InitStu.NVIC_IRQChannel = TIM6_IRQn | TIM7_IRQn;
	NVIC_InitStu.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStu.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStu.NVIC_IRQChannelSubPriority = 1;
	
	NVIC_Init(&NVIC_InitStu);
  1. NVIC_InitTypeDef NVIC_InitStu;
    定义了一个NVIC初始化结构体类型的变量NVIC_InitStu,用于存放中断相关的配置信息。

  2. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    调用此函数来配置中断优先级分组。这里选择了优先级分组1,STM32的中断优先级分为5个级别(0-4,0为最高),分组1意味着有1位用于抢占优先级,3位用于子优先级。这意味着最多可以配置8种不同的抢占优先级和8种子优先级组合。

3-7. 配置NVIC_InitStu结构体的成员:

  • NVIC_InitStu.NVIC_IRQChannel = TIM6_IRQn | TIM7_IRQn;
    设置需要配置的中断通道,这里同时配置了TIM6、TIM7的中断。
  • NVIC_InitStu.NVIC_IRQChannelCmd = ENABLE;
    启用上述指定的中断通道。
  • NVIC_InitStu.NVIC_IRQChannelPreemptionPriority = 1;
    设置抢占优先级为1(在分组1的情况下,范围是0-7,1表示较高中断优先级)。
  • NVIC_InitStu.NVIC_IRQChannelSubPriority = 1;
    设置子优先级也为1(在本分组中,范围同样是0-7,数值越小优先级越高)。
  1. NVIC_Init(&NVIC_InitStu);
    最后,使用NVIC_Init函数,根据NVIC_InitStu结构体中设定的参数来初始化指定的中断通道,完成中断优先级的配置。

相关推荐

  1. TIM定时器

    2024-07-21 22:20:03       49 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-21 22:20:03       171 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-21 22:20:03       189 阅读
  3. 在Django里面运行非项目文件

    2024-07-21 22:20:03       157 阅读
  4. Python语言-面向对象

    2024-07-21 22:20:03       170 阅读

热门阅读

  1. python 基础知识点(一)

    2024-07-21 22:20:03       34 阅读
  2. Python利用psutil库进行监控进程和资源

    2024-07-21 22:20:03       35 阅读
  3. SpringBoot RestHighLevelClient 按版本更新

    2024-07-21 22:20:03       42 阅读
  4. 跨域问题几种解决方法

    2024-07-21 22:20:03       38 阅读
  5. Python面试整理-文件处理

    2024-07-21 22:20:03       30 阅读
  6. 分式

    2024-07-21 22:20:03       36 阅读
  7. Spring WebFlux 介绍与效果演示示例

    2024-07-21 22:20:03       38 阅读
  8. django 需要修改的文件

    2024-07-21 22:20:03       37 阅读
  9. Random,ThreadLocalRandom,SecureRandom有什么区别

    2024-07-21 22:20:03       32 阅读
  10. Python 爬虫技术 第05节 异常处理

    2024-07-21 22:20:03       43 阅读
  11. 微信小程序开发:DOM 相关 API 使用详解

    2024-07-21 22:20:03       36 阅读
  12. QtQuick-QML语法

    2024-07-21 22:20:03       34 阅读
  13. Codeforces Round 960 (Div. 2)VP

    2024-07-21 22:20:03       37 阅读
  14. WebAssembly在前端开发中的创新与应用

    2024-07-21 22:20:03       37 阅读