文章参考有
https://www.bilibili.com/video/BV1th411z7sn?p=14&share_source=copy_web

文章目录

  • 一、简介
    • 1、基本定时器
      • 关于预分频系数从1变到2的计数器时序图
    • 2、通用计时器
      • 时钟选择
      • 输入捕获和输出比较
    • 3、高级定时器
  • 二、代码
    • 1、关于时钟总线的外设情况
    • 2、初始化定时器参数
    • 3、关于中断
    • 4、一些别的函数
  • 三、LED显示计数

一、简介

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

1、基本定时器



主从触发模式:让内部的硬件在不受程序的控制下实现自动运行,使用得好可减轻CPU负担。
这个紫色部分就是主从触发模式的一个实例。
当我们使用DAC的时候,可能需要用DAC输出一段波形,就需要每隔一段时间就来触发一下来输出下一个电压点。也是会牵涉到中断。
使用主模式可以把这个定时器的更新事件,映射到这个触发输出TRGO,然后TRGO直接接到DAC的引脚上。(跟着动,不用再额外去申请中断)

预分频器、CNT计数器、自动重装载寄存器构成了最基本的计数电路,也叫做微时基单元。
预分频器、CNT计数器、自动重装载寄存器都是16位。
预分频器对收到的时钟(CK_PSC)进行分频:如果是写1,表示是2分频,输出=输入/2。预分频器和实际的分频系数差1。

(计数器计数频率)CK_CNT = CK_PSC(预分频器的值) / PSC(分频赋的值)+1

计数器可对预分频后的计数时钟进行计数。计数时钟每来一个上升沿,计数器就加1。达到自动重装器的值后产生中断信号,并且清零计数器,开启下一次计数。
当每一次计数的事件都一样,计数跟计时就没啥区别。

计数器溢出频率 f=计数器计数频率 / ARR(重装载寄存器的值)+1

定时的时间 T = 1 / f


在这里图上画的一个向上的折线箭头。就代表这里会产生中断信号
这种计数值等于自动重装值产生的中断,一般把他叫做更新中断。这个更新中断之后就会通到NVIC。我们再配置好NMC的定时器通道。那定时器的更新中断就能够得到CPU的响应。

向下的箭头代表事件,这里对应的叫更新事件。更新事件不会触发中断。但可以触发肉部其他电路的工作。

关于预分频系数从1变到2的计数器时序图


首先预分频系统的频率一直没变,是系统时钟。在CNT_EN置于0时(没开),定时器CK_CNT不启动。CNT_EN=1时CK_CNT启动。然后在开启后的第一个上升沿开始计数。
当预分频系数由1变为2时,首先写入预分频控制寄存器。在计数器完成这个周期(到达FC后),触发更新事件,预分频器缓冲器置为1.预分频计数器变为010101这么延续,在为0时CK_CNT上升沿触发一次。

我的理解是,预分频控制寄存器是虚假的皇帝,预分频控制缓存器才是摄政王,更新事件是玉玺。只要玉玺盖了剩下的才开始动。
当然这么也有可能存在问题,比如你在刚开始计数就更改时序,结果还要等到他把这一堆跑完才可以更改。所以在stm32库函数里这个摄政王是可以设置开不开的。

2、通用计时器

拥有定时中断、主模式触发DAC的功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能



中间的部分就是基本的定时中断。
上部分是有时钟源选择,编码接口,主从模式。
下部分是输入捕获和输出比较。

当计数值计到自动重装值时。计数值清零同时产生更新中断和更新事件
对于通用定时器而言。这个计数器的计数模式就不止向上计数这一种(也就是计数器从开始,向上自增,计到重装值,清零同时申请中断。)
通用定时器和高级定时器还支持向下计数模式和中央对齐模式。
向下计数模武就是从重装值况始。向下自减,减到0,回到重装值同时申请中断,这样循环。
中央对齐模式:先上升到重装值,申请中断,再向下自减,减到0,再申请中断。继续下一轮循环。
不过一般都是向上计数用得多。

时钟选择


内部时钟源

外部时钟源模式1
当TIMx_SMCR寄存器的SMS=111时,此模式被选中。计数器可以在选定输入端的每个上升沿或下降沿计数。

外部时钟源模式2
选定此模式的方法为:令TIMx_SMCR寄存器中的ECE=1
计数器能够在外部触发ETR的每一个上升沿或下降沿计数

输入捕获和输出比较

https://blog.csdn.net/wei348144881/article/details/109091539

3、高级定时器


二、代码

#include "Timer.h"
#include "stm32f10x.h"  void TIM3_Init()
{TIM_TimeBaseInitTypeDef TIM3_TimeBaseInitStructure;NVIC_InitTypeDef NVIC_InitStructure;//1、时钟使能RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//2、初始化定时器参数TIM3_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;   //时钟划分TIM3_TimeBaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;   //计数器模式向上计数TIM3_TimeBaseInitStructure.TIM_Period = 10000 -1;TIM3_TimeBaseInitStructure.TIM_Prescaler = 7200 -1;TIM3_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3,&TIM3_TimeBaseInitStructure);//3、允许TMI3更新中断TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//4、配置NVICNVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器//5、使能TIM3TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设}
 void TIM3_IRQHandler(void)   //TIM3中断
{if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 {//此处写入中断后要干的活的代码TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源 }
}

1、关于时钟总线的外设情况

TIM3挂载在APB1上

2、初始化定时器参数

溢出时间 = (自动重载值period + 1)*(分频系数prescaler + 1)/ 输入时钟频率

一般情况下这个输入时钟频率是内部时钟的情况下就是72MHz

输出频率(最后使用的频率)f = 输入时钟频率 / (分频系数prescaler + 1)

f的意思是,1s计X个数 。计1个数的时间是 :1 / f

所以溢出的总时间是 = 计一个数的时间(1/f) * 个数(重装载值)

1s = 1000ms = 1000000us
M = 10的六次方

 TIM_TimeBaseInitTypeDef TIM3_TimeBaseInitStructure; //这个定义必须放在函数开头,这里为了方便理解放在了一起
//2、初始化定时器参数TIM3_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;   //时钟划分TIM3_TimeBaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;   //计数器模式向上计数TIM3_TimeBaseInitStructure.TIM_Period = 10000 -1; //自动重载TIM3_TimeBaseInitStructure.TIM_Prescaler = 7200 -1;TIM3_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3,&TIM3_TimeBaseInitStructure);

记1个数的时间=7200 / 72000000 = 0.0001s = 0.1ms
总时间 = 0.1ms * 10000 = 1s

注意这两个数都是16位,最大值是65535

3、关于中断

配置NVIC时选择TIM3中断

TIM3中断函数

4、一些别的函数

恢复缺省配置
void TIM_DeInit(TIM_TypeDef* TIMx);
时基单元初始化
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
使能计数器
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);选择ITRx其他定时器时钟
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);选择TIx捕获通道的时钟
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,uint16_t TIM_ICPolarity, uint16_t ICFilter);
单独更改时基函数中的配置
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);

三、LED显示计数

led屏幕的使用函数是用的正点原子的函数

#include "stm32f10x.h"
#include "KEY.h"
#include "LED.h"
#include "delay.h"
#include "EXTI.h"
#include "lcd.h"
#include "Timer.h"uint8_t num;int main(void){ delay_init();            //延时函数初始化    LCD_Init();NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2TIM3_Init();while(1){LCD_ShowxNum(30,40,num,7,24,0);   }}void TIM3_IRQHandler(void)   //TIM3中断
{if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 {num++;TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源 }
}
#include "Timer.h"
#include "stm32f10x.h"  void TIM3_Init()
{TIM_TimeBaseInitTypeDef TIM3_TimeBaseInitStructure;NVIC_InitTypeDef NVIC_InitStructure;//1、时钟使能RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//2、初始化定时器参数TIM3_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;   //时钟划分TIM3_TimeBaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;   //计数器模式向上计数TIM3_TimeBaseInitStructure.TIM_Period = 10000 -1; //自动重载TIM3_TimeBaseInitStructure.TIM_Prescaler = 7200 -1;TIM3_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3,&TIM3_TimeBaseInitStructure);//3、允许TMI3更新中断TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//4、配置NVICNVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器//5、使能TIM3TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设}

STM32之定时器(TMI)相关推荐

  1. STM32普通定时器(TIM2-7)的时钟源

    STM32普通定时器(TIM2-7)的时钟源 转载于:https://www.cnblogs.com/LittleTiger/p/6218048.html

  2. [转]解决STM32开启定时器时立即进入一次中断程序问题

    [转]解决STM32开启定时器时立即进入一次中断程序问题 参考文章: (1)[转]解决STM32开启定时器时立即进入一次中断程序问题 (2)https://www.cnblogs.com/tubuji ...

  3. STM32系统定时器SysTick(只能向下递减)延时闪烁灯

    参考:stm32 系统定时器 SysTick 作者:点灯小哥 发布时间: 2021-03-10 13:46:00 网址:https://blog.csdn.net/weixin_46016743/ar ...

  4. STM32通用定时器(原理、结构体、库函数、定时器中断每秒闪烁一次灯) —— 时钟源、分频值、重装载值

    参考:stm32定时器与定时器中断 作者:打酱油的 发布时间: 2021-04-11 01:04:09 网址:https://blog.csdn.net/weixin_46098612/article ...

  5. stm32高级定时器 基础知识

    stm32高级定时器 高级定时器时基单元: 包含一个16位自动重装载寄存器 ARR 一个16位的计数器CNT,可向上/下计数 一个16位可编程预分频器PSC,预分频器时钟源有多种可选,有内部的时钟.外 ...

  6. stm32关定时器_STM32F103ZET6的基本定时器

    1.定时器的分类 STM32F103ZET6总共有8个定时器,它们是:TIM1~TIM8.STM32的定时器分为基本定时器.通用定时器和高等定时器. TIM6.TIM7是基本定时器.基本定时器是只能向 ...

  7. STM32之定时器中断控制LED闪烁

    上篇博客我们是用延时函数实现了LED的闪烁,今天我们使用STM32的定时器来使LED闪烁. 关于32的定时器的种类,今天我在这先不做过多的说明,有时间我会再另写一篇博客来专门介绍32的定时器.今天我们 ...

  8. STM32 通过定时器产生PPM信号

    标题STM32 通过定时器产生PPM信号 说明: 该代码基于STM32F103VET6 和STD标准库实现.若需要在其他单片平台使用需要调整IO,和定时器,底层代码. 定时器要达到us级定时. 实现原 ...

  9. STM32———高级定时器的死区时间计算方法

    STM32---高级定时器的死区时间计算方法 1.定时器的时钟分频因子和预分频系数的区别: 1.1 时钟分频因子(Clock division),决定定时器的工作时钟频率. tDTS=fDTS ; t ...

  10. STM32系统定时器SysTick

    1. SysTick系统定时器概述 学习完STM32的中断,下来就要学习STM32的定时器.就像电话最基本的功能是与人通话一样,定时器最基本的功能就是定时(STM32有些定时器的功能强大得超乎想象,当 ...

最新文章

  1. 不懂装饰器,就不是真正会 Python
  2. fork()会拷贝子线程吗?
  3. Runtime.getRuntime().exec()
  4. 各大主流.Net的IOC框架性能测试比较
  5. bbPress 介绍,安装和中文包
  6. 【codevs3153】【BZOJ3895】取石子游戏,博弈论之记忆化搜索
  7. nodejs服务器部署教程一
  8. java 调用存储过程structdescriptor_Spring SimpleJdbcCall如何在存储过程调用中为oracle STRUCT指定模式...
  9. 中国移动通信研究院笔试题2
  10. 写了个鼠标键盘模拟器,希望对大家有用哈!
  11. 对称矩阵(MIT课程)
  12. C++ Test的使用
  13. 蓝牙耳机选哪种的比较好、高端蓝牙耳机推荐
  14. es6 符号 双问号
  15. 用python画箱体图
  16. 嵌入式系统主要应用于哪些行业中?
  17. html 实现自动填表
  18. 无法联网的情况下,dbeaver离线安装数据库驱动-clickhouse
  19. Android 简单音乐播放器开发
  20. 操作系统原理,进程的基本状态,运行态,就绪态,等待态与转换模型,进程的其他状态,创建,终止,挂起与转换模型,Linux进程状态模型示例

热门文章

  1. 化工原理 --- 流体输送机械 --- 复习课
  2. python可以这样学豆瓣_豆瓣程序员如何利用Python开发出这么成功的社区?
  3. Android项目jenkins自动化构建之360加固(一)
  4. EFI 分区/恢复分区不可删除?你需要使用命令行了(全命令行操作)
  5. 如何用python代码,更改照片尺寸,以及更换照片底色
  6. NLP学习——信息抽取
  7. 完整视频播放器封装库,仿优酷
  8. cocos 战棋游戏 源代码_cocos2d-x完整RPG游戏源代码
  9. 串级 PID 为什么外环输出是内环的期望?(和我之前对串级PID的总结一样)
  10. 无人机项目跟踪记录六十五----无线收发模块电路