如何使用STM32的通用定时器

目录

  • 一、确定功能实现(示例)
    • 1、输入捕获:测量脉宽
    • 2、输出比较:输出PWM(1MHz周期,脉宽2KHz)
    • 3、普通计时器:定时500ms = (5000*7200) / 72MHz
  • 二、确定计数方式
  • 三、确定时钟源
  • 四、确定主、从模式
  • 五、对应模式的设置
  • 六、事件
  • 通用定时器框图
  • 七、代码结构 (部分)
  • 八、STM32CubeMX配置

一、确定功能实现(示例)

1、输入捕获:测量脉宽

时钟来源:外部输入引脚TI
计数方式:72MHz--1us精度,重装载值--65535,向上计数
主模式默认,从模式不开启。
捕获方式:上升沿捕获

2、输出比较:输出PWM(1MHz周期,脉宽2KHz)

计算周期 T o u t = ( A R R + 1 ) ∗ ( P S C + 1 ) F t T_{out}=\frac{(ARR+1)*(PSC+1)}{F_{t}} Tout=Ft(ARR+1)(PSC+1)

时钟来源:内部时钟来源
计数方式:ARR决定PWM周期,CCR决定PWM占空比,递增计数
		ARR = 72 - 1,CCR = 500 -1;
主模式默认,从模式失能。
输出模式:PWM模式1,输出通道输出极性为:低电平有效

3、普通计时器:定时500ms = (5000*7200) / 72MHz

时钟来源:内部时钟来源
计数方式:72MHz--1us精度,重装载值--5000,向上计数
主模式默认,从模式失能。

二、确定计数方式

计数的精度(分频)、计数上限(重载值)、向上&向下

三、确定时钟源

	内部时钟AHB:普通计数计时器
	外部输入TI(TIMx_CH):输入捕获、编码器模式、PWM 输入
	外部触发ETR(IO):触发定时器启动、停止、复位或作为时钟源
	内部触发ITR:一个定时器作另一个定时器的预分频器(不常用)

四、确定主、从模式

(默认启用主模式的复位模式,关闭从模式)

​ ​ ​ ​常用的模式场景示例

定时器同步操作	主:更新/使能					从:触发
时间间隔测量		主:复位                  	从:复位
事件驱动计数		主:比较脉冲/OC1REF			从:触发模式
正交编码器处理	主:使能                     从:编码器模式

1、主模式选择–(默认复位模式)

复位:当定时器产生更新事件时,输出一个复位信号。通常用于从定时器的复位。(默认使用该模式)
使能:当定时器启用时,输出一个使能信号。 
更新:当定时器产生更新事件时,输出一个触发信号。
比较脉冲:当定时器的比较寄存器与计数器值匹配时,输出一个脉冲信号
比较 OC1REF、OC2REF 、OC3REF 、OC4REF模式。

2、从模式选择–(默认关闭)

复位模式:测量两个信号之间的时间间隔
门控模式:在特定时段内允许定时器计数。
触发模式:定时器在收到外部事件后开始工作,例如同步事件触发 
外部时钟模式:使用外部信号源(如方波、脉冲)来控制定时器的计数 
编码器模式:用于读取正交编码器的位置信息(仅TI1、TI2)

五、对应模式的设置

输入捕获:

通道映射选择:TI1、TI2、TI3、TI4
捕获极性:上升沿、下降沿、双边沿
滤波器:可以为输入信号配置滤波器,以滤除高频噪声。
输入预分频器:可以为输入信号设置预分频器,减慢输入信号的处理速率。例如,预分频为 2 时,每两个输入脉冲处理一次。

输出比较:

输出模式:OCxM配置,如下表
输出极性:高电平有效、低电平有效
比较值:CCR的值(可使用函数修改:__HAL_TIM_SET_COMPARE())
输出状态:使能
输出通道:TIMx_CH1、TIMx_CH2、TIMx_CH3、TIMx_CH4
OCxM 配置值 模式名称 描述
000 冻结(Frozen) 当计数器与比较值匹配时,输出保持不变。
001 活动电平(Set Active) 当匹配时,将输出引脚设置为高电平。
010 非活动电平(Set Inactive) 当匹配时,将输出引脚设置为低电平。
011 切换(Toggle) 当匹配时,输出引脚电平反转(高电平变为低电平,低电平变为高电平)。
100 强制为低(Force Inactive) 强制将输出引脚设置为低电平(忽略比较事件)。
101 强制为高(Force Active) 强制将输出引脚设置为高电平(忽略比较事件)。
110 PWM 模式 1 计数器小于比较值时输出为高电平,计数器大于比较值时输出为低电平。
111 PWM 模式 2 计数器小于比较值时输出为低电平,计数器大于比较值时输出为高电平。

六、事件

  1. 更新事件
    当定时器的计数器(CNT)溢出或者重新加载时,产生更新事件。这通常发生在计数器达到自动重装载寄存器(ARR)的值时。
  2. 捕获比较事件
    当定时器的计数器值与某个捕获/比较寄存器(CCR1、CCR2 等)中的值匹配时,产生捕获或比较事件。
  3. 触发事件
    触发事件是用于同步定时器或外部硬件的事件。当定时器配置为主定时器或从定时器时,主定时器可以通过触发事件启动从定时器。
  4. 中断事件
    定时器产生的各种事件(如更新事件、捕获/比较事件等)可以通过中断机制通知 CPU。
  5. 溢出事件
    溢出事件类似于更新事件,但它只发生在计数器向上计数超过最大值时(上溢出),或向下计数低于最小值时(下溢出)。

通用定时器框图

如何使用STM32的通用定时器_第1张图片

七、代码结构 (部分)

//一、通用定时器的基本设置
TIM_HandleTypeDef htim1;
__HAL_RCC_TIM1_CLK_ENABLE();	//使能TIM1时钟
	htim1.Instance 				 = TIM1;								// 定时器x
	htim1.Init.Prescaler 		 = 72-1;								// 定时器预分频
	htim1.Init.CounterMode		 = TIM_COUNTERMODE_UP;					// 递增计数模式:向上
	htim1.Init.Period 			 = 1000-1;								// 自动重装载值
	htim1.Init.ClockDivision 	 = TIM_CLOCKDIVISION_DIV1;				// 内部时钟分频(CK_INT)
	htim1.Init.RepetitionCounter = 0;									// 重复计数器
	htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;		// 自动重装:失能
HAL_TIM_PWM_Init(&htim1);//注意使用对应的模式函数
//如要只需要使用基本定时器:HAL_TIM_Base_Init(&htim1)
//用到输入比较:HAL_TIM_IC_Init(&htim1);
//用到输出比较:HAL_TIM_OC_Init(&htim1);
  
//二、主模式或者从模式的配置
	//1.主模式选择
TIM_MasterConfigTypeDef sMasterConfig = {0};
	sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;				//复位模式 
	sMasterConfig.MasterSlaveMode     = TIM_MASTERSLAVEMODE_DISABLE;//从模式失能
HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);		//使能配置

	//2.从模式选择
TIM_SlaveConfigTypeDef SlaveConfig = {0};
	SlaveConfig.SlaveMode			= TIM_SLAVEMODE_RESET;			//从模式:复位模式
	SlaveConfig.InputTrigger 		= TIM_TS_TI1FP1;				//定时器输入触发源:TI1FP1
	SlaveConfig.TriggerPolarity	    = TIM_TRIGGERPOLARITY_RISING;	//上升沿检测
	SlaveConfig.TriggerFilter		= 0;							//不滤波
HAL_TIM_SlaveConfigSynchro(&htim1,&SlaveConfig);					//使能配置

//三、输入或者输出模式的配置
	//1.输出OC配置
TIM_OC_InitTypeDef sConfigOC = {0};
	sConfigOC.OCMode 	   = TIM_OCMODE_PWM1;			//输出模式:PWM1
	sConfigOC.Pulse 	   = 50;						//设置比较值:
	sConfigOC.OCPolarity   = TIM_OCPOLARITY_HIGH;		//设置输出比较极性
	//(一般常用配置上述参数)
	sConfigOC.OCNPolarity  = TIM_OCNPOLARITY_HIGH;		//设置互补输出比较极性
	sConfigOC.OCFastMode   = TIM_OCFAST_DISABLE;		//使能或使能输出比较快速模式
	sConfigOC.OCIdleState  = TIM_OCIDLESTATE_RESET;		//空闲状态下OC1输出
	sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;	//空闲状态下OC1N输出
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);	//配置输出到TIM1通道1
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);						//开始输出

	//2.输入IC配置
TIM_IC_InitTypeDef sConfigIC = {0};
	sConfigIC.ICPolarity  = TIM_ICPOLARITY_RISING;       //上升沿捕获 
	sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;    //映射到TI1上
	sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;              //配置输入分频,不分频
	sConfigIC.ICFilter    = 0;                           //配置输入滤波器,不滤波
HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1);	//配置输入到TIM1通道1
HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_1);						//开始捕获

//四、GPIO口配置 
	//PE9 -> TIM1_CH1
GPIO_InitTypeDef GPIO_InitStruct = {0};
	__HAL_RCC_GPIOE_CLK_ENABLE();
	__HAL_AFIO_REMAP_TIM1_ENABLE();
	GPIO_InitStruct.Pin	  = GPIO_PIN_9;
    GPIO_InitStruct.Mode  = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

//五、定时器的事件标志
#define TIM_FLAG_UPDATE                    TIM_SR_UIF                           /*!< Update interrupt flag         */
#define TIM_FLAG_CC1                       TIM_SR_CC1IF                         /*!< Capture/Compare 1 interrupt flag */
#define TIM_FLAG_CC2                       TIM_SR_CC2IF                         /*!< Capture/Compare 2 interrupt flag */
#define TIM_FLAG_CC3                       TIM_SR_CC3IF                         /*!< Capture/Compare 3 interrupt flag */
#define TIM_FLAG_CC4                       TIM_SR_CC4IF                         /*!< Capture/Compare 4 interrupt flag */
#define TIM_FLAG_COM                       TIM_SR_COMIF                         /*!< Commutation interrupt flag    */
#define TIM_FLAG_TRIGGER                   TIM_SR_TIF                           /*!< Trigger interrupt flag        */
#define TIM_FLAG_BREAK                     TIM_SR_BIF                           /*!< Break interrupt flag          */
#define TIM_FLAG_CC1OF                     TIM_SR_CC1OF                         /*!< Capture 1 overcapture flag    */
#define TIM_FLAG_CC2OF                     TIM_SR_CC2OF                         /*!< Capture 2 overcapture flag    */
#define TIM_FLAG_CC3OF                     TIM_SR_CC3OF                         /*!< Capture 3 overcapture flag    */
#define TIM_FLAG_CC4OF                     TIM_SR_CC4OF                         /*!< Capture 4 overcapture flag    */

补充:定时器基本配置解析

ClockDivision: 首先定时器时钟来源是来自APB的72MHz,通过CK_INT分频得到定时器的时钟频率,通常为DIV_1,即不分频为72MHz;
Prescaler 	 : 设置预分频系数PSC,例如72,则说明72MHz/1 = 1MHz = 1us, CNT计数+1;
Period 		 : 设置自动重装载值ARR,例如1000,则1000 x 1us = 1ms,说明计数到10001ms)为一个周期。

八、STM32CubeMX配置

stm32CubeMX输出PWM示例配置 ------ 蓝桥_吹雪

你可能感兴趣的:(stm32,嵌入式硬件,单片机)