你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

[经验分享]SMT32的PWM波形输出配置的大神总结

[复制链接]
STMCU小助手 发布时间:2021-9-23 10:37
本文分享STM32之PWM波形输出配置总结。! X( O+ c- q& y

9 t+ J1 u. d8 V# W. z- B$ g7 l一.   TIMER分类:' i+ ~9 g" f& A; j- \

8 W$ l8 t' g  O5 L4 b1 c
6 J4 _9 J9 g4 ]2 A! Y! s- ?4 h% O+ G
STM32中一共有11个定时器,其中TIM6、TIM7是基本定时器;TIM2、TIM3、TIM4、TIM5是通用定时器;TIM1和TIM8是高级定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。其中系统嘀嗒定时器是前文中所描述的SysTick。
; A: D% C( }" k7 q' Y+ Z0 c
13.png
其中TIM1和TIM8是能够产生3对PWM互补输出,常用于三相电机的驱动,时钟由APB2的输出产生。TIM2-TIM5是普通定时器,TIM6和TIM7是基本定时器,其时钟由APB1输出产生。* w5 u' M6 J" d: ?3 t! Q

" F+ g; n- b( Z% R  s- Y二、PWM波形产生的原理:
  U/ Y- Q$ b* r* A# A, a+ D, d
- K* _. b9 M, d

1 B! I. X/ c$ d0 [通用定时器可以利用GPIO引脚进行脉冲输出,在配置为比较输出、PWM输出功能时,捕获/比较寄存器TIMx_CCR被用作比较功能,下面把它简称为比较寄存器。4 D4 t# F' C+ x; ^: u! D
  W, K7 C* n+ R5 B
这里直接举例说明定时器的PWM输出工作过程:若配置脉冲计数器TIMx_CNT为向上计数,而重载寄存器TIMx_ARR被配置为N,即TIMx_CNT的当前计数值数值X在TIMxCLK时钟源的驱动下不断累加,当TIMx_CNT的数值X大于N时,会重置TIMx_CNT数值为0重新计数。5 U' q  e2 R" q
1 W( W) {  f9 O' B: Z- Y0 A& m4 z
而在TIMxCNT计数的同时,TIMxCNT的计数值X会与比较寄存器TIMx_CCR预先存储了的数值A进行比较,当脉冲计数器TIMx_CNT的数值X小于比较寄存器TIMx_CCR的值A时,输出高电平(或低电平),相反地,当脉冲计数器的数值X大于或等于比较寄存器的值A时,输出低电平(或高电平)。
* [, w3 a$ d7 c( H7 n8 Q& W/ s4 c0 W0 j3 O' b! [! P8 y

( z) G) C3 A% y- _! ?' U) r5 V8 d7 x如此循环,得到的输出脉冲周期就为重载寄存器TIMx_ARR存储的数值(N+1)乘以触发脉冲的时钟周期,其脉冲宽度则为比较寄存器TIMx_CCR的值A乘以触发脉冲的时钟周期,即输出PWM的占空比为 A/(N+1) 。
$ g# I" u2 b1 h0 g% q7 m' R
. G$ B$ K7 \! M) F0 T三、STM32产生PWM的配置方法:
' F5 Q3 G7 Z. R7 ~" s( e0 u3 H/ Y5 n9 {" V0 @# Y2 o, b

' |: Y% q# ]$ v/ c) k% {( O" t1、配置GPIO口:
/ l* W# `7 P1 `0 R; ]
7 z! c% C2 f* l, g% j# B6 A* g2 g" n
2 t" k3 A( O0 Y3 w) l8 w
  配置IO口的时候无非就是开启时钟,然后选择引脚、模式、速率,最后就是用结构体初始化。不过在32上,不是每一个IO引脚都可以直接使用于PWM输出,因为在硬件上已经规定了用某些引脚来连接PWM的输出口。下面是定时器的引脚重映像,其实就是引脚的复用功能选择:
: {. S* t# D( S3 j, F  L1 `  V( r" F, T% K) C. b5 V
! V  Z9 X; e' j* y4 d; {
  a.定时器1的引脚复用功能映像:. u; J/ ]$ U* [( `2 q0 Q$ z: l
14.png
  b.定时器2的引脚复用功能映像:
) `# d  A' a* d7 w5 d# t
15.png
  c.定时器3的引脚复用功能映像:
) E) C2 z# _* e2 m" |+ S
16.png
    d.定时器4的引脚复用功能映像:0 T5 l+ V1 K- O$ y4 D2 |2 I& I
17.png

# k" O& V0 Q/ @; Z2 Y根据以上重映像表,我们使用定时器3的通道2作为PWM的输出引脚,所以需要对PB5引脚进行配置,对IO口操作代码:1 l; f; J" e% C2 S
  1. GPIO_InitTypeDef GPIO_InitStructure;//定义结构体$ O) h& R2 y& N7 g/ i9 l
  2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);//使能GPIO外设和AFIO复用功能模块时钟+ Q' L8 }2 G' U6 |# F
  3. GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //选择Timer3部分重映像    / L; D9 c; S9 `3 ?9 ^3 [
  4. //选择定时器3的通道2作为PWM的输出引脚TIM3_CH2->PB5    GPIOB.5
    ' D5 M+ [$ U( u6 b! B7 `1 @6 J
  5. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
    & D+ `5 m' H0 C2 f6 e
  6. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽功能) G* X/ [! @: M! [8 H
  7. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;( m: d5 A# U- J! I3 a' m
  8. GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化引脚
复制代码
2、初始化定时器: 
4 @) g0 X) {/ a: A

  1. , _+ T" l3 [' s( x
  2. TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;//定义初始化结构体9 p8 d6 \7 `" X' y- J
  3. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟6 [' t" D/ }6 U4 N2 W2 O: @9 v
  4. //初始化TIM3# C* S8 y, E* k$ K" V# c- D7 r0 J
  5. TIM_TimeBaseStructure.TIM_Period = arr; //自动重装载寄存器的值. ]) K9 L" S! O
  6. TIM_TimeBaseStructure.TIM_Prescaler =psc; //TIMX预分频的值0 m/ Z$ {! ~. u( U& f2 n5 t- M4 N# ^
  7. TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割
    " Y# b$ j6 {% C2 ^" H7 m6 |
  8. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数" T9 z: |& `) N$ [) Q. O/ c
  9. TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据以上功能对定时器进行初始化
复制代码
3、设置TIM3_CH2的PWM模式,使能TIM3的CH2输出:
+ |  W( r- g  K0 Z( f: O, k
  1. TIM_OCInitTypeDef  TIM_OCInitStructure;//定义结构体
      s  c, J+ ]8 z! W, D
  2. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;//选择定时器模式,TIM脉冲宽度调制模式21 B, e& z4 Q9 E) L" F
  3. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能5 a' [6 i+ A% T0 o( K
  4. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//输出比较极性低
    % C+ h  F) ~: R- k# t% T0 {
  5. TIM_OC2Init(TIM3, &TIM_OCInitStructure);//根据结构体信息进行初始化/ i) T5 A. `; _5 B) Q" B
  6. TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能定时器TIM2在CCR2上的预装载值
复制代码
4、使能定时器3:- r. Q4 F; ^) B, n0 P4 o% d
  1. TIM_Cmd(TIM3, ENABLE);  //使能定时器TIM3
复制代码
经过以上的操作,定时器3的第二通道已经可以正常工作并输出PWM波了,只是其占空比和频率都是固定的,我们可以通过改变TIM3_CCR2,则可以控制它的占空比。修改占空比的函数为:5 B; f9 ~3 X: u+ s# O9 r; g
  1. TIM_SetCompare2(TIM3,n);  //n不同,占空比不同。
复制代码
5、修改pwm波形的占空比:0 I$ k5 V  ~2 [9 @# u
编写一个函数:& O. p% @3 f$ a  k& S1 _+ _
  1. void TIM3_PWM_Init(u16 arr,u16 psc);
复制代码
将以上所有的代码都加进来这个函数中,只要在main函数中调用该函数进行初始化,然后使用TIM_SetCompare2()函数修改PWM的占空比就可以在PB5脚得到需要的PWM波形了。关于频率以及占空比的计算方法有以下例子:
, F9 F' T* I; D+ H! H; A) G
  1. % R' v' q; G* [
  2. int main(void)$ \6 k2 r0 S% U, s6 g
  3. {
    ! h; l% N- N5 k0 ~  X4 y
  4.   TIM3_PWM_Init(9999,143);//频率为:72*10^6/(9999+1)/(143+1)=50Hz
    * K6 h: K  y" \. V0 |5 d2 g- T3 L
  5.   TIM_SetCompare2(TIM3,4999);//得到占空比为50%的pwm波形
    ; x. T! S: q1 T! h+ ]& m# D! k: N
  6.   while(1);
    . v3 X, y/ Q( h# ~$ O1 L  y1 [
  7. }
复制代码
9 w5 C  d9 @% {% b

5 s' t* U. E% }6 E

/ j' D9 l4 K" f. s& h+ g3 ?% u6 _1 h: F( N
! H. O4 h: G3 \5 J
收藏 评论0 发布时间:2021-9-23 10:37

举报

0个回答

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版