主要外设:

  • TIM:Timer 定时器

TIM中的基本电路

定时器

计数器的基本功能

  • 复位:计数器值=初值、产生一个输出脉冲、产生更新事件(UEV)脉冲、更新中断标志UIF=1
  • 计数:计数器值递增或递减
  • 设置方向:递增或递减

计数器的使用:输入脉冲(N个)→计数器→输出脉冲(1个)

  • 输入脉冲的第一个边沿时刻:计数器进行复位
  • 输入脉冲的非首个边沿时刻:检查计数器是否等于终值
    • 若相等(溢出),对计数器进行复位
    • 若不等(计数),对计数器进行计数
  • 所以N=|终值-初值|+1

计数器的数据:初值、计数器值、终值

  • 计数器值:在计数器中,位宽决定计数范围(16bit计数器为0~65535)
  • STM32以0为初值或终值
  • 另一个值(终值或初值):所以计数器还需要一个额外的寄存器

计数器的定时(分频)功能:

  • 若输入为频率fp的时钟信号
  • 则输出为频率f的时钟信号f=fp*(1/N),N作为分频系数

时基单元

输入→预分频寄存器PSC及影子寄存器、预分频计数器→自动重载寄存器ARR及影子寄存器、核心计数器、计数器寄存器CNT→产生上溢、下溢

→产生UEV事件→[产生更新中断UIF、DMA中断]

  • PSC和ARR都有一个影子寄存器:真正起作用的寄存器、不能直接用代码修改
  • 代码修改PSC和ARR时
    • 直接修改影子寄存器的值(无缓冲)
    • 等到UEV事件时,统一修改影子寄存器的值(缓冲)

时钟源

输入信号→时钟源选择→时基单元

  • 内部时钟
  • 引脚TIM_CH(外部输入):外部时钟模式1
  • 引脚TIM_ETR(外部输入):外部时钟模式2
  • 内部触发信号ITR:内部其他定时器

外部时钟模式2:

引脚TIM_ETR→GPIO AFR→GPIO输入电路→边沿选择SMCR(ETP)→分频器SMCR(ETPS)→滤波器SMCR(ETF)→时钟源选择SMCR(ECE、SMS)→时基单元

引脚TIM_CH→输入捕获单元→捕获/比较寄存器→中断/DMA

捕获/比较寄存器→输出比较单元→引脚TIM_CH

定时器分类

  • 内核定时器(CortexM):SysTick系统节拍定时器
  • 外设定时器(STM32):TIM基本、通用、高级定时器、看门狗定时器、实时时钟RTC、低功耗定时器

TIM_Base时基单元:内部时钟模式

主要功能:用内部时钟,定时触发事件/中断

数据通路

内部时钟APB timer→时钟源选择SMCR(ECE、SMS)→时基单元→中断→NVIC→CPU

时基单元TIM_Base:输入脉冲(N1*N2个)→预分频模块计数模块→输出脉冲(1个)

  • 预分频模块:预分频计数器+预分频寄存器
  • 计数模块:核心计数器+自动重载寄存器+计数器寄存器

预分频模块

  • 预分频计数器:主要用于分频,计数值为0→PSC,分频系数为N1=PSC+1
  • 预分频寄存器:预分频系数PSC(计数终值)

计数模块

  • 核心计数器:可用于分频或计数
  • 自动重载寄存器:设置自动重载系数ACC(计数初值或终值)
  • 计数器寄存器:记录当前计数值CNT

计数模式:针对核心计数器

  • 递增计数:0→ARR(上溢)
  • 递减计数:ARR→0(下溢)
  • 中心对齐计数:0→ARR-1(上溢)、ARR→0(下溢)

时基单元的定时功能

  • 输入时钟信号:APB的定时器时钟TIM_CLK
  • 输入时钟信号fp,经过预分频模块和计数模块的两次分频,最终产生特定周期T(频率为f)的时钟信号
  • f=1/T=fp*(1/N1)*(1/N2)T*fp=N1*N2=(PSC+1)*(ACC+1)PSC=N1-1,ACC=N2-1

硬件设计

  • TIM10挂接在APB2总线上,定时器时钟TIM2_CLK为100MHz
  • 若产生10ms定时中断:10ms*100MHz=10000*1000
  • 即PSC=10000-1、ARR=1000-1

CubeMX的配置

  1. 引脚分配:无
  2. 外设配置:
  • Timers-TIM10 →模式→ 勾选Activated
  • Timers-TIM10 →参数设置(时基单元设置)→ PSC预分频器=10000-1、ARR自动重载寄存器=100-1、计数器模式=递增up、内部时钟分频器=不分频、auto-reload preload=disable
  • System Core-NVIC-NVIC中断表 →TIM1 update interrupt and TIM10 global interrupt→ 勾选使能、并设置抢占优先级和子优先级

用户代码

//USER CODE2:外设启动
__HAL_TIM_CLEAR_IT(&htim10, TIM_IT_UPDATE);//清除定时器初始化过程中的中断标志、避免定时器一启动就进入中断
HAL_TIM_Base_Start_IT(&htim10); // 启动定时器中断、启动定时器 //USER CODE4:定义中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance==TIM10){//判断更新中断来源 }
}

TIM_Base时基单元:ETR外部时钟模式2

主要功能:对外部输入脉冲进行计数

数据通路:

TIM_ETR引脚→GPIO输入电路→GPIO的AFR→预分频PSC=0(影子寄存器)→核心计数器CNT

时基单元的外部脉冲计数功能

  • 输入脉冲信号:捕获/比较通道CH、外部触发引脚ETR
  • PSC通常置0
  • ACC通常置为特别大的值(防止计数结束前发生溢出)
  • 读取CNT中的计数值

硬件设计

PA0复用为TIM2_ETR,用来接收外部的脉冲信号

CubeMX的配置

  1. 引脚分配:
  • 在外设配置时,可自动将PA0复用为TIM2_ETR
  1. 外设配置:
  • Timers-TIM2 → 模式 →时钟源=ETR2
  • Timers-TIM2 → 参数设置(时基单元设置)→ PSC预分频器=0、ARR自动重载寄存器=0xFFFFFFFF、计数器模式=向上、内部时钟分频器=不分频、auto-reload preload=disable
  • Timers-TIM2 → 参数设置(时钟源)→ 时钟滤波=0、时钟极性=不反向、时钟分频=不分频

用户代码

HAL_TIM_Base_Start(&htim2);//启动定时器
uint32_t Result = __HAL_TIM_GET_COUNTER(&htim2); // 读取外部脉冲计数值

TIM_OC输出比较单元

时基单元TIM_Base为内部时钟模式:CNT从初值→CCR→终值循环变化

捕获/比较寄存器CCR→输出控制→引脚TIM_CH(输出比较通道)

TIM_CH的输出比较模式分类:

  • PWM1:[初值→CCR)时输出有效电平、[CCR→终值]时输出无效电平(PWM2相反)(脉冲宽度调制波形)
  • ACTIVE:CNT=CCR(匹配)时输出有效电平、不匹配时输出无效电平(INACTIVE相反)(单脉冲模式)
  • TOGGLE:CNT=CCR(匹配)时输出电平翻转
  • TIMING:CNT=CCR(匹配)时无通道输出(冻结模式)
  • FORCED_ACTIVE:强制输出有效电平
  • FORCED_INACTIV:强制输出无效电平

TIM_CH输出有效电平的极性:高电平有效、低电平有效

脉冲宽度调制Pulse Width Modulation:对模拟信号电平进行数字编码的方法,应用于灯光亮度调节、功率控制、电机控制等领域

  • 周期Period:一个完整PWM波形所持续时间(时基单元提供)
  • 占空比Duty:(高电平持续时间Ton/PWM周期)x100%(输出比较单元提供)

硬件设计

PA5复用为TIM2_CH1,产生周期为1ms,占空比为47.5%的PWM信号

  • TIM2挂接在APB2总线上,定时器时钟TIM2_CLK为100MHz
  • PWM的周期为200ms:1ms*100MHz=100*1000设PSC=100-1、ARR=1000-1、向上计数
  • 占空比为47.5%,若使用PWM1、输出极性为高电平有效、则CCR为475

CubeMX的配置

  1. 引脚分配:
  • Pinout View:搜索PA5 设置为TIM2_CH1
  1. 外设配置:
  • Timers-TIM2 →模式→ 时钟源=内部时钟源、Channel1=PWM通用CH1
  • Timers-TIM2 →参数设置(时基单元设置)→ PSC预分频器=100-1、ARR自动重载寄存器=1000-1、计数器模式=向上、内部时钟分频器=不分频、auto-reload preload=disable
  • Timers-TIM2 →参数设置(PWM输出通道设置)→ 模式=PWM mode1、脉冲(CCR)=475、通道极性=高电平有效、输出比较预装载=使能(PWM波形循环)、快速模式:禁用

用户代码

//USER CODE2:外设启动
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); //USBR CODE3:后台程序(无限循环)
//呼吸灯:PWM的不同占空比时,在人眼的视觉暂留效果,导致LED看起来“不同亮度”
//扫描频率需大于50Hz(周期20ms),以避免闪烁
__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,Duty);//步进20%的占空比
HAL_Delay(100);

TIM_IC输入捕获单元

主要功能:测量信号的参数,比如周期和频率

  • 被测信号的周期 = 两次上升沿CNT的差值 x ( PSC + 1 ) / 时基单元周期

引脚TIM_CH(输入捕获通道)→输入滤波→边沿检测→当前通道直接输入方式、其他通道的间接输入方式→预分频器→捕获/比较寄存器CCR

  • 当TIM_CH的上升沿或下降沿时,将CNT的值写入到CCR中

硬件设计

PA0复用为TIM2_CH1,输入捕获

PA6复用为TIM3_CH1,比较输出PWM,即被测信号源(100KHz占空比50%的方波)

CubeMX的配置

  1. 引脚分配:
  • Pinout View:搜索PA0 设置为TIM2_CH1
  1. 外设配置:
  • Timers-TIM2 →模式→ 时钟源=内部时钟源、Channel1=输入捕获 直接模式
  • Timers-TIM2 →参数设置(时基单元设置)→ PSC预分频器=0、ARR自动重载寄存器=0xFFFFFFFF、计数器模式=向上、内部时钟分频器=不分频、auto-reload preload=disable
  • Timers-TIM2 →参数设置(输入捕获通道1设置)→ 极性选择=上升沿、输入捕获通道IC选择=直接输入模式、预分频器分频比=不分频、输入滤波=0

用户代码

uint32_t Diff = 0 ; // 存放捕获差值
uint8_t MeasureFlag = 0 ; // 测量完成标志:0表示未完成,1表示完成
uint8_t CapIndex = 0 ; // 捕获指示:0表示没有开始捕获,1表示完成一次捕获
uint32_t CapVal1 = 0 ; // 存放第一次捕获值
uint32_t CapVal2 = 0 ; // 存放第二次捕获值 //USER CODE2:外设启动
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); // 启动定时器2通道1的输入捕获功能 //USBR CODE3:后台程序(无限循环)
if( MeasureFlag == 1){ // 判断测量标志是否置位
Diff =CapVal2 >= CapVal1?(CapVal2 - CapVal1):(0xFFFFFFFF + 1 - CapVal1 + CapVal2); // 计算差值
printf ("Period is: %.4f ms\r\n",(double)Diff/100000); // 计算信号周期
MeasureFlag = 0; // 清除测量完成标志
HAL_Delay(1000);
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); // 启动下一次捕获
}
//USER CODE4:定义中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){
if(htim->Instance==TIM2){//判断发生捕获中断的定时器
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){//判断发生捕获中断的通道
if(CapIndex == 0){ //存放第一次捕获时CCR的值
CapVal1=HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);
CapIndex=1;
}else if(CapIndex == 1){//存放第二次捕获时CCR的值
CapVal2=HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);
HAL_TIM_IC_Stop_IT(&htim2, TIM_CHANNEL_1); // 停止捕获
CapIndex=0; //重置捕获标志
MeasureFlag=1;//测量完成的结束标志
}
}
}
}

STM32外设:定时器TIM的更多相关文章

  1. STM32通用定时器(转载)

    STM32的定时器功能很强大,学习起来也很费劲儿. 其实手册讲的还是挺全面的,只是无奈TIMER的功能太复杂,所以显得手册很难懂,我就是通过这样看手册:while(!SUCCESS){看手册-}才搞明 ...

  2. STM32 基于定时器的PWM发生器

    脉冲宽度调制(PWM),是英文"Pulse Width Modulation" 的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术.简单一点,就 ...

  3. Stm32高级定时器(三)

    Stm32高级定时器(三) 1 互补输出和死区插入 1.1 死区:某个处于相对无效状态的时间或空间 本来OCX信号与OCXREF时序同相同步,OCXN信号与OCXREF时序反相同步.但为了安全考虑,以 ...

  4. STM32通用定时器原理

    /************************************************************************************************ 转载 ...

  5. STM32 通用定时器的几种配置方式

    STM32 通用定时器的几种配置方式 //------------------------------------------------------------------------------ ...

  6. STM32通用定时器配置

    一.STM32通用定时器原理 STM32 系列的CPU,有多达8个定时器,其中TIM1和TIM8是能够产生三对PWM互补输出的高级定时器,常用于三相电机的驱动,它们的时钟由APB2的输出产生.其它6个 ...

  7. stm32基本定时器timer6的原理与使用

    /********************基本定时器 TIM 参数定义,只限 TIM6.7************/ /* 一.定时器分类 STM32F1 系列中,除了互联型的产品,共有 8 个定时器 ...

  8. STM32——通用定时器基本定时功能

    STM32——————通用定时器基本定时功能                                                                           1.  ...

  9. Stm32高级定时器(四)

    Stm32高级定时器(四) 1 编码器接口模式 1.1 编码器原理 什么是正交?如果两个信号相位相差90度,则这两个信号称为正交.由于两个信号相差90度,因此可以根据两个信号哪个先哪个后来判断方向.根 ...

  10. Stm32高级定时器(二)

    Stm32高级定时器(二) 1 主从模式:主?从? 谈论主从,可知至少有两个以上的触发或者驱动信号,stm32内部有多个定时器,可以相互之间驱动或者控制. 主模式:定时器使能只受驱动时钟控制或者输出控 ...

随机推荐

  1. 搞懂 Vue3 中的各种 ref:toRef,toRefs,isRef,unref...

    在 Vue3 中,有许多与响应式相关的函数,例如 toRef.toRefs.isRef.unref 等等.合理地使用这些函数可以在实际开发中大大提高效率.本文将详细介绍这些函数的用法,让我们在实际开发 ...

  2. SSM登录操作

    1.编写实体类 略 2. 写mapper映射文件 通过名字查询 通过ID主键查询... 略 写dao CRUD相关抽象方法 List<Student> getAll(); Student ...

  3. 《SQL与数据库基础》23. 读写分离

    目录 读写分离 一主一从 准备 配置 双主双从 准备 配置 主库配置 从库配置 从库关联主库 主库相互复制 双主双从读写分离 本文以 MySQL 为例.以 MyCat 数据库中间件为例,通过 MyCa ...

  4. VB快速上手文档教程

    前言 本来我想可能不会接触到这个语言, 不过在用excel时需要用到VBA. 这就不得不专门去学习一番. 入了个门, 专门写个文档留着. 万一以后用得到呢- 论VB, 我还是初学者. 如有弄错了的地方 ...

  5. Java实践项目 - 购物车模块

    Smiling & Weeping ----世界上美好的东西不太多,立秋傍晚从河对岸吹来的风, 加入购物车 1.数据创建--创建t_cart CREATE TABLE t_cart( cid ...

  6. 用OLED屏幕播放视频(2): 为OLED屏幕开发I2C驱动

    下面的系列文章记录了如何使用一块linux开发扳和一块OLED屏幕实现视频的播放: 项目介绍 为OLED屏幕开发I2C驱动 使用cuda编程加速视频处理 这是此系列文章的第2篇, 主要总结和记录一个I ...

  7. Node.js vs. Spring Boot:Hello World 性能对决,谁更快一点?

    前言: Spring Boot 在 Java 生态中备受欢迎,它是一款基于 Java 构建的轻量级服务端框架,主要用于 Web 服务.Spring Boot 的应用使得创建各类基于 Spring 的企 ...

  8. containerd镜像拉取配置

    背景: 公司要求部署最一套新版的k8s系统来部署生产应用,说实话很头疼.因为k8s自1.23版本之后就用不docker作为容器的默认运行时了,而是采用的containerd,这就带来了一系列的问题.没 ...

  9. 【保姆级安装使用教程#1】Xshell与Xftp的下载、安装和使用

    1. 下载 官网下载地址:==Xshell与Xftp下载地址== 当然也可以用鄙人的百度网盘连接下载这是链接:链接百度网盘下载Xshell与Xftp分别下载Xshell与Xftp 2. 安装Xshel ...

  10. Redis——Redis面试题

    文章目录 概述 什么是Redis Redis有哪些优缺点 为什么要用 Redis /为什么要用缓存 为什么要用 Redis 而不用 map/guava 做缓存? Redis为什么这么快 数据类型 Re ...