如何利用STM32通用定时器实现输出两路占空比和频率可调的互补PWM
2015-04-02 20:49
1031 查看
MCU:STM32F334C8T6
PWM即脉宽调制,可以用来驱动电机,驱动全桥电路等,用过STM32的知道,用它的定时器可以很容易实现PWM输出,使用高级定时器的TIMx_CHy和TIMx_CHyN可以轻易实现互补PWM(complementary PWM)波形的输出。
高级定时器资源有限,本文利用通用定时器(General-purpose timers)实现互补PWM输出,在高级定时器资源不够时不失为一个好方法。
STM32的定时器PWM有两种模式:PWM mode 1和PWM mode 2
In downcounting, channel 1 is inactive (OC1REF=‘0’) as long as TIMx_CNT>TIMx_CCR1 else active (OC1REF=’1’).
PWM mode 2 - In upcounting, channel 1 is inactive as long as TIMx_CNT<TIMx_CCR1 else active.
In downcounting, channel 1 is active as long as TIMx_CNT>TIMx_CCR1 else inactive.
官方手册对channel 1 的说明,其他channel类似,考虑向上计数模式
PWM mode 1:TIM3_CNT<TIM3_CCR1 输出高,TIM3_CNT>TIM3_CCR1 输出低
PWM mode 2:TIM3_CNT<TIM3_CCR1 输出低,TIM3_CNT>TIM3_CCR1 输出高
可以看出,无论是mode1还是mode2,电平翻转都是在计数器TIM3_CNT中的值达到TIM3_CCR1 中的值(次数可以控制占空比,见下文)的时候
据此,可以将TIM的两个通道(如TIM3_CH1和TIM3_CH2)分别配置为mode1和mode2,那么即可输出两路互补互补PWM,此为方法一
acive high:TIM3_CNT<TIM3_CCR1 输出高,TIM3_CNT>TIM3_CCR1 输出低
active low:TIM3_CNT<TIM3_CCR1 输出低,TIM3_CNT>TIM3_CCR1 输出高
于是,同种模式下,分别将两个通道的有效电平配置为高和低,也可以实现互补PWM输出,此为方法二
在向下计数模式中原理类似,不再说明
CNT中是计时器当前的计数值,CCR1中是用来比较的值,当CNT达到CCR1的值时,将发生电平转变
另一个寄存器ARR,自动装载寄存器,存储的是自动装载的值,向上计数中当CNT递加达到ARR的值时将被复位,从0从新开始,而向下计数时,当CNT到达0时,ARR中的值将被自动装载到CNT重新开始递减,也就是说ARR中的值是计数周期(中心对其计数模式此处不考虑)
假设我们需要的频率为freq,占空比dutycycle,定时器使用系统频率SYSCLK,有如下关系:
ARR = SYSCLK/freq,dutycycle=CCR1/ARR
可见,通过更改ARR实现频率可调,更改CCR1实现占空比可调
附图为亲自测试效果,两种方法效果相同
测试基于STM32F334C8T6,频率100k,占空比45%,互补波占空比55%
wind
2015,04,02
PWM即脉宽调制,可以用来驱动电机,驱动全桥电路等,用过STM32的知道,用它的定时器可以很容易实现PWM输出,使用高级定时器的TIMx_CHy和TIMx_CHyN可以轻易实现互补PWM(complementary PWM)波形的输出。
高级定时器资源有限,本文利用通用定时器(General-purpose timers)实现互补PWM输出,在高级定时器资源不够时不失为一个好方法。
STM32的定时器PWM有两种模式:PWM mode 1和PWM mode 2
工作原理:
PWM mode 1 - In upcounting, channel 1 is active as long as TIMx_CNT<TIMx_CCR1 else inactive.In downcounting, channel 1 is inactive (OC1REF=‘0’) as long as TIMx_CNT>TIMx_CCR1 else active (OC1REF=’1’).
PWM mode 2 - In upcounting, channel 1 is inactive as long as TIMx_CNT<TIMx_CCR1 else active.
In downcounting, channel 1 is active as long as TIMx_CNT>TIMx_CCR1 else inactive.
官方手册对channel 1 的说明,其他channel类似,考虑向上计数模式
方法一:
假设高电平为有效电平,即高电平为active,使用定时器3PWM mode 1:TIM3_CNT<TIM3_CCR1 输出高,TIM3_CNT>TIM3_CCR1 输出低
PWM mode 2:TIM3_CNT<TIM3_CCR1 输出低,TIM3_CNT>TIM3_CCR1 输出高
可以看出,无论是mode1还是mode2,电平翻转都是在计数器TIM3_CNT中的值达到TIM3_CCR1 中的值(次数可以控制占空比,见下文)的时候
据此,可以将TIM的两个通道(如TIM3_CH1和TIM3_CH2)分别配置为mode1和mode2,那么即可输出两路互补互补PWM,此为方法一
方法二:
方法一中假设高电平为active状态,事实上active状态也可以是低电平,在这种情况下,考虑同一种模式(mode1)acive high:TIM3_CNT<TIM3_CCR1 输出高,TIM3_CNT>TIM3_CCR1 输出低
active low:TIM3_CNT<TIM3_CCR1 输出低,TIM3_CNT>TIM3_CCR1 输出高
于是,同种模式下,分别将两个通道的有效电平配置为高和低,也可以实现互补PWM输出,此为方法二
在向下计数模式中原理类似,不再说明
频率和占空比的调节:
上面提到了两个寄存器:CNT和CCR1,(channel x 对应CRx)CNT中是计时器当前的计数值,CCR1中是用来比较的值,当CNT达到CCR1的值时,将发生电平转变
另一个寄存器ARR,自动装载寄存器,存储的是自动装载的值,向上计数中当CNT递加达到ARR的值时将被复位,从0从新开始,而向下计数时,当CNT到达0时,ARR中的值将被自动装载到CNT重新开始递减,也就是说ARR中的值是计数周期(中心对其计数模式此处不考虑)
假设我们需要的频率为freq,占空比dutycycle,定时器使用系统频率SYSCLK,有如下关系:
ARR = SYSCLK/freq,dutycycle=CCR1/ARR
可见,通过更改ARR实现频率可调,更改CCR1实现占空比可调
部分代码:
uint16_t period=0,pulsewidth=0; GPIO_InitTypeDef GPIO_InitStruct; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; period = 72*1000000/(100*1000);//计数周期,系统频率72M,PWM输出频率100k pulsewidth = 45*period/100; //脉宽,占空比45% //开启外设时钟 //配置GPIO TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = period - 1;//ARR
</pre><pre name="code" class="html">//填充TIM_TimeBaseInitStruct其他参数
<span style="font-family: Arial, Helvetica, sans-serif;">TIM_TimeBaseInit(TIM3, & TIM_TimeBaseInitStruct);</span>
//OCInit结构体初始化,填充完所有参数 TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse = pulsewidth; //CCR1 TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //TIM_OC1Init()开启通道1 //OC2 方法1 : 修改Mode TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; /*********************************** //OC2 方法2 : 修改 Polarity TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low; ***********************************/ //TIM_OC2Init()开启通道2 //最后打开时钟 TIM_Cmd(TIM3, ENABLE);
附图为亲自测试效果,两种方法效果相同
测试基于STM32F334C8T6,频率100k,占空比45%,互补波占空比55%
完整代码下载:
http://download.csdn.net/detail/wind4study/8559157wind
2015,04,02
相关文章推荐
- STM32一个Timer输出4路不同频率、可调占空比的PWM
- STM32: 利用高级定时器产生6路互补PWM波形输出在BLDC中H-PWM-L-ON驱动方式下驱动无刷电机
- STM32一个Timer输出4路不同频率、可调占空比的PWM
- STM32定时器输出不同频率不同占空比的PWM
- stm32输出可调频率和可调占空比的pwm信号
- STM32一个Timer输出4路不同频率、可调占空比的PWM
- STM32学习笔记:通用定时器输出PWM
- (转)STM32学习笔记(5):通用定时器PWM输出
- AVRmega16通过一个定时器实现多路IO口输出多路可调的PWM
- 【定时器/中断/PWM】利用一个定时器实现一路PWM波的输出---点亮LED
- STM32 多个定时器PWM波输出频率不同。
- STM32F4_TIM输出PWM波形(可调频率、占空比)
- Stm32 定时器 定时时间设置及PWM频率 占空比的设置总结
- STM32学习笔记(5):通用定时器PWM输出
- STM32利用通用定时器输入PWM
- 详解STM32的PWM输出及频率和脉宽(占空比)的计算——寄存器配置六步曲!
- R4 STM32高级定时器笔记之PWM互补输出
- STM32 自定义频率与占空比PWM输出的方法
- stm32通用定时器的PWM输出
- mini6410利用定时器1把GPE2 和GPE4口输出可调PWM