欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > STM32之定时器(TIMER)与脉冲宽度调制(PWM)

STM32之定时器(TIMER)与脉冲宽度调制(PWM)

2025/5/21 17:43:18 来源:https://blog.csdn.net/2401_85565442/article/details/148083169  浏览:    关键词:STM32之定时器(TIMER)与脉冲宽度调制(PWM)

一、STM32定时器的原理与应用

  • 基本概念

定时器的作用一般是为了使用定时功能和中断功能(洗衣机、微波炉、电风扇、智能空调......),当然在STM32中也可以利用定时器产生周期性的脉冲信号来控制不同的外设(电机的转速、舵机的角度、灯光的亮度........),所以掌握STM32中的定时器对于项目开发是很有必要的。

  • 外设种类

对于STM32F407微处理器而言,内部一共集成了14个定时器,其中有2个基本定时器(TIM6和TIM7)、10个通用定时器(TIM2~TIM5、TIM9~TIM14)、2个高级定时器(TIM1和TIM8)。

其中通用定时器TIM2和TIM5为32位定时器,其他为16位定时器,当然,定时器位数越大,定时时间越久。

  • 基本特点

  • 时钟分析

  • 内部框图

  • 程序设计

练习:要求使用4个定时器,实现对开发板的4个LED进行控制,要求D0每隔100ms电平翻转1次,D1每隔800ms电平翻转1次,D2每隔20s电平翻转1次,D3每隔100s电平翻转1次。

  • 功能拓展

相比于基本定时器而言,通用定时器增加了输入捕获功能以及输出比较功能,并且通用定时器具有独立通道,就可以把GPIO引脚连接到某个通道,利用通道进行输入信号的检测以及脉冲信号的输出。

STM32F407ZET6一共提供10个通用定时器(TIM2~TIM5、TIM9~TIM14),TIM2和TIM5是32bit定时器,其他的定时器都是16bit定时器。TIM2~TIM5的计数方式有三种可以选择,分别为递增计数、递减计数、递增/递减计数。

递增计数:计数器从 0 计数到自动重载值(TIMx_ARR 寄存器的内容),然后重新从 0 开始计数并生成计数器上溢事件。

递减计数:计数器从自动重载值(TIMx_ARR 寄存器的内容)开始递减计数到 0,然后重新从自动重载值开始计数并生成计数器下溢事件。

中心对齐:计数器从 0 开始计数到自动重载值(TIMx_ARR 寄存器的内容)- 1,生成计数器上溢事件;然后从自动重载值开始向下计数到 1 并生成计数器下溢事件。之后从 0 开始重新计数。

对于通用定时器TIM2~TIM5,都挂载在APB1外设总线下,定时器的频率为84MHZ,对于TIM12~TIM14都挂载在APB1外设总线下,定时器的频率为84MHZ,TIM9~TIM11是挂载在APB2总线下,所以定时器的频率为168MHZ,如下图

定时功能:基本上使用流程和基本定时器一致,只不过通用定时器的计数方式更灵活而已。

输入捕获:可以把定时器的某个通道连接到GPIO引脚上,然后从外部输入脉冲信号,经过 通道的滤波以及边沿检测之后,可以记录某个电平信号的脉冲宽度以及周期。

输出比较:可以把定时器的某个通道连接到GPIO引脚上,主动从引脚输出一个固定的脉冲, 原理很简单,其实就是计数器(TIM_CNT)如果超过比较寄存器中的值,就可以 输出一个电平信号(高电平或者低电平)。

对于TIM9~TIM14而言,也可以进行定时功能,同样也具有输入捕获以及输出比较功能,但是只能采用向上计数的方式,并且相比于TIM2~TIM5,只有2个独立通道。

  • 脉宽调制

PWM(Pulse Width Modulation)称为脉冲宽度调制,脉冲宽度调制是能利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中,比如PWM技术可以用在工业控制领域(控制电机的转速、控制舵机的角度........)。

PWM技术的关键参数有两个,一个是频率,一个是占空比频率指的是利用STM32的定时器通道输出脉冲的次数。占空比是指在一个脉冲周期中通电时间相对于总时间所占的比例,也可以简单理解为一个周期内高电平持续时间相对于总时间所占的比例(%)。

要实现精确的占空比控制,该电路必须有恒定的工作频率做保证。其实频率固定,也就是工作电路周期固定。因为占空比控制的电路接通率是建立在恒定工作周期上的,如果电子控制模块控制电路的周期不能保证恒定,那么所谓的占空比控制是毫无意义的。

思考:比如想要利用MCU的某个IO口去控制硬件,,需要使用定时器的某个通道,因为通道才有比较功能,请问应该用哪个定时器的哪个通道? 回答:查阅数据手册 !!!

PWM技术的原理其实很简单,就是利用STM32定时器中的某个通道的输出比较功能来输出周期性的脉冲信号,然后调节脉冲的宽度(调节占空比)达到控制外设的目的。

  • 调制原理

  • 舵机控制

  • 硬件接线

  • 程序设计

/** ****************************************************************************** * @file main.c 
* @author cecelmx@126.com 
* @version * @date 2025/03/27 
* @brief 利用MCU的通用定时器TIM3的输出比较功能实现PWM调节舵机的角度 ****************************************************************************** 
* @note 
* 1. 舵机的型号是SG90,该舵机的角度是0~180度,对应的脉冲信号是20ms 
* 2. 舵机的角度控制需要0.5ms~2.5ms的高电平,比例关系: 0度 -- 0.5ms * 3. IO口需要复用为定时器的通道,所以IO口必须设置为复用模式 * ****************************************************************************** */ 
/* Includes ------------------------------------------------------------------
*/ 
#include "stm32f4xx.h" //必须包含 
void SG90_Config(void) 
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
GPIO_InitTypeDef GPIO_InitStructure; 
TIM_OCInitTypeDef TIM_OCInitStructure; 
//1.打开TIM3的时钟 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 
//2.打开GPIO端口时钟 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);//3.配置IO口为复用模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用模式 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOC, &GPIO_InitStructure); 
//4.把IO口复用为定时器 
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3); 
//5.配置TIM3的时基 + 初始化TIM3 
TIM_TimeBaseStructure.TIM_Prescaler = 8400-1; 
TIM_TimeBaseStructure.TIM_Period = 200-1; 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 
//6.配置定时器的通道的参数 
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 5; 
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 
TIM_OC1Init(TIM3, &TIM_OCInitStructure); 
//7.使能预装载寄存器 
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//8.使能自动重载预装载寄存器 
TIM_ARRPreloadConfig(TIM3, ENABLE);//9.使能TIM3 
TIM_Cmd(TIM3, ENABLE); } 
/** 
* @brief 微秒延时函数 
* @param nTime: 待延时的微秒时间
* @retval None 
* @note 函数参数不能超过798915us 
*/ 
void delay_us(__IO uint32_t nTime) 
{ 
SysTick->CTRL = 0; // 关闭定时器 
SysTick->LOAD = 21 * nTime - 1; // 设置重载值SysTick->VAL = 0; // 清空计数器 
SysTick->CTRL = 1; //打开定时器,并且使用21MHZ时钟源 
while ((SysTick->CTRL & 0x00010000)==0);// 等待延时时间到达SysTick->CTRL = 0; // 关闭定时器}/** 
* @brief 毫秒延时函数 
* @param nTime: 待延时的微秒时间 
* @retval None 
* @note 函数参数不能超过798ms 
*/ 
void delay_ms(__IO uint32_t nTime)
{ 
SysTick->CTRL = 0; // 关闭定时器 
SysTick->LOAD = 21 * nTime * 1000 - 1; // 设置重载值 
SysTick->VAL = 0; // 清空计数器 
SysTick->CTRL = 1; //打开定时器,并且使用21MHZ时钟源 
while ((SysTick->CTRL & 0x00010000)==0);// 等待延时时间到达 
SysTick->CTRL = 0; // 关闭定时器 
} 
int main(void){ 
//1.硬件初始化 
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //中断优先级分组 
SG90_Config();BEEP_Init();while(1) 
{ 
TIM_SetCompare1(TIM3,5); // 0.5ms -- 0度 delay_ms(200); //延时200ms TIM_SetCompare1(TIM3,10); // 1.0ms -- 45度 delay_ms(200); //延时200ms TIM_SetCompare1(TIM3,15); // 1.5ms -- 90度 delay_ms(200); //延时200ms TIM_SetCompare1(TIM3,20); // 2.0ms -- 135度 delay_ms(200); //延时200ms TIM_SetCompare1(TIM3,25); // 2.5ms -- 180度 delay_ms(200); //延时200ms } } /************************ (C) COPYRIGHT Your Name *****END OF FILE*************/

实战练习:实现一个智能开关,要求通过开发板的2个机械按键,KEY0用于断开,KEY1用于闭合,结合舵机实现智能开关的功能。

  • 灯光亮度

实战作业:要求实现氛围灯的调光功能,要求灯光亮度有4个档位,要求只使用1个按键,通过短按实现亮度调节,拓展:长按实现灯的开关。

思考:如果想要利用PWM技术控制开发板的LED1(PF10)LED灯的亮度,请问怎么实现???

回答:对于传感器(比如舵机、电机.....)或者外部设备(LED、BEEP.....)而言,其实并不关心脉冲信号的来源,只根据脉冲信号来进行驱动,所以脉冲信号可以选择使用定时器的通道来生成,但是这种方案可移植性较差,原因就是有的IO口并没有定时器通道的功能。

所以也可以选择利用定时器(定时功能)来模拟周期性的脉冲信号,也就是说可以利用IO口的输出功能来输出高低电平 + 精准延时,实现PWM占空比的调节。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词