STM32-定时器

article/2025/10/10 19:28:19

定时器(TIM)


本文来自于《STM32——江科大》的笔记整理。

文章目录

  • 定时器(TIM)
  • 7. TIM
    • 7.1 TIM定时中断
      • 7.1.1 TIM简介
      • 7.1.2 定时器类型
        • 7.1.2.1 基本定时器
        • 7.1.2.2 通用定时器
          • 内外时钟源的选择
          • 实现定时器的级联功能
            • TIM1&TIM8工作在从模式时内部触发时钟可选项
            • TIM2&TIM3&TIM4&TIM5工作在从模式时内部触发时钟可选项
            • TIM9&TIM12工作在从模式时内部触发时钟可选项
        • 7.1.2.3 高级定时器
      • 7.1.3 定时器定时中断(使用的内部时钟)
        • 定时中断基本结构
        • 时序图
          • 预分频器时序
          • 计数器时序
          • 计数器无预装时序
          • 计数器有预装时序
          • RCC时钟树
        • 代码:
          • Timer.c
          • Timer.h
          • main.c
      • 7.1.4 定时器外部时钟
        • 代码
        • Timer.c
        • Timer.h
        • main.c
    • 7.2 TIM输出比较
      • 7.2.1 输出比较简介
      • 7.2.2 PWM简介
      • 7.2.3 输出比较通道(通用定时器)
        • PWM的工作过程
      • 7.2.4 输出比较模式
      • 7.2.5 PWM基本结构
      • 7.2.6 输出比较通道(高级定时器)
      • 7.2.7 舵机简介
      • 7.2.8 直流电机及驱动简介
    • 7.3 PWM驱动硬件


7. TIM

7.1 TIM定时中断

7.1.1 TIM简介

  • TIM(Timer)定时器
  • 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
  • 16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时
  • 不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
  • 根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型

7.1.2 定时器类型

类型编号总线功能
高级定时器TIM1、TIM8APB2拥有通用定时器全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能
通用定时器TIM2、TIM3、TIM4、TIM5APB1拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能
基本定时器TIM6、TIM7APB1拥有定时中断、主模式触发DAC的功能
  • STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4

7.1.2.1 基本定时器

计数模式:只支持向上计数这一种模式

我们一般把 自动重装寄存器的值等于CNT计数器的值 会产生一个更新事件一个更新中断

更新中断过后,就会通往NVIC,此时我们需要配置好NVIC的定时器通道,这样定时器的中断就可以得到CPU的响应了

简单介绍主模式DAC的功能

  • 它可以让内部的硬件在不受程序的控制下实现自动运行

在这里插入图片描述

  • 这样定时器的更新就不需要通过中断来触发了DAC的转换了

7.1.2.2 通用定时器

计数模式

  • 向上计数模式
  • 向下计数模式
  • 中央对齐模式(向上/向下计数)

在这里插入图片描述

内外时钟源的选择

对于基本定时器来言只能选择内部时钟源(72MHz)

对于通用定时器而言还可以选择外部时钟

第一个外部时钟可以选择——》TIMx_ETR0引脚(PA0)的外部时钟

如果想在ETR外部引脚提供时钟,或者想对ETR时钟进行计数,把这个定时器当做计数器来用的话

配置外部时钟模式2

在这里插入图片描述

当这个TRG当做外部时钟来使用时,这一路叫做“外部时钟模式1”

在这里插入图片描述

实现定时器的级联功能
TIM1&TIM8工作在从模式时内部触发时钟可选项

在这里插入图片描述

TIM2&TIM3&TIM4&TIM5工作在从模式时内部触发时钟可选项

在这里插入图片描述

TIM9&TIM12工作在从模式时内部触发时钟可选项

在这里插入图片描述

ITRx由TS位确定,TIM1&TIM8工作在从模式下内部触发时钟的可选项,如果所选器件对应的定时器不存在则该选项也不存在,如TIM1可选择TIM5_TRGO/TIM2_TRGO/TIM3_TRGO/TIM4_TRGO。

在这里插入图片描述

在这里插入图片描述

然后在选择外部时钟模式1,就实现了定时器的级联

总结:

在这里插入图片描述

在这里插入图片描述

7.1.2.3 高级定时器

简单看一下,相对于变化的是

7.1.3 定时器定时中断(使用的内部时钟)

定时中断基本结构

在这里插入图片描述

时序图

预分频器时序

在这里插入图片描述

计数器时序

在这里插入图片描述

计数器无预装时序

在这里插入图片描述

计数器有预装时序

在这里插入图片描述

RCC时钟树

在这里插入图片描述
在这里插入图片描述

所有定时器的时钟都是72MHz

代码:

OLED代码 -->见STM32——OLED显示屏

Timer.c
#include "stm32f10x.h"                  // Device headervoid Timer_Init(void)
{//开启TIM2时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//选择内部时钟驱动(定时器上电后默认就是使用内部时钟)TIM_InternalClockConfig(TIM2);//配置结构体TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//设置时钟分频TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//向上计数TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//ARR自动重装器的值TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;//PSC预分频器的值TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//1s定时//重复计数器的值(高级定时器的功能不需要用)TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//初始化时基单元TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);//TIM_TimeBaseInit函数里面,手动生成的一次更新时间(与更新中断同时发生)//然后更新中断会置中断标志位//手动清除中断标志位,解决通电立刻进中断的问题TIM_ClearFlag(TIM2, TIM_FLAG_Update);//设置使能中断(选择更新中断)TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//配置NVIC//配置分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);//启动定时器TIM_Cmd(TIM2, ENABLE);
}//放到了主函数中
//void TIM2_IRQHandler()
//{
//	//检测对应标志位
//	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
//	{
//		//清除标志位
//		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
//	}
//}
Timer.h
#ifndef __TIMER_H
#define __TIMER_Hvoid Timer_Init(void);#endif
main.c
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"uint16_t Num;int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1, 1, "Num:");while (1){OLED_ShowNum(1, 5, Num, 5);}
}void TIM2_IRQHandler(void)
{//查询中断标准位if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){Num ++;//清除中断标准位TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

7.1.4 定时器外部时钟

注意:我选择的是 定时器2

引脚选择:PA0,因为PA0是TIM2的ERT引脚

代码

Timer.c

#include "stm32f10x.h"                  // Device headervoid Timer_Init(void)
{//选择定时器2(PA0是TIM2的ERT引脚)RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//通过ETR引脚的外部时钟模式2配置//第二个参数 外部触发预分频器//第三个参数 外部触发的极性//第三个参数 外部触发滤波器(0x00-0x0F)之间的值TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;//因为手动触发没那么快,所以时基不分频//触发一次CNT+1,如果设置分频了那可以需要触发几次,CNT才能+1TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);TIM_ClearFlag(TIM2, TIM_FLAG_Update);TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM2, ENABLE);
}
//查看CNT的值
uint16_t Timer_GetCounter(void)
{return TIM_GetCounter(TIM2);
}/*
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}
*/

Timer.h

#ifndef __TIMER_H
#define __TIMER_Hvoid Timer_Init(void);
uint16_t Timer_GetCounter(void);#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"uint16_t Num;int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1, 1, "Num:");OLED_ShowString(2, 1, "CNT:");while (1){OLED_ShowNum(1, 5, Num, 5);OLED_ShowNum(2, 5, Timer_GetCounter(), 5);}
}void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){Num ++;TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

7.2 TIM输出比较

7.2.1 输出比较简介

  • OC(Output Compare)输出比较

  • 输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形

在这里插入图片描述

  • 每个高级定时器和通用定时器都拥有4个输出比较通道(有各自的CCR寄存器,共有CNT计数器)

  • 高级定时器的前3个通道额外拥有死区生成和互补输出的功能

7.2.2 PWM简介

  • PWM(Pulse Width Modulation)脉冲宽度调制

  • 在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域

  • PWM参数:

    • 频率 = 1 / TS

    • 占空比 = TON / TS (下图占空比是50%)

在这里插入图片描述

  • 分辨率 = 占空比变化步距(1%,2%,3% … 分辨率1%)

在这里插入图片描述

7.2.3 输出比较通道(通用定时器)

PWM的工作过程

在这里插入图片描述
1、CCR1寄存器:捕获/比较值寄存器:设置比较值;
计数器值TIMx_CNT与通道1捕获比较寄存器CCR1进行比较,通过比较结果输出有效电平和无效电平

  • OC1REF=0 无效电平
  • OC1REF=1 无效电平

2、TIMx_CCMR1寄存器:OC1M[2:0]位:用于设置PWM模式

  • 110:PWM模式1
  • 111:PWM模式2

3、CCER寄存器:CC1P位:输入/捕获1输出极性。

  • 0:高电平为有效电平
  • 1:低电平为有效电平

4、CCER寄存器:CC1E位:输入/捕获1输出使能。

  • 0:关闭使能
  • 1:打开使能

5、输出电平信号

7.2.4 输出比较模式

模式描述
冻结CNT=CCR时,REF保持为原状态
匹配时置有效电平CNT=CCR时,REF置有效电平
匹配时置无效电平CNT=CCR时,REF置无效电平
匹配时电平翻转CNT=CCR时,REF电平翻转
强制为无效电平CNT与CCR无效,REF强制为无效电平
强制为有效电平CNT与CCR无效,REF强制为有效电平
PWM模式1向上计数:CNT<CCR时,REF置有效电平,CNT≥CCR时,REF置无效电平向下计数:CNT>CCR时,REF置无效电平,CNT≤CCR时,REF置有效电平
PWM模式2向上计数:CNT<CCR时,REF置无效电平,CNT≥CCR时,REF置有效电平向下计数:CNT>CCR时,REF置有效电平,CNT≤CCR时,REF置无效电平

7.2.5 PWM基本结构

在这里插入图片描述

参数计算

在这里插入图片描述

PWM的频率就等于计数器的更新频率。

原理讲解:

下图为向上计数模式:
在这里插入图片描述

  • 在PWM输出模式下,除了CNT(计数器当前值)、ARR(自动重装载值)之外,还多了一个值CCRx(捕获/比较寄存器值)。
  • 当CNT小于CCRx时,TIMx_CHx通道输出低电平;
  • 当CNT等于或大于CCRx时,TIMx_CHx通道输出高电平。

PWM的一个周期

  • 定时器从0开始向上计数
  • 当0-t1段,定时器计数器TIMx_CNT值小于CCRx值,输出低电平
  • t1-t2段,定时器计数器TIMx_CNT值大于CCRx值,输出高电平
  • 当TIMx_CNT值达到ARR时,定时器溢出,重新向上计数…循环此过程
  • 至此一个PWM周期完成

总结:

每个定时器有四个通道,每一个通道都有一个捕获比较寄存器,

将寄存器值和计数器值比较,通过比较结果输出高低电平,便可以实现脉冲宽度调制模式(PWM信号)

TIMx_ARR寄存器确定PWM频率,

TIMx_CCRx寄存器确定占空比

7.2.6 输出比较通道(高级定时器)

现在了解即可

在这里插入图片描述

7.2.7 舵机简介

  • 舵机是一种根据输入PWM信号占空比来控制输出角度的装置
  • 输入PWM信号要求:周期为20ms,高电平宽度为0.5ms~2.5ms

在这里插入图片描述

硬件电路

注意:如果单独给舵机单独供电,供电的负极要和STM32共地

在这里插入图片描述

7.2.8 直流电机及驱动简介

  • 直流电机是一种将电能转换为机械能的装置,有两个电极,当电极正接时,电机正转,当电极反接时,电机反转
  • 直流电机属于大功率器件,GPIO口无法直接驱动,需要配合电机驱动电路来操作
  • TB6612是一款双路H桥型的直流电机驱动芯片,可以驱动两个直流电机并且控制其转速和方向

在这里插入图片描述

硬件电路

在这里插入图片描述

H:高电平

L:低电平

在这里插入图片描述

7.3 PWM驱动硬件

见 STM32-PWM驱动硬件


关注收藏不迷路


给那些看完的朋友,奖励一个 赤赤博客-后端+前端,觉得不错的话可以推荐给身边的朋友哟!
在这里插入图片描述



http://chatgpt.dhexx.cn/article/Is2FM9Q7.shtml

相关文章

定时器

51中断系统的组成 定时/计数器的基本原理 逻辑开关闭合后&#xff0c;脉冲信号将对加1计数器充值。若计数器的容量为2 n (n为整数)&#xff0c;则当数值达到满计数值后将产生溢出&#xff0c;使中断请求标志TFx(x为0或1)进位为1&#xff0c;同时加1计数器清零。 如果在启动计数…

定时器同步

cube Gated Mode定时器同步 遇到的问题主从模式介绍&#xff08;参考&#xff09;解决方法定时器代码和开启代码 遇到的问题 在改造一块无刷电机电调时&#xff0c;遇到一些问题&#xff0c;其中就有&#xff1a;两个定时器分别是三个PWM的H和L驱动脚&#xff0c;当直接设置ti…

Linux定时器

原文&#xff1a;正点原子Linux驱动手册 Linux内核时间管理 系统时间管理需要一个硬件定时器提供时钟 &#xff0c;通常这个定时器时通用的&#xff0c;有利于系统移植。 像UCOS 或 FreeRTOS 一般使用 Systick 作为系统时钟源&#xff08;systick 是cortex-m 内核提供的定时器…

单片机定时器

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 一、定时器简介 C51中的定时器和计数器是同一个硬件电路支持的&#xff0c;通过寄存器配置不同&#xff0c;就可以将他当做定时器 或者计数器使用。 确切的说&#xff0c;定…

定时器使用

目录 一、定时器简单介绍 二、定时器的使用 三、定时器的实现 一、定时器简单介绍 定时器就相当于是闹钟 在网络编程中定时器非常关键的 比如浏览器浏览某个网页网卡了&#xff0c;浏览器就会转圈圈&#xff08;阻塞等待&#xff09;&#xff0c;这个等待不是无限等待&…

51单片机定时器/计数器(定时器中断)

51单片机定时器/计数器&#xff08;中断系统&#xff1a;定时器中断&#xff09; 实现功能 通过定时器终端控制LED灯 D1 间隔一秒闪烁 单片机型号&#xff1a;STC89C52 定时器介绍 1、51单片机定时器原理 定时器实质上就是一个加1计数器。它随着计数器的输入脉冲进行自加1&a…

定时器用法

在JavaScr中&#xff0c;定时器可以让我们在设定的时间间隔之后来执行代码&#xff0c;而不是在函数被调用后立即执行。而定时器分别有两种类型&#xff1a; 一次性定时器&#xff1a;仅在指定的延迟时间后触发一次。间隔性定时器&#xff1a;每隔一定的时间间隔就触发一次。 …

STM32定时器

目录 一 定时器的基本介绍 二 定时器的原理框图 1、定时器时钟 2 时基单元 3 捕获输入 4 PWM输出。 三 定时器的应用 1 定时器的基础定时计数功能 2 PWM比较输出 3 外部脉冲计数 a、外部触发输入&#xff08;ETR--外部时钟模式2&am…

SpringBoot定时器

SpringBoot定时器 1 介绍2 注解3 代码4 Cron表达式1. 格式2. 取值3. 特殊字符4. 经典案例 5 Cron既然那么麻烦就生成吧 1 介绍 定时器是一种控制任务延时调用&#xff0c;或者周期调用的技术。 作用&#xff1a;定时邮件、短信发送、更新数据、同步数据、检查数据库和缓存数据…

555定时器

555定时器 美国signetics公司1972年研制&#xff0c;取代机械式定时器&#xff0c;因为输入端有3个5k欧的电阻得名 电路结构 输入引脚 输出引脚 1.因为要接电容&#xff0c;电流较大&#xff0c;需要用oc门进行输出 2.需要接上拉电阻接vcc功能引脚 5号引脚对参考电压的影…

SysTick 定时器

11.1关于 SysTick 定时器 SysTick定时器(又名系统滴答定时器)是存在于Cortex-M3的一个定时器&#xff0c;只要是ARM Cotex-M系列内核的MCU都包含这个定时器。使用内核的SysTick定时器来实现延时&#xff0c;可以不占用系统定时器&#xff0c;节约资源。由于SysTick是在CPU核内…

JavaScript之定时器

定时器 一、 setTimeout() 定时器二、停止 setTimeout() 定时器三、setInterval() 定时器四、清除setInterval() 定时器五、电子时钟案例 在很多页面中&#xff0c;我们都可以看到一些倒计时或者和时间相关的效果&#xff0c;今天小熊将就JavaScript里面的倒计时做一概述。 首先…

STM32-通用定时器-定时器中断

1 STM32的定时器 STM32F103ZET6一共有8个定时器&#xff0c;其中分别为&#xff1a;高级定时器&#xff08;TIM1、TIM8&#xff09;&#xff1b;通用定时器&#xff08;TIM2、TIM3、TIM4、TIM5&#xff09;&#xff1b;基本定时器&#xff08;TIM6、TIM7&#xff09;。 …

Python——定时器

1.定时器 Timer定时器源码实现&#xff0c;和自定义一个线程方式一样&#xff0c;都是继承Thread类&#xff0c;重写了run()方法&#xff0c;只是实现的功能是延时执行一个函数或方法。 &#xff08;1&#xff09;线程定时器(Timer)解释&#xff1a; Timer类是Thread的子类&a…

[JavaEE]定时器

专栏简介: JavaEE从入门到进阶 题目来源: leetcode,牛客,剑指offer. 创作目标: 记录学习JavaEE学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 目录: 1.定时器的概念 2.标准库中的定时器 3.实现定时…

定时器的作用

一、简介。 在很多时候&#xff0c;我们设计网页时&#xff0c;为了某种表现形式&#xff0c;会使用到定时器这一功能&#xff0c;如&#xff1a;为了保证用户有仔细阅读我们的用户条款&#xff0c;我们会给确认按钮设置只有条款被打开&#xff0c;并超过5秒才允许点击。 二、…

定时器简介

文章目录 一.定时器基本介绍A.CPU时序B.定时器的原理 二.定时/计数器的相关寄存器A.定时器工作方式寄存器&#xff08;TMOD&#xff09;B.控制寄存器&#xff08;TCON&#xff09; 三.定时器的四种工作方式图解 一.定时器基本介绍 A.CPU时序 振荡周期&#xff1a;CPU外部晶振…

定时器基本常识

1.概念解读 1.1定时器和计数器&#xff0c;电路一样 1.2定时或者计数的本质就是让单片机某个部件数数 1.3当定时器用的时候&#xff0c;靠内部震荡电路数数 1.4当计数器用的时候&#xff0c;书外面的信号&#xff0c;读取针脚的数据 2.定时器怎么定时 定时器的本质原理&a…

定时器详解

1. 什么是定时器&#xff08;timer&#xff09; 定时器实际上就是Soc当中的一个内部外设。 &#xff08;1&#xff09;定时器与计数器 定时器常与计数器扯到一起&#xff0c;计数器也是soc当中的一个内部外设&#xff0c;计数器顾名思义是用来计数的&#xff0c;就和我们的秒…

定时器(Timer)

一、定时器是什么&#xff1f; 定时器类似于我们生活中的闹钟&#xff0c;可以设定一个时间来提醒我们。 而定时器是指定一个时间去执行一个任务&#xff0c;让程序去代替人工准时操作。 标准库中的定时器: Timer 方法作用void schedule(TimerTask task, long delay)指定dela…