STM32 CUBEMX主从定时器配置PWM任意相位可调,占空比以及频率可调(学习记录)

一.前言

通常stm32产生PWM用的是定时器的PWM模式,以此来生成频率和占空比可调的方波信号。但某些时候也需要生成初始相位可调的方波,仅仅使用一个PWM功能就不能满足要求了,这时我们可以通过主从定时器来实现。

定时器可以设置主从关系,简单来说就是可以用主定时器控制从定时器,这个过程可以套娃,如:从定时器可以控制从从定时器。

 主从模式定时器内部连接图(每款芯片可能有所不同,具体参见自己芯片手册):

定时器内部触发连接源,例:若从定时器为TIM2,主定时器为TIM1,那么触发源为TR0。

这里我构想了两种方法,方法一仅作参考,推荐方法二,效果更好。

二.方法一

1.原理

以两PWM相位相差180°,两PWM占空比任意可调为例:

这里使用了三个定时器,TIM1为主定时器,TIM2为从定时器。TIM3为从从定时器。TIM1与TIM3所成PWM为最后所需要的,TIM2起到相位调节的作用。当TIM1产生上升沿时,TIM2开始计时,当TIM2计时到周期的一半时(即为180°相位值时,换个意思也就是时间差,这里时间差为周期一半,也就是TIM2产生占空比为50%的PWM)产生PWM,TIM2的上升沿被TIM3检测到后,TIM3开始产生PWM,占空比任意。这样就可以实现两任意相位,任意占空比的PWM。

2.实现

以STM32F407ZGT6为例(其他型号类似),实现双PWM相位差为180°(若需其他相位更改TIM2占空比就行了!),占空比任意。

2.1创建项目

配置时钟树,我这里配置时钟为80Mhz

2.2配置定时器

2.2.1 TIM1配置(主定时器)

只用了1个通道,配置为PWM输出模式,内部时钟

 因为前面时钟为80Mhz,故预分频79,时钟周期1000,pwm频率:80Mhz/(79+1)/1000=1Khz,

设置触发输出使能,通道一比较输出(重要!!!)、PWM模式1,pulse为300(占空比为300/1000=30%)

 

2.2.2 TIM2配置 (从定时器)

定时器二模式设置为触发模式、触发源根据前言中的表可以得到为ITR0,选择内部时钟,通道1输出PWM。预分频为79,计数周期为1000,设置触发输出使能,通道一比较输出、PWM模式2(pwm模式2重要!!!),pulse为500(占空比为500/1000=50%,也就是相位为180°)

2.2.3 TIM3配置 (从从定时器)

配置和TIM2一样,只是触发源由表得为ITR1,因为后面没有从定时器了,故不再配置触发输出了,这里为PWM模式1,占空比参数随便设为200(200/1000=20%)

3.下载测试

3.1 生成代码

主程序添加:

    HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);

记得魔术棒里设置下载复位,或者手动复位。

 3.2 运行结果

这里TIM1与TIM3所成波形为所需结果。

3.2.1 TIM1与TIM2

黄色为TIM1,当TIM1产生上升沿,TIM2开始计时,当达到180°(周期一半,即占空比50%)时,开始产生PWM,TIM1与TIM2周期一致。

3.2.2 TIM2与TIM3

黄色色为TIM3,当TIM2开始产生上升沿时,TIM3被触发,产生PWM

3.2.3 TIM1与TIM3(所需结果)

TIM1与TIM3为所需结果,周期相同,相位相差180°,占空比随便设置的,可以在cube里面调,或者用函数调。

如图所示,两个目标PWM相位差在180°,但是在实际应用中可能存在一定误差,因此想了第二种方法。 

三.方法二 

1.原理

需要产生两个PWM相位任意差,占空比和频率可调。同样使用3个主从定时器,1个定时器用来定时,2个定时器来产生PWM。因为相位改变本质是改变信号的初始时间,当延时初始时间占周期时间一半,则相位差为180°。需要多少相位差,则据公式:相位差=延时/周期。

2.配置cubemx

配置时钟树,据所需配置,如80Mhz

 

2.1 TIM1产生PWM1

配置定时器1产生PWM,内部时钟源,预分频80-1,计数周期100-1,占空比10%

2.2 主定时器TIM2定时设置相位

主定时器用于定时初始开始时间,当定时时间达到触发从定时器产生PWM。以相位相差180°为例,那么时间差则因为PWM周期的一半。在TIM1中配置计数周期为100-1,要一半则为50-1,如下图所示:

 配置内部时钟,不选择通道只计时,预分频79(需与上面定时器相同!),触发模式设置为更新事件(就是计数达到了事件进行更新触发从定时器产生PWM)。

2.3从定时器TIM3产生PWM2

当上面主定时器达到时间时,触发从定时器TIM3产生PWM。配置为触发模式,内部时钟,通道为PWM模式,触发源根据上面表格或者芯片手册可得为ITR1,预分频、计数周期与TIM1的相同,占空比根据自己需要填,如10%

 3.测试

生成代码并在main函数里添加

	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
	HAL_TIM_Base_Start(&htim2);
	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);

 验证结果:

可见,两个PWM的相位相差为一半,即180°,若需要其他相位只需更改TIM2中的计数值就行了。 

四、程序中随时修改数据以及所涉及到的问题(补充)

通过第二种方法配置好并添加启动程序后,相位的确是我们所需要的相位了,但是有些情况下我们又需要去在程序中修改PWM的频率、相位以及占空比的大小。而在这里,我们就会用到几个常用函数:

1.__HAL_TIM_SET_PRESCALER(&htim3, 79);  //设置预分频器值

2.__HAL_TIM_SET_COUNTER(&htim3, 0);  // 设置计数器值
3.__HAL_TIM_GET_COUNTER(&htim4);//得到当前值

至于如何在程序中使用上面函数修改相关值大小,需要弄清楚定时器产生PWM以及其定时原理,然后根据需要设定相应的计数器值和预分频值。定时器原理可以参考下面两篇文章:

【1】STM32 PWM基本知识及配置过程_stm32 pwm配置-CSDN博客

 【2】STM32定时器详解_stm32通用定时器基本定时器-CSDN博客

注意:在使用以上函数修改相关值时,需要注意时序!!!如下图所示:

当从某时写入新的值时,并不是立马完成数据更改, 而是等计数器计数值满归零时才开始运行新的数据。所以,为了保证时序的准确,最好是加一个延时等待计数器时序上的更新

其他

1.OCxREF指通道x,这里定时器有四个通道

2.同一个定时器共用一个计时器,即同一个定时器的4个输出通道的频率(周期)相同

3.TIM1_CH1N与TIM1_CH1是互补意思

4.PWM 模式一:初始为高电平,立即触发;PWM模式二:初始为低电平,等高电平再触发

声明:本文为作者学习记录,由于知识有限,存在各种不足,望谅解!

  • 54
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值