文章目录

  • 一、TIM简介
  • 二、定时器类型
    • 基本定时器
    • 通用定时器
    • 高级定时器
  • 三、定时中断基本结构
  • 四、时序图
    • 预分频器时序
    • 计数器时序
    • 计数器无预装时序
    • 计数器有预装时序
    • RCC时钟树
  • 五、定时器定时中断
  • 六、定时器外部时钟
  • 七、定时器库函数(tim.h)

一、TIM简介

  • TIM(Timer)定时器
  • 定时器可以对输入的时钟(方波)进行计数,并在计数值达到设定值触发中断
    • 输入时钟: 内部时钟,外部时钟
    • 对输入的时钟进行计数就是计时
  • 每个定时器都具备的3个核心:
    • 16位计数器【寄存器】
    • 16位预分频器【对计数器时钟分频】
    • 16位自动重装寄存器【计数的目标值】
    • 3个核心组成时基单元
    • 在72MHz时钟下可以实现最大59.65s(65536*65536/72MHZ)的定时(中断)
      • 72MHZ/65536=最小时钟分频(最大的周期)
      • 时钟分频倒数是周期,周期表示一个方波的时长,乘以重装值(方波的个数)就是定时(中断)的时长
  • 定时器支持级联,级联一个定时器:59.65* 65536* 65536
  • 不仅具备基本的定时中断功能,定时器还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
  • 根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型

二、定时器类型


注意:STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4

基本定时器

  • 只能连接内部时钟(72MHZ)
  • 预分频的值+1=实际的分频系数,例如预分频的值为1则表示分频系数为2,是2分频,则输出36MHZ
  • 自动重装寄存器满了可以触发更新中断(通往NVIC)和更新事件(不会触发中断,触发其他外设电路)
  • 计数器:对预分频后的时钟(方波)进行计数
  • 主模式触发DAC:防止主程序频繁被中断,通过主模式,将定时器的更新事件映射到触发输出,定时器的更新就无须通过更新中断来实现【类似于DMA控制器,实现硬件自动化】

通用定时器

  • 通用定时器包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能

  • 通用定时器和高级定时器支持向上计数,向下技术,中央对齐模式

  • 编码器接口:读取正交编码器的输出波形

  • 该框图可以分为三个部分

    • 上面部分可以完成定时中断功能,内外时钟源选择和主从触发模式选择

    • 下面由输入捕获单元和输出比较电路组成

      • IC输入比较 ;CC捕获比较寄存器 ;OC输出比较
  • 外部时钟模式2:通过TIMx_ETR——触发控制器——时基单元

    • 外部时钟可以来自TIMx_ETR,如图所示PA0可以输入外部时钟给stm32,输入的方波可以经过极性选择,边沿检测,预分频器,输入滤波等将波形进行整形
  • 外部时钟模式1(用作触发输入):通过TRGI——触发控制器——时基单元

    • TRGI当做外部时钟,时钟源来自多个地方
    • TRGI的输入可以是ETR(即TIMx_ETR)或ITR信号(即其他定时器)或TI1F_ED信号(输入捕获单元的CH1、CH2、CH3引脚)或TI1FP1和TI1FP2信号(CH1、CH2引脚的时钟)
      • 关于ITR信号:TRGO输出可以接到其他定时器,所以可以级联,而其他定时器的接入是设计在ITR信号部分
      • ITRX可以实现定时器级联功能
      • 关于TI1F_ED信号:ED表示上升沿和下降沿都有效
  • 各种定时器时钟源的GPIO配置

高级定时器

  • DTG死区生成电路:可以驱动三相无刷电机,输出一对互补的的PWM波
  • BRK完成 刹车输入功能
  • 重复计数器:每隔几个计数周期才发送一次更新事件和更新中断(即对输出的信号再进行分频,定时时间更长)

三、定时中断基本结构

  • RCC使能定时器,此时定时器的基准时钟和外设的工作时钟都设定好了

中断源选择:

  • 外部中断:有中断引脚选择AFIO,例如配置GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
  • 定时器中断:有中断输出控制,例如配置TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    • 如通用定时器框图所示,一个定时器中包含多个中断源如TGI,计数器值等于重装值,输入捕获与输出比较匹配时,参数可以选择如下

      void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)
      @param  TIM_IT: specifies the TIM interrupts sources to be enabled or disabled.
      *   This parameter can be any combination of the following values:
      *     @arg TIM_IT_Update: TIM update Interrupt source
      *     @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
      *     @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
      *     @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
      *     @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
      *     @arg TIM_IT_COM: TIM Commutation Interrupt source
      *     @arg TIM_IT_Trigger: TIM Trigger Interrupt source
      *     @arg TIM_IT_Break: TIM Break Interrupt source
      

四、时序图

预分频器时序

  • 计数器计数频率:CK_CNT = CK_PSC / (PSC + 1)【预分频的值+1=实际的分频系数】

  • 当计数到一半改变分频值,不会从那个时刻修改,而是等本次计数周期结束后才开始【结束会产生更新事件,预分频寄存器的值才会传递到预分频缓冲器,下一个周期才会起作用】

  • CK_PSC与CK_CNT的关系

  • 预分频寄存器实际上有两个,一个是供用户读写使用的预分频控制寄存器,该寄存器不会决定分配系数,另一个是缓冲寄存器(影子寄存器),真正起作用

计数器时序


计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1)= CK_PSC / (PSC + 1) / (ARR + 1)

例如:定时1s时间计算psc和arr:

  • 定时1s表示计数溢出频率是1HZ
  • 而计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1)=CK_PSC / (PSC + 1) / (ARR + 1)
  • 所以只要满足(PSC + 1) / (ARR + 1) = 72000000即可
  • psc=7200-1
  • arr = 10000-1

自动重装寄存器有缓冲寄存器可以使用,使用则是有预装,不使用则是无预装,通过设置ARPE位进行设置

计数器无预装时序

  • 更改自动加载寄存器时为36,此时计数器计数到36会触发中断更新

计数器有预装时序

  • 更改自动加载寄存器时为36,由于设置了缓冲寄存器,此时由自动加载影子寄存器起作用,到F5时才重新计数
  • 引入缓冲寄存器的目的是为了让值的变化与更新事件同步,防止运行过程中造成错误

RCC时钟树

  • 任何一个时钟源都可以开启或关闭,任何一个外设的时钟也可以被开启或关闭,将系统功耗降到最低
  • SystemInit()就是用来配置时钟树
    • 首先启动内部8MHZ高速RC振荡器作为系统时钟
    • 然后启动外部4-16MHZ高速石英晶体振荡器,进入PLL锁相环倍频到72MHZ,选择锁相环输出为系统时钟
  • 中间的SYSCLK就是系统时钟72MHZ
    • 进入AHB预分频器,当SystemInit()设置为1的时候就是不分频,还是72MHZ
    • APB1总线配置的系数是2,分频后为36MHZ,由于下面的支路会将频率扩大2倍,所以stm32中所有的定时器的预分频还是72MHZ。
    • 关于与门控制,就是通过该函数(RCC_APB1/2PeriphClockCmd())进行控制,
  • 时钟产生电路有四个震荡源:
    • 内部8MHZ高速RC振荡器
    • 外部4-16MHZ高速石英晶体振荡器(晶振),比内部8MHZ高速RC振荡器稳定
    • 外部32.768MHZ低速晶振,给RTC提供时钟
    • 内部40KHZ低速RC振荡器,给看门狗提供时钟
  • CSS:时钟安全系统:检测外部时钟运行状态,一旦外部时钟失效就会切换到内部时钟
  • 关系图:

五、定时器定时中断

Timer.c

#include "stm32f10x.h"                  // Device headeruint16_t Num;void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_InternalClockConfig(TIM2);//选择内部时钟源,如果是使用内部时钟可以不写TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频,有1分频2分频和4分频TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//计数器模式,向上、向下、中央对齐TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;//重装值TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 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;//stm32f10x.h中对应型号的参数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(void)
{//中断函数中查看标志位if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){Num ++;//中断函数中清除标志位TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}
  • .h头文件的声明里面省略了extern

六、定时器外部时钟

Timer.c

#include "stm32f10x.h"                  // Device headeruint16_t Num;void Timer_Init(void)
{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);//PA0可以作为TIMx_ETR信号输入端TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);//第二个参数是预分频器,第三个参数是外部触发的极性,第一是反向,低电平或下降沿有效,第二个是不反向,高电平或上升沿有效,最后一个参数是外部触发滤波器,通过设置16进制来设定采样频率和采样个数TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;//重装值TIM_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);
}uint16_t Timer_GetCounter(void)
{return TIM_GetCounter(TIM2);//获取计数器的值
}void TIM2_IRQHandler(void)
{//中断函数中查看标志位if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){Num ++;//中断函数中清除标志位TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

七、定时器库函数(tim.h)

void TIM_DeInit(TIM_TypeDef* TIMx);//恢复缺省配置
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//定时器时基单元配置
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);//使能运行控制
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);//使能中断输出信号
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);//内部时钟模式
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);//ITx其他定时器模式
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,uint16_t TIM_ICPolarity, uint16_t ICFilter);//TIx捕获通道
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);//ETR外部时钟模式1
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);//ETR外部时钟模式2
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);//不是配置时钟,而是设置ETR引脚的预分频器,极性,滤波器扥
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);//单独设置预分频值
void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);//改变计数器计数模式
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);//自动重装器是否设置预装功能
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);//给计数器写入一个值
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);//给自动重装器写入一个值
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);//获取当前计数器的值
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);//获取当前预分频的值
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

参考视频:江科大自化协

STM32——TIM简介与TIM中断相关推荐

  1. STM32 | STM32CubeMX基础之TIM

    一.定时器分类 定时器主要分为三类定时器: 基本定时器(TIM6,TIM7),通用定时器(TIM2~TIM5),高级定时器(TIM1,TIM8). 基本定时器(TIM6,TIM7) 可以看到,基本定时 ...

  2. STM32定时器详解——TIM详解

    TIM简介 1.TIM (Timer)定时器 2.定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断 3.16位计数器.预分频器.自动重装寄存器的时基单元,在72MHz计数时4.钟下可以实 ...

  3. 1. stm32 mcu简介

    1. stm32 mcu简介 1.1 stm32 mcu结构 1.2 STM32 MCU存储器映像 1.3 STM32 MCU系统时钟树 1.4 Cortex-M3简介 1.1 stm32 mcu结构 ...

  4. STM32(3)——外部中断的使用

    1 .简介 ARM Coetex-M3内核共支持256个中断,其中16个内部中断,240个外部中断和可编程的256级中断优先级的设置.STM32目前支持的中断共84个(16个内部+68个外部),还有1 ...

  5. STM32笔记 (七)中断系统与NVIC嵌套向量中断控制器

    简介 STM32拥有一个强大的中断系统,几乎所有外设都能产生中断,对于F103系列的单片机,ARM公司在Cortex‐M3 的内核水平上搭载了一个异常响应系统(异常就是中断), 支持为数众多的系统异常 ...

  6. stm32 USART接收总线空闲中断--USART_IT_IDLE

    stm32 USART接收总线空闲中断--USART_IT_IDLE 版权声明:转载请注明作者和链接 https://blog.csdn.net/Hola_ya/article/details/815 ...

  7. STM32 关于外部中断线、中断源和中断服务函数的问题

    STM32 关于外部中断线.中断源和中断服务函数的问题 中断线问题: 上图可以看出,PA0.PB0...PG0共用的EXTI0中断线,PA1.PB1...PG1共用的EXTI1中断线,也就是 编程里面 ...

  8. stm32的rxne和idle中断_STM32 HAL CubeMX 串口IDLE接收空闲中断+DMA

    历程详解 详解包括: 中断原理讲解 例程流程详解 库函数分析详解 对应寄存器介绍 对应函数介绍 对应注释详解 本篇文章提供两种方法: 一种是 :IDLE 接收空闲中断+DMA 一种是: IDLE 接收 ...

  9. STM32 IO 简介

    STM32 IO 简介 1.IO介绍 2.仿真与下载 1.IO介绍 STM32 的 IO 口可以由软件配置成如下 8 种模式: 1. 输入浮空 2. 输入上拉 3. 输入下拉 4. 模拟输入 5. 开 ...

最新文章

  1. [Bzoj2282]消防(二分答案+树的直径)
  2. ecshop商品详情相册顺序调整
  3. IT工程师实战英语之一
  4. mybatis整合数据权限
  5. button onclick 多个同名_多个按钮的OnClickListener()android
  6. AI+BI,真的如想象中的那么美好吗?
  7. U-Boot>WebHome翻译
  8. 合并数字 — m个数字消除相邻的差的绝对值为1的两个数中较大的那一个,直到没有两个相邻的差的绝对值为 1 的数(动态数组定义)
  9. Mac OS X上编写 ASP.NET vNext(一)KRE环境搭建
  10. Item 22: 当使用Pimpl机制时,在实现文件中给出特殊成员函数的实现
  11. Linux C/C++的编译
  12. JAVA学习,你必读的5本JAVA书籍
  13. 看娃娃创始人 丁力:我爱幼教,如同爱我的女儿
  14. The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals
  15. 让tp6显示错误信息及行号
  16. ABAP调用外部webservice 问题
  17. 数据可视化和可视化分析:你能看到数据世界
  18. 数字电视至显示android,手机投屏到电视的5种方法 看完才知道原来这么简单!
  19. 复工别慌,这里有 24 个渠道可以买到口罩
  20. SQL语句基础MySQL版

热门文章

  1. 开发工程师必备的一直网站
  2. YoLo: You Only Look Once: Unified, Real-Time Object Detection译文
  3. 传统企业互联网转型升级新玩法:技术合伙
  4. html拖拽模态框,bootstrap模态框实现拖拽效果
  5. java word转pdf 后通过 PdfReader 和 PdfStamper对pdf添加水印 通过poi等组件实现
  6. 两个div右侧固定,左侧自适应屏幕
  7. 3dMAX足球建模教程
  8. 让ChatGPT来制作Excel表格,ChatGPT实现文本和表格的相互转换
  9. Mysql为什么使用B+树(一)之红黑树简述
  10. 病毒宏基因组学(Meta-virome)