STM32快速入门(定时器之输出PWM波形)

STM32快速入门(定时器之输出PWM波形)

前言

本节主要讲解STM32利用通用定时器,利用CCR和CNT寄存器,输出指定占空比和频率的PWM波形。其功能的应用有:实现LED呼吸灯的效果、控制步进电机、控制直流电机转速等。

导航

图98 通用定时器框图:

TimerPWM

图片引自STM32 F1XX系列的中文参考手册。在通用定时器章节的定时器架构图中,本章讲解的定时器输出功能位于右下角的红色矩形中。

定时器实现PWM输出的实现细节

参考中文手册,实现细节图125如下:

PWM

它内部实现是:输出模式控制器通过比较TIMx_CCR1(比较捕获寄存器)和TIMx_CNT(计数器)的值,由输出模式控制器来确定输出高(有效)电平,还是低(无效)电平,用户可以通过改变TIMx_CCR1寄存器的值来改变PWM的占空比。这通常会将输出模式控制器配置成PWM模式1或PWM模式2,两种模式就是互为取反的关系,同时这两种模式也是输出模式控制器最常用的配置。

对于原理图125左侧的输出模式控制器:

该部分作用是:控制输出模式控制器的输出行为。这里将输出模式控制器的输出标记为OC1REF。

输出模式控制器有7种配置,这些配置是通过操作 TIMx_CCMR1.OC1M[6:4] 实现,7种配置在中文手册中的描述如下,手册中的描述可能太晦涩,配合江科的表格会更友好:

TIMx_CCMR1__OC1M2

TIMx_CCMR1__OC1M1

对于原理图125右侧:

右侧包括一个极性选择器和输出使能电路。

该部分作用是:1、对输出电压的极性进行控制。2、控制输出电路的使能。

我们可以通过配置 TIMx_CCER.CC1P[1] 控制选择器是直接选择OC1REF波形(输出模式控制器的输出)还是选择OC1REF的反相波形。也就是说,输出模式控制器配置成PWM1/WPM2可以实现对OC1REF的反相,配置 TIMx_CCER.CC1P[1] 间接配置选择器也能实现对OC1REF的反相。通过配置 TIMx_CCER.CC1E[0] 可以实现对输出电路的使能。

由定时器输出PWM的原理可以得出调节占空比的公式,PWM频率就是定时器溢出的周期、占空比就是TIMx_CCR1的值,其计算公式如下:

PWMFrequency

关于定时器的PWM模块还需提一句的是,有三个寄存器存在缓冲寄存器/影子寄存器的概念的,这三个寄存器分别是:ARR、PSC、CCRx。影子寄存器的存在延续旧值的生命周期,这样让旧值继续该时期的使命。如果用户提供的新值立马生效,系统就会出于一种未定义的状态。有了缓冲寄存器/影子寄存器的概念,在一个更新周期中真正起作用的是影子寄存器,而用户想要修改预分频控制寄存器,会先将值写到缓冲器中,待这个更新周期过去,才会将缓冲器的值给到影子寄存器

下面中文手册的的两张时序图可以很好的说明了:

Shadow

缓冲寄存器 ----> 预分频控制寄存器

影子寄存器 ----> 预分频缓冲器

还需注意的是:TIMx_CR1.ARPE[7]TIMx_CCMR1.OC1PE[3]寄存器可以让用户选择ARR、CCRx是否启用影子寄存器的功能,而PSC寄存器默认必须使用影子寄存器的功能,但是用户可以通过TIM_PrescalerConfig函数动态配置计数器的预分频系数,它的第三个参数可以选择TIM_PSCReloadMode_Immediate,这会让定时器立即产生一个更新事件,间接实现了立即更新的效果。

定时器实现PWM输出的步骤

综上,可以总结出配置定时器输出部分的套路:

  1. 我们需要把 TIMx_CCMR1.CC1S[1:0] 配置为00,这样CC1通道就被配置为输出

  2. 通过配置 TIMx_CCMR1.OC1M[6:4] ,这里将输出模式控制寄存器配置成PWM1模式。即110。

  3. 配置原理图右部分是否开启反相 TIMx_CCER.CC1P[1] ,这里配置为0不反相。

  4. 最后使能 TIMx_CCER.CC1E[0] 位,来使能原理图右边的输出使能电路。

一般的话,我门还会配置 TIMx_CCMR1.OC1PE[3]TIMx_CR1.ARPE[7],分别启用TIMx_CCR1、TIMx_ARR寄存器的影子功能。

定时器实现PWM输出的库函数实现

因为我的开发板LED0被焊在了PB5所以,所以需要将定时器的PWM波形输出到PB5上。经过查表需要对TIM3_CH2输出进行一个重映射;此外还要将PB5配置成复用推挽输出的状态。

GPIOCfg

IORemap

定时器PWM输出配置,实例代码如下:

void LunarInitTIM3() {
	TIM_TimeBaseInitTypeDef TIM3_Cfg;
	GPIO_InitTypeDef GPIOB5_Cfg;
	TIM_OCInitTypeDef TIM3_OCCfg;

    // 定时器时基配置   BEGIN

	// 打开TIM3所需要的时钟 APB1
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	TIM_TimeBaseStructInit(&TIM3_Cfg);
	// 配置使用内部时钟 72M Hz
	TIM_InternalClockConfig(TIM3);

    // 这里配置定时器更新频率是1000HZ
	TIM3_Cfg.TIM_CounterMode = TIM_CounterMode_Up;
	TIM3_Cfg.TIM_Period = 100 - 1;
	TIM3_Cfg.TIM_Prescaler = 720 - 1;

	TIM_TimeBaseInit(TIM3, &TIM3_Cfg);
	// 因为TIM_TimeBaseInit会置TIMx_EGR.UG[0]为1,手动产生一个更新事件,
	// 同时会同步影子寄存器的值,而该更新事件又会产生一个多余的中断,所以,
	// 我们需要在开启中断之前,手动清楚更新事件标志位
	TIM_ClearFlag(TIM3, TIM_FLAG_Update);

    // 定时器时基配置   END


	// 配置GPIO 	BEGIN

	// 开启复用时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	// 部分重映射
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
	// 初始化GPIOB5为推挽复用输出
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

 	GPIOB5_Cfg.GPIO_Mode = GPIO_Mode_AF_PP;
 	GPIOB5_Cfg.GPIO_Pin = GPIO_Pin_5;
 	GPIOB5_Cfg.GPIO_Speed = GPIO_Speed_2MHz;

 	GPIO_Init(GPIOB, &GPIOB5_Cfg);

	// 配置GPIO 	END


	// 配置TIM3的PWM输出	BEGIN

	TIM_OCStructInit(&TIM3_OCCfg);

	TIM3_OCCfg.TIM_OCMode = TIM_OCMode_PWM1;
	TIM3_OCCfg.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM3_OCCfg.TIM_OutputState = TIM_OutputState_Enable;
	TIM3_OCCfg.TIM_Pulse = 0;

	TIM_OC2Init(TIM3, &TIM3_OCCfg);

	// 配置TIM3的PWM输出	END

	// 使能arr和ccr寄存器的影子功能
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
	TIM_ARRPreloadConfig(TIM3, ENABLE);

	// 使能更新中断
	// TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	// 开启定时器
	TIM_Cmd(TIM3, ENABLE);
}

int main() {

	// 初始化定时器
	LunarInitTIM3();
    // 初始化系统定时器
	SYSTick_Init();

	int dir = 0, cr = 0;

	while(1) {
		TIM_SetCompare2(TIM3, cr);
		Delay_Ms(20);

		if (dir == 0) {
			cr++;
			if (cr > 99) {
				dir = 1;
				cr = 99;
			}
		} else {
			cr--;
			if (cr < 0) {
				dir = 0;
				cr = 0;
			}
		}
	}

	return 0;
}

实验结果就是PB5处的LED灯实现了呼吸的效果。


本章完结

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: STM32F4系列微控制器中的高级定时器,可以用来产生PWM(脉宽调制)信号。PWM信号常用于电机驱动、LED灯控制、音频信号生成等应用。 首先,我们需要选择一个高级定时器来作为PWM输出源。STM32F4系列微控制器有多个高级定时器可供选择,如定时器1(TIM1)、定时器2(TIM2)、定时器3(TIM3)等。我们可以根据具体需求选择一个合适的定时器。 然后,在初始化定时器之前,需要先对GPIO端口进行配置。设置GPIO引脚的模式为复用模式,并选择合适的引脚复用功能,以使其连接到定时器输出通道。 接下来,我们需要初始化选定的高级定时器。通过配置定时器的时钟源、分频系数和计数模式等参数,来设置定时器的工作频率和计数范围。同时,还需要配置定时器的模式为PWM输出模式,并选择合适的通道模式和极性。 在初始化完成后,我们可以通过修改定时器的自动重载寄存器(ARR)和占空比调整寄存器(CCR)来控制PWM信号的周期和占空比。自动重载寄存器用于设置PWM信号的周期,占空比调整寄存器则用于设置PWM信号的占空比。 最后,启动定时器即可开始输出PWM信号。通过设置定时器的使能位,我们可以启动定时器开始计数,并将生成的PWM信号输出到相应的GPIO引脚。 需要注意的是,通过高级定时器输出PWM信号时,需要仔细计算和设置定时器的参数,确保生成的PWM信号满足具体应用要求。 以上就是使用STM32F4高级定时器输出PWM的基本步骤。当然,具体的实现还需要根据具体芯片型号和使用的开发环境来进行细致调整和配置。 ### 回答2: STM32F4高级定时器是一种功能强大的定时器模块,可用于输出PWM信号。以下是使用STM32F4高级定时器输出PWM的步骤: 第一步,配置定时器: 首先,选择要使用的定时器,如TIM1、TIM2等。然后,根据需要配置周期、分频系数和计数模式等参数。可通过寄存器设置或使用STM32CubeMX进行配置。 第二步,配置PWM模式: 选择PWM输出模式,例如选择PWM模式1或2。配置输出通道的极性、周期和占空比等参数。此外,还可以设置多通道的自动更新和互补输出功能。 第三步,配置GPIO引脚: 选定用于输出PWM信号的GPIO引脚,并配置为复用功能。确保GPIO引脚与定时器通道相匹配。 第四步,编程实现PWM输出: 使用适当的编程语言,例如C或汇编语言,编写程序以初始化和启动定时器。在程序中,设置PWM的周期和占空比,然后启动定时器。 第五步,输出PWM信号: 定时器开始计数后,会自动输出PWM信号。根据配置的周期和占空比参数,定时器会生成相应的PWM波形信号。 除了上述步骤外,还可以根据需要使用中断来处理定时器事件。通过配置中断服务例程,可以在定时器溢出、计数匹配等事件发生时执行特定的操作,以实现更精确的控制。 总之,STM32F4高级定时器提供了强大的PWM输出功能,通过适当的配置和编程,可以实现高精度的PWM信号输出。 ### 回答3: STM32F4系列微控制器中的高级定时器(advanced timer)可以用于输出PWM信号。以下是使用STM32CubeIDE配置高级定时器输出PWM的步骤: 1. 在STM32CubeIDE中创建一个新的工程,并选择适合的STM32F4系列微控制器型号。 2. 打开RCC配置工具,在高级定时器的时钟源中选择合适的时钟源,例如内部时钟。 3. 打开GPIO配置工具,选择需要使用的IO引脚,并将其配置为复用功能。 4. 打开定时器配置工具,选择需要使用的高级定时器(如TIM1、TIM2等)。根据需要,配置定时器的计数模式、计数频率、自动重装载值等。 5. 配置定时器通道,选择需要用于PWM输出的通道,并设置通道的输出模式为PWM模式。 6. 根据具体需求设置PWM的周期和占空比。可以通过调整自动重装载值和通道的比较值来实现。 7. 配置定时器的时钟分频系数,使其与所需的PWM频率相匹配。 8. 生成代码,并将生成的代码添加到工程中。 9. 在生成的代码中,根据需要调用HAL库提供的函数来启动和停止定时器。 通过上述步骤,就可以使用STM32F4的高级定时器输出PWM信号了。在实际应用中,还可以根据需要调整PWM的周期、占空比以及使用中断等功能来实现更复杂的PWM输出

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值