当前位置: 首页 > news >正文

【嵌入式学习笔记】嵌入式入门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
http://www.lryc.cn/news/110736.html

相关文章:

  • GD32F103输入捕获
  • [RT-Thread]基于ARTPI的文件系统认识与搭建
  • 动态规划+二分查找
  • 8.2小非农ADP数据来袭黄金将会如何表现?
  • linux启动oracle
  • AssetBundleBrowser导入报错解决方案
  • vue-baidu-map-3x 使用记录
  • 《GPU并行计算与CUDA编程》笔记
  • Shell编程基础(十二)函数
  • 【雕爷学编程】MicroPython动手做(33)——物联网之天气预报3
  • Screens 4 for mac VNC客户端 强大的远程控制工具
  • 搜索与图论(三)
  • 阿里云“通义千问”开源,可免费商用
  • 23.7.31 牛客暑期多校5部分题解
  • Python爬虫的学习day02 requests 模块post 函数, lmxl 模块的 etree 模块
  • 客户流失分析预测案例 -- 机器学习项目基础篇(7)
  • uniapp中我使用uni.navigateTo跳转webview页面传参,但是接收的参数只有一半。
  • 使用kaminari,在列表页实现分页功能
  • Android 性能调优之bitmap的优化
  • HOT74-数组中的第K个最大元素
  • 类与对象【中】
  • uni-app:实现列表单选功能
  • vue中axios二次封装并发起网络请求配置
  • 开源全文搜索引擎汇总
  • gitlab CI/CD 安装 gitlab runner
  • 服务器中了malox勒索病毒后怎么办怎么解决,malox勒索病毒解密数据恢复
  • Python小白学习:超级详细的字典介绍(字典的定义、存储、修改、遍历元素和嵌套)
  • word转pdf两种方式(免费+收费)
  • 基于图像形态学处理的目标几何形状检测算法matlab仿真
  • python系列教程211——map