0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32 TIM—基本定时器

冬至子 来源:纷纭杂谈 作者:CY_CHEN 2023-07-22 17:05 次阅读

STM32F4xx系列控制器有共有14个TIM定时器。其中2个高级控制定时器TIM1和TIM8、10 个通用定时器TIM2TIM5和TIM9TIM14、 2个基本定时器TIM6和TIM7。

各个定时器的特性如下:

图片

三种定时器中基本定时器是最简单的,功能少,结构简单,我们先从简单的开始入手。

基本定时器主要两个功能,第一就是基本定时功能,生成时基,第二就是专门用于驱动数模转换器(DAC)。由于PWM波可以实现DAC的输出,所以一般也就不用到基本定时器的第二个功能了。控制器的两个基本定时器 功能完全一样,但所用资源彼此都完全独立,可以同时使用。

基本定时器 TIM6 和 TIM7是一个 16位向上递增的定时器,当在自动重载寄存器(TIMx_ARR)添加一个计数值后并使能 TIMx,计数寄存器(TIMx_CNT)就会从 0 开始递增,当 TIMx_CNT 的数值与 TIMx_ARR值相同时就会生成事件并把 TIMx_CNT 寄存器清 0,完成一次循环过程。如果没有停止定时器就循环执行上述过程。

基本定时器框图

图片

时基单元

编程定时器的主要模块由一个 16 位递增计数器及其相关的自动重载寄存器组成。计数器的时钟可通过预分频器进行分频。

计数器、自动重载寄存器和预分频器寄存器可通过软件进行读写。即使在计数器运行时也可执行读写操作。

时基单元包括:

● 计数器寄存器 (TIMx_CNT)

● 预分频器寄存器 (TIMx_PSC)

● 自动重载寄存器 (TIMx_ARR)

自动重载寄存器是预装载的。每次尝试对自动重载寄存器执行读写操作时,都会访问预装载寄存器。预装载寄存器的内容既可以直接传送到影子寄存器,也可以在每次发生更新事件 UEV 时传送到影子寄存器,这取决于 TIMx_CR1 寄存器中的自动重载预装载使能位 (ARPE)。当计数器达到上溢值并且 TIMx_CR1 寄存器中的 UDIS 位为 0 时,将发送更新事件。该更新事件也可由软件产生。

计数器由预分频器输出 CK_CNT 提供时钟,仅当 TIMx_CR1 寄存器中的计数器启动位 (CEN)置 1 时,才会启动计数器。

请注意,实际的计数器使能信号 CNT_EN 在 CEN 置 1 的一个时钟周期后被置 1。

预分频器

预分频器可对计数器时钟频率进行分频,分频系数介于 1 和 65536 之间。该预分频器基于TIMx_PSC 寄存器中的 16 位寄存器所控制的 16 位计数器。由于 TIMx_PSC 控制寄存器有缓冲,因此可对预分频器进行实时更改。而新的预分频比将在下一更新事件发生时被采用。

计数模式

计数器从 0 计数到自动重载值(TIMx_ARR 寄存器的内容),然后重新从 0 开始计数并生成计数器上溢事件。

每次发生计数器上溢时会生成更新事件,或将 TIMx_EGR 寄存器中的 UG 位置 1(通过软件或使用从模式控制器)也可以生成更新事件。

通过软件将 TIMx_CR1 寄存器中的 UDIS 位置 1 可禁止 UEV 事件。这可避免向预装载寄存器写入新值时更新影子寄存器。这样,直到 UDIS 位中写入 0 前便不会生成任何更新事件,但计数器和预分频器计数器都会重新从 0 开始计数(而预分频比保持不变)。此外,如果TIMx_CR1 寄存器中的 URS 位(更新请求选择)已置 1,则将 UG 位置 1 会生成更新事件UEV,但不会将 UIF 标志置 1(因此,不会发送任何中断或 DMA 请求)。

发生更新事件时,将更新所有寄存器且将更新标志(TIMx_SR 寄存器中的 UIF 位)置 1(取决于 URS 位):

● 使用预装载值(TIMx_PSC 寄存器的内容)重新装载预分频器的缓冲区

● 使用预装载值 (TIMx_ARR) 更新自动重载影子寄存器

时钟源

计数器时钟由内部时钟 (CK_INT) 源提供。

CEN(TIMx_CR1 寄存器中)和 UG 位(TIMx_EGR 寄存器中)为实际控制位,并且只能通过软件进行更改(保持自动清零的 UG 除外)。当对CEN 位写入 1 时,预分频器的时钟就由内部时钟 CK_INT 提供。

接下来了解基本定时器的相关寄存器:

TIM6 和 TIM7 控制寄存器 1 (TIMx_CR1)

图片

位 7 ARPE:自动重载预装载使能 (Auto-reload preload enable)

0:TIMx_ARR 寄存器不进行缓冲。

1:TIMx_ARR 寄存器进行缓冲。

位 3 OPM:单脉冲模式 (One-pulse mode)

0:计数器在发生更新事件时不会停止计数

1:计数器在发生下一更新事件时停止计数(将 CEN 位清零)。

位 2 URS:更新请求源 (Update request source)

此位由软件置 1 和清零,用以选择 UEV 事件源。

0:使能时,所有以下事件都会生成更新中断或 DMA 请求。此类事件包括:

— 计数器上溢/下溢

— 将 UG 位置 1

— 通过从模式控制器生成的更新事件

1:使能时,只有计数器上溢/下溢会生成更新中断或 DMA 请求。

位 1 UDIS:更新禁止 (Update disable)

此位由软件置 1 和清零,用以使能/禁止 UEV 事件生成。

0:使能 UEV。更新 (UEV) 事件可通过以下事件之一生成:

— 计数器上溢/下溢

— 将 UG 位置 1

— 通过从模式控制器生成的更新事件

然后更新影子寄存器的值。

1:禁止 UEV。不会生成更新事件,各影子寄存器的值(ARR 和 PSC)保持不变。但如果将UG 位置 1,或者从从模式控制器接收到硬件复位,则会重新初始化计数器和预分频器。

位 0 CEN:计数器使能 (Counter enable)

0:禁止计数器

1:使能计数器

注意:只有事先通过软件将 CEN 位置 1 ,才可以使用门控模式。而触发模式可通过硬件自动将CEN 位置 1 。

在单脉冲模式下,当发生更新事件时会自动将 CEN 位清零。

TIM6 和 TIM7 控制寄存器 2 (TIMx_CR2)

图片

位 6:4 MMS:主模式选择 (Master mode selection)

这些位用于选择主模式下将要发送到从定时器以实现同步的信息 (TRGO)。这些位的组合如下:

000:复位——TIMx_EGR 寄存器中的 UG 位用作触发输出 (TRGO)。如果复位由触发输入生成(从模式控制器配置为复位模式),则 TRGO 上的信号相比实际复位会有延迟。

001:使能——计数器使能信号 (CNT_EN) 用作触发输出 (TRGO)。该触发输出可用于同时启动多个定时器,或者控制在一段时间内使能从定时器。计数器使能信号由 CEN 控制位与门控模式下的触发输入的逻辑或运算组合而成。

当计数器使能信号由触发输入控制时,TRGO 上会存在延迟,选择主/从模式时除外(请参见TIMx_SMCR 寄存器中对 MSM 位的说明)。

010:更新——选择更新事件作为触发输出 (TRGO)。例如,主定时器可用作从定时器的预分频器。

TIM6 和 TIM7 DMA/ 中断使能寄存器 (TIMx_DIER)

图片

位 8 UDE:更新 DMA 请求使能 (Update DMA request enable)

0:禁止更新 DMA 请求。

1:使能更新 DMA 请求。

位 0 UIE:更新中断使能 (Update interrupt enable)

0:禁止更新中断。

1:使能更新中断。

TIM6 和 TIM7 状态寄存器 (TIMx_SR)

图片

位 0 UIF:更新中断标志 (Update interrupt flag)

该位在发生更新事件时通过硬件置 1。但需要通过软件清零。

0:未发生更新。

1:更新中断挂起。该位在以下情况下更新寄存器时由硬件置 1:

— 上溢或下溢并且当 TIMx_CR1 寄存器中 UDIS = 0 时。

— 当由于 TIMx_CR1 寄存器中 URS = 0 且 UDIS = 0 而通过软件使用 TIMx_EGR 寄存器中的 UG 位重新初始化 CNT 时。

TIM6 和 TIM7 事件生成寄存器 (TIMx_EGR)

图片

位 0 UG:更新生成 (Update generation)

该位可通过软件置 1,并由硬件自动清零。

0:不执行任何操作。

1:重新初始化定时器计数器并生成寄存器更新事件。请注意,预分频器计数器也将清零(但预分频比不受影响)。

基本定时器初始化函数和中断处理函数如下

void Timer6_Init(u16 arr,u16 pre)
{
  u32 prigroup = 0;
  u32 priority = 0;
  //1. 开时钟
  RCC- >APB1ENR  |= 1< < 4;
  //2. 设置模式
//  TIM6- >CR1  = 0;
  TIM6- >CR1 |= 1< < 7;    //开启预装载功能
  TIM6- >CR1 &= ~(1< < 3);  //连续计数
  TIM6- >CR1 |= 1< < 2;    //UG置1,产生更新,但不产生中断
  TIM6- >CR1 |= 1< < 1;    //暂时不产生更新
  TIM6- >CR1 &= ~(1< < 0);  //配置完成前,先关闭计数器
  //3. 设置预分频
  Timer6_SetPre(pre);
  //4. 设置自动重装载
  Timer6_SetArr(arr);
  //5. 设置中断
    //清标记
    TIM6- >SR  &= ~(1< < 0);
    //开外设中断
    TIM6- >DIER  |= 1< < 0;
    //NVIC
    prigroup = NVIC_GetPriorityGrouping();
    priority = NVIC_EncodePriority(prigroup,1,2);
    NVIC_SetPriority(TIM6_DAC_IRQn,priority);
    NVIC_EnableIRQ(TIM6_DAC_IRQn);
  //6. 更新并开启计数器
    TIM6- >CNT = 0;
    //允许更新
    TIM6- >CR1 &= ~(1< < 1);
    //产生更新
    TIM6- >EGR |= 1< < 0;
    //开启定时器
    TIM6- >CR1 |= 1< < 0;
}


void Timer6_SetArr(u16 arr)//重装载值设置
{
  if(arr == 0)
    TIM6- >ARR   = 0;
  else
    TIM6- >ARR = arr - 1;
}


void Timer6_SetPre(u16 pre)//分频设置
{
  if(pre == 0)
    TIM6- >PSC   = 0;
  else
    TIM6- >PSC = pre - 1;
}


u8 led_flag = 0;
//中断处理
void TIM6_DAC_IRQHandler()
{
  if(TIM6- >SR & (1< < 0))
  {
    //1. 清标记
    TIM6- >SR  &= ~(1< < 0);
    //2. 中断处理
      led_flag = ~led_flag;
  }
  else
    TIM6- >SR = 0;
}

接着编写主函数进行测试

#include "stm32f4xx.h"
#include "led.h"
#include "timer.h"


int main()
{
  LED_Init();
  Timer6_Init(18000,1250);    //一个周期0.125s

  while(1)
  {
    if(led_flag)              
        LED_Toggle();    //0.25sLED翻转一次,1s翻转四次
  }
}
```至此,基本定时器的功能就结束了,对于通用定时器和高级定时器的定时功能与基本定时器使用方法一样,这里就不再赘述。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 控制器
    +关注

    关注

    112

    文章

    15223

    浏览量

    171188
  • 定时器
    +关注

    关注

    23

    文章

    3147

    浏览量

    112036
  • 数模转换器
    +关注

    关注

    13

    文章

    741

    浏览量

    82433
  • PWM波
    +关注

    关注

    0

    文章

    98

    浏览量

    16700
  • STM32F4
    +关注

    关注

    3

    文章

    192

    浏览量

    27676
收藏 人收藏

    评论

    相关推荐

    STM32 TIM定时器的外部计数功能 计数值能不能为1啊?

    在利用STM32定时器TIM3和TIM4进行外部计数脉冲个数时,发现将重装载寄存的值设为0时的计数值不为1,而是不能进中断;所以问一下,
    发表于 05-19 16:00

    STM32 TIM定时器

    各位大虾帮忙看一下,我想在有数据操作时清除TIM2的计数值,当没有数据操作是让TIM2 正常计数,是不是在TIM2中断里调用TIM_SetCounter(
    发表于 03-12 14:48

    STM32 TIM定时器的使用(1)——定时 精选资料分享

    1、定时器简介STM32中,定时器的应用非常广泛,涉及计时、信号检测、电机控制等等,并且定时器章节的介绍在STM32F1的手册里面也占据了大
    发表于 08-05 06:50

    stm32TIM定时器 精选资料分享

    简介• STM32F1 系列中有 8 个定时器,分为基本定时器,通用定时器和高级定时器。• 基本定时器
    发表于 08-19 07:00

    如何去使用STM32 TIM定时器

    定时器总共分为哪几种?如何去使用STM32TIM定时器呢?
    发表于 10-27 07:18

    STM32 TIM定时器怎么使用?

    输入捕获的原理是什么?STM32 TIM定时器怎么使用?
    发表于 11-18 06:32

    stm32TIM定时器的工作框图求分享

    stm32TIM定时器的工作框图求分享
    发表于 11-24 06:54

    萌新求助,求STM32 TIM定时器的库函数学习笔记

    萌新求助,求STM32 TIM定时器的库函数学习笔记
    发表于 11-24 06:31

    STM32通用定时器TIM2的使用方法解析

    STM32中一共有11个定时器,其中2个高级控制定时器,4个普通定时器和2个基本定时器,以及2个看门狗
    发表于 11-21 15:40 6.3w次阅读
    <b class='flag-5'>STM32</b>通用<b class='flag-5'>定时器</b><b class='flag-5'>TIM</b>2的使用方法解析

    STM32定时器基本计数原理解析

    STM32TIM定时器分为三类:基本定时器、通用定时器和高级定时器。从分类来看就知道
    发表于 12-27 16:20 1.8w次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>定时器</b>基本计数原理解析

    STM32---定时器知多少

    的第14,15,16章节,里面对定时器的知识有详细的介绍。STM32F1系列的开发板一共有8个定时器,按照功能的不同可以分为:高级定时器TIM
    发表于 11-30 14:36 19次下载
    <b class='flag-5'>STM32</b>---<b class='flag-5'>定时器</b>知多少

    STM32定时器学习---基本定时器

    STM32F1系列的产品,除了互联网产品外,工作8个,3种定时器,其中一种就是基本定时器。那么STM32单片机的基本定时器如何操作以及编程呢
    发表于 12-02 14:06 27次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>定时器</b>学习---基本<b class='flag-5'>定时器</b>

    STM32 TIM定时器的使用(5)——PWM驱动电调控制无刷电机

    CCR的值,从而使PWM的占空比跟随按键改变,将PWM信号输入电调,最终实现对无刷电机的控制。3、实验用具正点原子STM32F1精英板新西达30A无刷电调A2212 1000KV无刷电机4、程序设计分析程序设计可以分为三大块:定时器、按键配置电机控制程序按键中断服务函数
    发表于 01-14 12:18 17次下载
    <b class='flag-5'>STM32</b> <b class='flag-5'>TIM</b><b class='flag-5'>定时器</b>的使用(5)——PWM驱动电调控制无刷电机

    STM32通用定时器TIM2的使用方法解析

    STM32中一共有11个定时器,其中2个高级控制定时器,4个普通定时器和2个基本定时器,以及2个看门狗
    发表于 02-11 10:59 6次下载
    <b class='flag-5'>STM32</b>通用<b class='flag-5'>定时器</b><b class='flag-5'>TIM</b>2的使用方法解析

    STM32的通用定时器

    STM32F1 的定时器非常多,由 2 个基本定时器TIM6、TIM7)、4 个通用定时器
    的头像 发表于 02-10 14:47 2560次阅读