【嵌入式学习笔记】嵌入式入门6——定时器TIMER

1.定时器概述

1.1.软件定时原理

使用纯软件(CPU死等)的方式实现定时(延时)功能有诸多缺点,如CPU死等、延时不精准

void delay_us(uint32_t us)
{
    us *= 72;
    while(us--);
}

1.2.定时器定时原理

使用精准的时基,通过硬件的方式,实现定时功能定时器核心就是计数器

在这里插入图片描述

1.3.STM32定时器分类

在这里插入图片描述

1.4.STM32定时器特性表

  • F1系列
    在这里插入图片描述
  • H7系列
    在这里插入图片描述

1.5.STM32基本、通用、高级定时器的功能整体区别

在这里插入图片描述

2.基本定时器(以F1为例)

2.1.基本定时器简介

  • 基本定时器:TIM6/TIM7
  • 主要特性:
    16位递增计数器(计数值:0~65535)
    16位预分频器(分频系数:1~65536)
    可用于触发DAC
    在更新事件(计数器溢出)时,会产生中断/DMA请求

2.2.基本定时器框图

注意:事件默认产生,可以配置为不产生;中断默认不产生,可以配置为产生。
在这里插入图片描述

2.3.定时器计数模式及溢出条件

在这里插入图片描述
在这里插入图片描述
以下分别是递增、递减、中心对齐模式的实例说明
在这里插入图片描述

2.4.定时器中断实验相关寄存器

  • TIM6 和TIM7 控制寄存器 1(TIMx_CR1)
    用于设置ARR寄存器是否具有缓冲,使能/关闭计数器

有缓冲和没缓冲的区别

  • 延时1s+延时2s:在无缓冲情况下,延时1s后要重新写ARR,这个过程消耗时间导致误差;有缓冲情况下,可以在1s延时内写ARR,不会立即生效,在1s延时结束后生效,没有误差。
  • 延时1s+延时1s:不用写ARR,没有区别
    在这里插入图片描述
  • TIM6 和TIM7 DMA/中断使能寄存器(TIMx_DIER)
    用于使能更新中断
    在这里插入图片描述
  • TIM6 和TIM7 状态寄存器(TIMx_SR)
    用于判断是否发生了更新中断,由硬件置1,软件清零
    在这里插入图片描述
  • TIM6 和TIM7 计数器(TIMx_CNT)
    计数器实时数值,可用于设置计时器初始值,范围:0~65535
    在这里插入图片描述
  • TIM6 和TIM7 预分频器(TIMx_PSC)
    用于设置预分频系数,范围:0~65535,实际预分频系数等于PSC+1
    在这里插入图片描述
  • TIM6 和TIM7 自动重装载寄存器(TIMx_ARR)
    用于设置自动重装载值,范围:0~65535
    在这里插入图片描述

2.5.定时器溢出时间计算方法

在这里插入图片描述

2.6.定时器中断实验配置步骤

  • 配置定时器基础工作参数:HAL_TIM_Base_Init()
  • 定时器基础MSP初始化:HAL_TIM_Base_MspInit() 配置NVIC、CLOCK等
  • 使能更新中断并启动计数器:HAL_TIM_Base_Start_IT()
  • 设置优先级,使能中断:HAL_NVIC_SetPriority()、 HAL_NVIC_EnableIRQ()
  • 编写中断服务函数:TIMx_IRQHandler()等 -> HAL_TIM_IRQHandler()
  • 编写定时器更新中断回调函数:HAL_TIM_PeriodElapsedCallback()

关键结构体

typedef struct 
{ 
    TIM_TypeDef *Instance;            	/* 外设寄存器基地址 */ 
    TIM_Base_InitTypeDef Init;     		/* 定时器初始化结构体*/
     ...
}TIM_HandleTypeDef;
typedef struct 
{ 
    uint32_t Prescaler;              	/* 预分频系数 */ 
    uint32_t CounterMode;             	/* 计数模式 */ 
    uint32_t Period;                  	/* 自动重载值 ARR */ 
    uint32_t ClockDivision;             /* 时钟分频因子 */ 
    uint32_t RepetitionCounter;   		/* 重复计数器寄存器的值 */ 
    uint32_t AutoReloadPreload; 		/* 自动重载预装载使能 */
} TIM_Base_InitTypeDef;

在这里插入图片描述

2.7.编程实战:定时器中断实验

  • 使用定时器6,实现500ms定时器更新中断,在中断里翻转LED0
  • PSC=7199,ARR=4999为例。

代码暂不贴出

3.通用定时器(以F1为例)

3.1.通用定时器简介

  • 通用定时器:TIM2/TIM3 /TIM4 /TIM5
  • 主要特性:
    16位递增、递减、中心对齐计数器(计数值:0~65535)
    16位预分频器(分频系数:1~65536)
    可用于触发DAC、ADC
    在更新事件、触发事件、输入捕获、输出比较时,会产生中断/DMA请求
    4个独立通道,可用于:输入捕获、输出比较、输出PWM、单脉冲模式
    使用外部信号控制定时器且可实现多个定时器互连的同步电路
    支持编码器和霍尔传感器电路等

3.2.通用定时器框图

在这里插入图片描述

3.3.计数器时钟源

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

外部时钟模式1
在这里插入图片描述
外部时钟模式2在这里插入图片描述
内部触发
使用一个定时器作为另一个定时器的预分频器(F1为例)
在这里插入图片描述

【小插曲——使用通用定时器进行定时器中断】

不同点:基本定时器只能递增计数,而通用定时器计数模式有三种
在这里插入图片描述

3.4.通用定时器PWM输出实验【输出比较】

3.4.1.通用定时器输出比较部分框图介绍

在这里插入图片描述

捕获/比较通道1的主电路—输出部分
在这里插入图片描述

捕获/比较通道的输出部分(通道1)
在这里插入图片描述

3.4.2.通用定时器输出PWM原理

假设:递增计数模式

  • ARR:自动重装载寄存器的值
  • CCRx:捕获/比较寄存器x的值
  • 当CNT < CCRx,IO输出0
  • 当CNT >= CCRx,IO输出1

总结:PWM波周期或频率由ARR决定,PWM波占空比由CCRx决定

在这里插入图片描述

3.4.3.PWM模式

在这里插入图片描述

3.4.4.通用定时器PWM输出实验配置步骤

  • 配置定时器基础工作参数:HAL_TIM_PWM_Init()
  • 定时器PWM输出MSP初始化:HAL_TIM_PWM_MspInit() 配置NVIC、CLOCK、GPIO等
  • 配置PWM模式/比较值等:HAL_TIM_PWM_ConfigChannel()
  • 使能输出并启动计数器:HAL_TIM_PWM_Start()
  • 修改比较值控制占空比(可选):__HAL_TIM_SET_COMPARE()
  • 使能通道预装载(可选):__HAL_TIM_ENABLE_OCxPRELOAD()

关键结构体

typedef struct 
{ 
   uint32_t OCMode; 	  	/* 输出比较模式选择 */
   uint32_t Pulse; 	        /* 设置比较值 */
   uint32_t OCPolarity;    	/* 设置输出比较极性 */
   uint32_t OCNPolarity;    /* 设置互补输出比较极性 */
   uint32_t OCFastMode;   	/* 使能或失能输出比较快速模式 */
   uint32_t OCIdleState;    /* 空闲状态下OC1输出 */
   uint32_t OCNIdleState;  	/* 空闲状态下OC1N输出 */ 
} TIM_OC_InitTypeDef;

在这里插入图片描述

3.4.5.编程实战:通用定时器PWM输出实验

  • 通过定时器输出的PWM控制LED0,实现类似手机呼吸灯的效果。
  • 2KHz为例,PSC=71,ARR=499。
  • 配置输出比较模式为:PWM模式1,通道输出极性为:低电平有效。

代码暂不贴出

3.5.通用定时器输入捕获实验【输入捕获】

3.5.1.通用定时器输入捕获部分框图介绍

在这里插入图片描述

捕获/比较通道的输入部分(通道1)
在这里插入图片描述
捕获/比较通道1的主电路—输入部分
在这里插入图片描述

3.5.2.通用定时器输入捕获脉宽测量原理

以捕获测量高电平脉宽为例,假设:递增计数模式

  • ARR:自动重装载寄存器的值
  • CCRx1:t1时间点CCRx的值
  • CCRx2:t2时间点CCRx的值

高电平期间,计时器计数的个数:N * (ARR+1) + CCRx2
在这里插入图片描述

3.5.3.通用定时器输入捕获实验配置步骤

  • 配置定时器基础工作参数:HAL_TIM_IC_Init()
  • 定时器输入捕获MSP初始化:HAL_TIM_IC_MspInit() 配置NVIC、CLOCK、GPIO等
  • 配置输入通道映射、捕获边沿等:HAL_TIM_IC_ConfigChannel()
  • 设置优先级,使能中断:HAL_NVIC_SetPriority()、 HAL_NVIC_EnableIRQ()
  • 使能定时器更新中断:__HAL_TIM_ENABLE_IT()
  • 使能捕获、捕获中断及计数器:HAL_TIM_IC_Start_IT()
  • 编写中断服务函数:TIMx_IRQHandler()等  HAL_TIM_IRQHandler()
  • 编写更新中断和捕获回调函数:HAL_TIM_PeriodElapsedCallback() HAL_TIM_IC_CaptureCallback()

关键结构体

typedef struct
{ 
    uint32_t ICPolarity;    /* 输入捕获触发方式选择,比如上升、下降沿捕获 */ 
    uint32_t ICSelection; 	/* 输入捕获选择,用于设置映射关系 */ 
    uint32_t ICPrescaler; 	/* 输入捕获分频系数 */ 
    uint32_t ICFilter;    	/* 输入捕获滤波器设置 */ 
} TIM_IC_InitTypeDef;

在这里插入图片描述

3.5.4.编程实战:通用定时器输入捕获实验

  • 通过定时器5通道1来捕获按键高电平脉宽时间,通过串口打印出来。
  • 1MHz计数频率为例,PSC=71,ARR=65535。
  • 配置输入捕获方式:上升沿捕获、输入通道1映射在TI1上、不分频、不滤波

代码暂不贴出

3.6.通用定时器脉冲计数实验【时钟源与从模式】

3.6.1.脉冲计数实验原理

在这里插入图片描述
外部时钟模式1
在这里插入图片描述

3.6.2.通用定时器脉冲计数实验配置步骤

  • 配置定时器基础工作参数:HAL_TIM_IC_Init()
  • 定时器输入捕获MSP初始化:HAL_TIM_IC_MspInit() 配置NVIC、CLOCK、GPIO等
  • 配置定时器从模式等:HAL_TIM_SlaveConfigSynchro()
  • 使能输入捕获并启动计数器:HAL_TIM_IC_Start()
  • 获取计数器的值:__HAL_TIM_GET_COUNTER()
  • 设置计数器的值:__HAL_TIM_SET_COUNTER()

关键结构体

typedef struct 
{ 
    uint32_t SlaveMode;             /* 从模式选择 */ 
    uint32_t InputTrigger;          /* 输入触发源选择 */ 
    uint32_t TriggerPolarity;      	/* 输入触发极性 */ 
    uint32_t TriggerPrescaler;   	/* 输入触发预分频 */ 
    uint32_t TriggerFilter;        	/* 输入滤波器设置 */ 
} TIM_SlaveConfigTypeDef;

在这里插入图片描述

3.6.3.编程实战:通用定时器脉冲计数实验

  • 将定时器2通道1输入的高电平脉冲作为定时器2的时钟,并通过串口打印脉冲数。
  • PSC=0,ARR=65535
  • 配置从模式:外部时钟模式1、触发选择、上升沿触发、不分频、不滤波

代码暂不贴出

4.高级定时器(以F1为例)

4.1.高级定时器简介

  • 高级定时器 :TIM1/TIM8
  • 主要特性:
    16位递增、递减、中心对齐计数器(计数值:0~65535)
    16位预分频器(分频系数:1~65536)
    可用于触发DAC、ADC
    在更新事件、触发事件、输入捕获、输出比较时,会产生中断/DMA请求
    4个独立通道,可用于:输入捕获、输出比较、输出PWM、单脉冲模式
    使用外部信号控制定时器且可实现多个定时器互连的同步电路
    支持编码器和霍尔传感器电路等
    重复计数器
    死区时间带可编程的互补输出
    断路输入,用于将定时器的输出信号置于用户可选的安全配置中

4.2.高级定时器框图

在这里插入图片描述

4.3.高级定时器输出指定个数PWM实验【重复计数】

4.3.1.重复计数器特性

在这里插入图片描述

4.3.2.高级定时器输出指定个数PWM实验原理

在这里插入图片描述

4.3.3.高级定时器输出指定个数PWM实验配置步骤

  • 配置定时器基础工作参数:HAL_TIM_PWM_Init()
  • 定时器PWM输出MSP初始化:HAL_TIM_PWM_MspInit() 配置NVIC、CLOCK、GPIO等
  • 配置PWM模式/比较值等:HAL_TIM_PWM_ConfigChannel()
  • 设置优先级,使能中断:HAL_NVIC_SetPriority()、 HAL_NVIC_EnableIRQ()
  • 使能定时器更新中断:__HAL_TIM_ENABLE_IT()
  • 使能输出、主输出、计数器:HAL_TIM_PWM_Start()
  • 编写中断服务函数:TIMx_IRQHandler()等 -> HAL_TIM_IRQHandler()
  • 编写更新中断回调函数:HAL_TIM_PeriodElapsedCallback()

关键结构体

typedef struct 
{ 
   uint32_t OCMode; 	  	/* 输出比较模式选择 */
   uint32_t Pulse; 	        /* 设置比较值 */
   uint32_t OCPolarity;    	/* 设置输出比较极性 */
   uint32_t OCNPolarity;    /* 设置互补输出比较极性 */
   uint32_t OCFastMode;   	/* 使能或失能输出比较快速模式 */
   uint32_t OCIdleState;    /* 空闲状态下OC1输出 */
   uint32_t OCNIdleState;  	/* 空闲状态下OC1N输出 */ 
} TIM_OC_InitTypeDef;

在这里插入图片描述

4.3.4编程实战:高级定时器输出指定个数PWM实验

  • 通过定时器8通道1实现指定个数PWM输出,用于控制LED1的亮灭
  • 2Hz为例,PSC=7199,ARR=4999
  • 配置输出比较模式为:PWM模式1
  • 通道输出极性为:高电平有效
  • 占空比:50%

代码暂不贴出

4.4.高级定时器输出比较模式实验【输出比较-翻转】

4.4.1.高级定时器输出比较模式实验原理

  • 输出比较模式:翻转
  • 当CNT = CCRx,OCxREF电平翻转

总结:PWM波周期或频率由ARR决定,占空比固定50%,相位由CCRx决定
在这里插入图片描述

4.4.2.高级定时器输出比较模式实验配置步骤

  • 配置定时器基础工作参数:HAL_TIM_OC_Init()
  • 定时器输出比较MSP初始化:HAL_TIM_OC_MspInit() 配置NVIC、CLOCK、GPIO等
  • 配置输出比较模式等:HAL_TIM_OC_ConfigChannel()
  • 使能通道预装载:__HAL_TIM_ENABLE_OCxPRELOAD()
  • 使能输出、主输出、计数器:HAL_TIM_OC_Start()
  • 修改捕获/比较寄存器的值:__HAL_TIM_SET_COMPARE()

关键结构体

typedef struct 
{ 
   uint32_t OCMode; 	  	/* 输出比较模式选择 */
   uint32_t Pulse; 	        /* 设置比较值 */
   uint32_t OCPolarity;    	/* 设置输出比较极性 */
   uint32_t OCNPolarity;    /* 设置互补输出比较极性 */
   uint32_t OCFastMode;   	/* 使能或失能输出比较快速模式 */
   uint32_t OCIdleState;    /* 空闲状态下OC1输出 */
   uint32_t OCNIdleState;  	/* 空闲状态下OC1N输出 */ 
} TIM_OC_InitTypeDef;

在这里插入图片描述

4.4.3.编程实战:高级定时器输出比较模式实验

  • 通过定时器8通道1/2/3/4输出相位分别为25%、50%、75%、100%的PWM
  • 1KHz为例,PSC=71,ARR=999
  • 配置输出比较模式为:翻转
  • 通道输出极性为:高电平有效

代码暂不贴出

4.5.高级定时器互补输出带死区控制实验【互补输出、死区、刹车】

4.5.1,互补输出,带死区控制

在这里插入图片描述

4.5.2,带死区控制的互补输出应用之H桥

由于元器件是有延迟特性,所以需要加上死区时间控制
在这里插入图片描述

4.5.3,捕获/比较通道的输出部分(通道1至3)

在这里插入图片描述

4.5.4,死区时间计算

在这里插入图片描述

4.5.5,刹车(断路)功能

  • 使能刹车功能:将TIMx_BDTR的BKE位置1,刹车输入信号极性由BKP位设置
  • 使能刹车功能后:由TIMx_BDTR的MOE、OSSI、OSSR位,TIMx_CR2的OISx、OISxN位,TIMx_CCER的CCxE、CCxNE位控制OCx和OCxN输出状态
    无论何时,OCx和OCxN输出都不能同时处在有效电平
    在这里插入图片描述
    发生刹车后的现象
  1. MOE位被清零,OCx和OCxN为无效、空闲或复位状态(OSSI位选择)
  2. OCx和OCxN的状态:由相关控制位状态决定,当使用互补输出时:根据情况自动控制输出电平,参考参考手册使用刹车(断路)功能小节
  3. BIF位置1,如果使能了BIE位,还会产生刹车中断;如果使能了TDE位,会产生DMA请求
  4. 如果AOE位置 1,在下一个 更新事件UEV时,MOE位被自动置 1

4.5.6,高级定时器互补输出带死区控制实验配置步骤

1,配置定时器基础工作参数HAL_TIM_PWM_Init()

2,定时器PWM输出MSP初始化HAL_TIM_PWM_MspInit() 配置NVIC、CLOCK、GPIO等

3,配置PWM模式/比较值等HAL_TIM_PWM_ConfigChannel()

4,配置刹车功能、死区时间等HAL_TIMEx_ConfigBreakDeadTime()

5,使能输出、主输出、计数器HAL_TIM_PWM_Start()

6,使能互补输出、主输出、计数器HAL_TIMEx_PWMN_Start()

关键结构体

typedef struct 
{ 
   uint32_t OCMode; 	  	/* 输出比较模式选择 */
   uint32_t Pulse; 	        /* 设置比较值 */
   uint32_t OCPolarity;    	/* 设置输出比较极性 */
   uint32_t OCNPolarity;    /* 设置互补输出比较极性 */
   uint32_t OCFastMode;   	/* 使能或失能输出比较快速模式 */
   uint32_t OCIdleState;    /* 空闲状态下OC1输出 */
   uint32_t OCNIdleState;  	/* 空闲状态下OC1N输出 */ 
} TIM_OC_InitTypeDef;
typedef struct 
{
    uint32_t OffStateRunMode;    /* 运行模式下的关闭状态选择 */ 
    uint32_t OffStateIDLEMode;   /* 空闲模式下的关闭状态选择 */ 
    uint32_t LockLevel; 		 /* 寄存器锁定设置 */ 
    uint32_t DeadTime; 	         /* 死区时间设置 */ 
    uint32_t BreakState; 	     /* 是否使能刹车功能 */ 
    uint32_t BreakPolarity;		 /* 刹车输入极性 */ 
    uint32_t BreakFilter; 		 /* 刹车输入滤波器(F1/F4系列没有) */ 
    uint32_t AutomaticOutput; 	 /* 自动恢复输出使能,即使能AOE位 */
} TIM_BreakDeadTimeConfigTypeDef;

在这里插入图片描述

4.5.7,编程实战:高级定时器互补输出带死区控制实验

  • 通过定时器1通道1输出频率为1KHz,占空比为70%的PWM,使用PWM模式1
  • 使能互补输出并设置死区时间控制:设置DTG为100(5.56us),进行验证死区时间是否正确
  • 使能刹车功能:刹车输入信号高电平有效,配置输出空闲状态等,最后用示波器验证
  • 1KHz为例,PSC=71,ARR=999
  • 以H桥为例,配置通道输出极性以及互补输出极性

4.6.高级定时器PWM输入模式实验【输入捕获+从模式】

4.6.1.PWM输入模式工作原理

在这里插入图片描述

4.6.2.PWM输入模式时序

在这里插入图片描述

4.6.3.高级定时器PWM输入模式实验配置步骤

  • 配置定时器基础工作参数:HAL_TIM_IC_Init()
  • 定时器捕获输入MSP初始化:HAL_TIM_IC_MspInit() 配置NVIC、CLOCK、GPIO等
  • 配置IC1/2映射、捕获边沿等:HAL_TIM_IC_ConfigChannel()
  • 配置从模式,触发源等:HAL_TIM_SlaveConfigSynchro()
  • 设置优先级,使能中断:HAL_NVIC_SetPriority()、 HAL_NVIC_EnableIRQ()
  • 使能捕获、捕获中断及计数器:HAL_TIM_IC_Start_IT()、 HAL_TIM_IC_Start()
  • 编写中断服务函数:TIMx_IRQHandler()等  HAL_TIM_IRQHandler()
  • 编写输入捕获回调函数:HAL_TIM_IC_CaptureCallback()
typedef struct
{ 
    uint32_t ICPolarity;    	/* 输入捕获触发方式选择,比如上升、下降沿捕获 */ 
    uint32_t ICSelection; 		/* 输入捕获选择,用于设置映射关系 */ 
    uint32_t ICPrescaler; 		/* 输入捕获分频系数 */ 
    uint32_t ICFilter;         	/* 输入捕获滤波器设置 */ 
} TIM_IC_InitTypeDef;
typedef struct 
{ 
    uint32_t SlaveMode;       	/* 从模式选择 */ 
    uint32_t InputTrigger;     	/* 输入触发源选择 */ 
    uint32_t TriggerPolarity;  	/* 输入触发极性 */ 
    uint32_t TriggerPrescaler; 	/* 输入触发预分频 */ 
    uint32_t TriggerFilter;   	/* 输入滤波器设置 */ 
} TIM_SlaveConfigTypeDef;

在这里插入图片描述

4.6.4.编程实战:高级定时器PWM输入模式实验

  • 通过定时器3通道2(PB5)输出PWM
  • 将PWM输入到定时器8通道1(PC6),测量PWM的频率/周期、占空比等信息
  • 72MHz采样频率( 精度约13.8ns ),PSC=0,ARR=65535
  • 不考虑溢出情况下,测量的最长PWM周期为910.2us

代码暂不贴出

5.实验汇总

序号定时器类型实现功能要点
1基础定时器定时器中断基础配置
2通用定时器PWM输出输出比较
3通用定时器输入脉冲测宽输入捕获
4通用定时器脉冲计数从模式(时钟源)
5高级定时器输出n个PWM输出比较+重复计数
6高级定时器【通用】多相位PWM输出比较(翻转模式)
7高级定时器互补输出PWM输出比较+死区控制(互补输出、刹车)
8高级定时器【通用】PWM测量输入捕获+从模式

重要结构体汇总

  • 定时器基本参数:TIM_Base_InitTypeDef
  • 输出比较设置:TIM_OC_InitTypeDef
  • 输入捕获设置:TIM_IC_InitTypeDef
  • 从模式设置:TIM_SlaveConfigTypeDef
  • 刹车与死区控制:TIM_BreakDeadTimeConfigTypeDef
  • 1
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值