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

【经验分享】stm32定时器时钟以及中间对齐模式

[复制链接]
STMCU小助手 发布时间:2022-1-23 19:24
在永磁同步电机的控制中,需要对电机的三相定子施加一定的电压,才能控制电机转动。现在用的较多的是SVPWM(SVPWM的具体原理会在后面另写一篇博客说明),要想产生SVPWM波形,需要控制的三相电压呈如下形式,即A、B、C三相的电压是中间对齐的,这就需要用到stm32定时器的中间对齐模式了。
1439959-20181009145135207-365988838.png
1、stm32的时钟树
stm32的时钟树如下图所示,简单介绍一下stm32时钟的配置过程。以外部时钟作为时钟源为例。HSE代表外部时钟(假设为8M)、SYSCLK为系统时钟,经过倍频器之后变成168M、SYSCLK经过AHB预分频器(假设分频系数为1)后变成HCLK时钟等于系统时钟SYSCLK,HCLK即AHB外部总线时钟,经过APB预分频器分出APB1时钟(分频系数为2,低速设备SYSCLK/4)与APB2时钟(分频系数为1,高速设备SYSCLK/2)
HSE->SYSCLK->HCLK->APB1、APB2。
1439959-20181009145934096-582470711.png
针对stm32f427的配置源码如下
  1. static void SetSysClock(void)4 K) j5 T3 q9 _4 P% C+ j
  2. {
    % a$ h, F- F4 [6 G
  3. #if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx): h% |* q2 y3 t
  4. /******************************************************************************/
    ' q/ p0 h0 H: |" p" D
  5. /*            PLL (clocked by HSE) used as System clock source                */
    + X" I& b3 O; M1 t
  6. /******************************************************************************/
    ; e% U9 \: ?+ \; z$ {
  7.   __IO uint32_t StartUpCounter = 0, HSEStatus = 0;$ O5 [& `( B, q  c! x) @( u
  8.   , G$ c( v# Y# y
  9.   /* Enable HSE */
      Y7 ]! l3 t2 ]7 D- x
  10.   RCC->CR |= ((uint32_t)RCC_CR_HSEON);2 }& x, s9 H/ w
  11. / K( m) t- s8 x9 `: H. I6 }2 a, _( y
  12.   /* Wait till HSE is ready and if Time out is reached exit */
    ; O8 O; b% [0 h: \
  13.   do8 ~; N( o8 F! G! T+ J, P5 m4 H, v! N% b
  14.   {% S+ v0 i$ Q/ B% }$ f
  15.     HSEStatus = RCC->CR & RCC_CR_HSERDY;
    1 M/ _; O7 U- d& a% z+ {
  16.     StartUpCounter++;
    ) ^# f* i8 D' S" M
  17.   } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));( e5 z- k8 D! n
  18. 1 W, W1 G  H$ k8 M9 }+ F
  19.   if ((RCC->CR & RCC_CR_HSERDY) != RESET)
    ; r9 V, V' V1 g; f* s3 D3 c5 u
  20.   {9 c5 j, ]1 y0 w+ ?
  21.     HSEStatus = (uint32_t)0x01;
    . c& l2 |* J. E/ ]# @
  22.   }0 U+ g( j7 t1 X
  23.   else
    / M6 T% _( Q% k( o, ]7 `
  24.   {
    ( o& m* h4 z; |# Y5 M
  25.     HSEStatus = (uint32_t)0x00;
    : s/ O$ ^3 [  w( U+ G, W; ^1 u
  26.   }7 A6 V! v+ k' U; w0 ?% J# ]

  27. 2 j) N' h( D+ z/ t% X! o8 \
  28.   if (HSEStatus == (uint32_t)0x01)
    + }) k1 s0 K' ~, Z$ w
  29.   {7 C3 ]* m- Y6 Y0 c0 T+ g  K
  30.     /* Select regulator voltage output Scale 1 mode */
    & j3 Z; \# k# K$ |* W* O" r1 _
  31.     RCC->APB1ENR |= RCC_APB1ENR_PWREN;; |" f  c# y9 p$ |5 I
  32.     PWR->CR |= PWR_CR_VOS;
    9 q. c% j+ }9 u( J7 L) K  y6 O( O
  33. - w8 w9 i/ x& u- Q! D
  34.     /* HCLK = SYSCLK / 1*/
    ( i% G" o5 B- x+ g+ C
  35.     RCC->CFGR |= RCC_CFGR_HPRE_DIV1;//AHB时钟  
      X( @+ @& X8 F# j+ V5 {$ W
  36. * V  c/ t+ q) I5 ~$ m
  37. #if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx)      * {4 `/ Z% D% \$ Y; S, f1 |- k
  38.     /* PCLK2 = HCLK / 2*/1 W, w1 o. F/ \% J  E  M  E
  39.     RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;//APB2时钟
    / M# z8 E- i' \5 d
  40.     ! l$ J$ y8 ?+ k% s8 h' F8 v5 s
  41.     /* PCLK1 = HCLK / 4*/
    6 S0 L- ^: Z& e8 D; l9 b/ X
  42.     RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;//APB1时钟
    5 u' J; F" w* i$ t8 m
  43. #endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx */6 N% C  D! X9 B+ g9 u, B

  44. 1 X. `# @! X: f
  45.    / N8 w' c1 j* L6 b* C+ Z8 J
  46.     /* Configure the main PLL */
    % T5 Q$ G  J2 n! T& @6 C! s* |
  47.     RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
    6 R, u, v# g/ L4 z* S
  48.                    (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);5 a1 ?8 ?6 o: i$ c* q# V3 m, l! {
  49. : O/ O8 S% [3 r$ [2 ?0 N5 p8 Y, {
  50.     /* Enable the main PLL */
    ' ]; x9 ^5 v& r$ n" h0 v
  51.     RCC->CR |= RCC_CR_PLLON;7 a# }1 Z5 Y+ R: I" ^0 y* A
  52. 9 N. i; {; h, p
  53.     /* Wait till the main PLL is ready */
    & W2 a: A. D- I* r# n
  54.     while((RCC->CR & RCC_CR_PLLRDY) == 0)
    ; {& A' [* g1 M% x0 o
  55.     {
    ( [) I, A6 h6 [; o) F( F% s
  56.     }
    $ {4 m5 H) B8 ]2 L% S  _3 e6 L5 A
  57.    : J6 ^4 r2 x( v
  58. #if defined (STM32F427_437xx) || defined (STM32F429_439xx)
    , P& ?: O2 H4 n9 e& Q& g
  59.     /* Enable the Over-drive to extend the clock frequency to 180 Mhz */
      _( v: z9 `# y
  60.     PWR->CR |= PWR_CR_ODEN;
    7 ^- a8 E; M+ _) K% n& f& k7 Z( X
  61.     while((PWR->CSR & PWR_CSR_ODRDY) == 0)" j8 ^$ s2 f& b- J
  62.     {! U# n$ o" U) T7 e2 j1 T" n9 [6 u
  63.     }
    . a7 j! E1 ~/ A" Q$ Z
  64.     PWR->CR |= PWR_CR_ODSWEN;7 T$ N% z8 l# Y9 d- _$ \
  65.     while((PWR->CSR & PWR_CSR_ODSWRDY) == 0)
    9 N- s  K! C# x
  66.     {& \2 C. @; z2 z
  67.     }      ! h: u7 X0 B# v* _- _: f
  68.     /* Configure Flash prefetch, Instruction cache, Data cache and wait state */1 V: \: Q, e5 h2 @. \$ q8 \
  69.     FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
      B, F( d8 c# W! }3 H' b$ b
  70. #endif /* STM32F427_437x || STM32F429_439xx  */
    ; C- s: f9 j6 R# e+ `$ f
  71. ( }8 v0 W- N" [' I
  72. 0 d+ H, F2 l3 ]- r
  73.     /* Select the main PLL as system clock source */
    / k+ S" H+ H3 i% U
  74.     RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    / _" p$ |; P6 Y6 s* k) t
  75.     RCC->CFGR |= RCC_CFGR_SW_PLL;
    & ?# k! i- }/ C- }) G3 A/ C/ r

  76. + M, c" c5 \: k7 e+ f/ V$ @
  77.     /* Wait till the main PLL is used as system clock source */
    ) b( S0 P: o! x' q: u5 W, ^! n
  78.     while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);. A% \, ]( Y* d2 j
  79.     {, p6 B/ |7 L& O3 b0 W
  80.     }
    & m- u. s3 R$ \% p3 g
  81.   }
    - \$ @4 I/ D- X1 O7 Q
  82.   else) j  X6 d) j/ Q4 n8 t. @" q
  83.   { /* If HSE fails to start-up, the application will have wrong clock
    0 t# q/ @# B4 x" W6 R
  84.          configuration. User can add here some code to deal with this error */
      W$ ]$ G1 T% i2 X2 b
  85.   }
    $ @. ^% V1 l! q+ ~" N/ x/ u
  86. }
复制代码
5 n% a  R3 b* I7 k, l! h
2、stm32定时器的时钟
stm32定时器分为高级定时器(TIM1与TIM8)、通用定时器(TIM2-TIM5、TIM9-TIM14)、基本定时器(TIM6、TIM7)。不同的定时器使用不同的时钟。
其中TIM1、TIM8、TIM10、TIM11使用的是APB2时钟,而其余定时器使用的是APB1时钟。
1439959-20181009151652667-444631565.png
在stm32手册中有这么一段话
1439959-20181009151806696-2025482643.png

) c6 M! y3 u& ~* x8 S7 l
根据前面RCC配置可以知道TIM1、TIM8、TIM10、TIM11使用的时钟频率为SYSCLK,其他定时器使用的时钟频率为SYSCLK/2
3、stm32定时器1的中间对齐模式
对齐模式的图示如下图所示,可以看到在中心对齐模式下产生的PWM波形的周期比实际计数周期要大1倍,所以假设要使用中间对齐模式,并且需要产生的PWM波频率为20K,那么对应的定时器时基应该设为40K。

- U7 o/ z/ ^- k
1439959-20181009163316621-467293386.png

$ E7 _% e) n" X( h0 a0 K( q
在SVPWM波的产生过程中使用的是定时器1的3对互补的PWM通道,它的配置如下
  1. static void TIM1_Configuration(void)
    3 m4 a! j, o4 p2 |9 d8 a' b3 _! f
  2. {    ( J/ w# q6 a8 A, N$ M
  3.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;! u. Y' `( H3 X' x6 H6 K- U
  4.     TIM_OCInitTypeDef  TIM_OCInitStructure;: B) x5 L% N* D6 n
  5.     TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
    9 a7 r8 Y& {  N+ F( R/ A  U4 ^  A
  6.    
    / X. [; {: g2 D* E" q
  7.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//使能定时器1时钟
    ) j  ?  r! f7 E7 k$ U
  8.     " g7 Z& T1 g4 U" O. v" C  ^
  9.     Time1_Period =  (SystemCoreClock / 40000 );//定时器频率为APB2频率的2倍=HCLK 自动重装载为40K,最大值为4200
    ! \  C# l1 I8 x0 M% l! V
  10.    
    6 r; t, U% b4 B- g, ~7 C; ]. |; N
  11.     Limit_Pluse_Max_Value = Time1_Period * 0.95;
    " l) e& O0 M' {. v- l( ]
  12.     " c6 ^! ]/ p  v( j1 W& ?  O
  13.   /* TIM1 Peripheral Configuration */ $ @  ?  K. w4 Z
  14.     4 F+ X7 r* k0 p6 W0 m, |+ {
  15.   TIM_DeInit(TIM1);1 N: @! r# n( L( Q8 [
  16. 9 C& u$ J+ W$ c+ G. I' a- [- h
  17.   /* Time Base configuration */- ]' r2 [$ Q* G& M3 K
  18.     //配置定时器的计数方式为中间对齐方式,所以产生的PWM波的频率为20K
    6 `% R4 \2 v( e% h; i( a' _- N
  19.   TIM_TimeBaseStructure.TIM_Prescaler = 0x0;
    . M1 f; I/ W% E. l6 A5 _# R
  20.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;//TIM_CounterMode_Up;TIM_CounterMode_CenterAligned1
    $ n: J2 F  ^- j: \/ Q
  21.   TIM_TimeBaseStructure.TIM_Period = Time1_Period - 1;//PERIOD;//定时器时基40K
    9 n. q7 v& S: Q1 k
  22.   TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;7 ?) d4 l. A7 q( L1 ]& e
  23.   TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
    + J8 e3 y9 T' \* i: U
  24. 8 g5 o6 a6 X% d7 B0 J& V" V/ B2 b
  25.   TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);7 z+ o4 t( N0 M8 q6 b+ _7 \$ W

  26. : i  |  E2 E2 q; E( t' z
  27.   /* Channel 1, 2,3 and 4 Configuration in PWM mode */9 q. P. {* _/ ?& `
  28.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; - V7 u3 o0 x3 [% O
  29.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; , J1 e) a- l) M; a  E+ o; q  b$ o5 L
  30.   TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;                  * J, F' ?  X4 W5 a5 @4 \  C
  31.   TIM_OCInitStructure.TIM_Pulse = Time1_Period / 2;//CCR1_Val; //占空比50%
    ' u- H% F9 i6 d
  32.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//TIM_OCPolarity_Low;TIM_OCPolarity_High;3 L( F9 l" y. M% i* T* ^( A
  33.   TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//TIM_OCNPolarity_Low;TIM_OCNPolarity_High;         $ C* M0 L* |3 q
  34.   TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//TIM_OCIdleState_Set;
    # u  M6 b1 n0 o9 y
  35.   TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
    * m0 ]! u8 \+ S4 s
  36.     + Z$ t$ ^" ^- d9 @  a
  37.   TIM_OC1Init(TIM1,&TIM_OCInitStructure);
    ; d% d. f, C0 l3 {% {5 Z
  38. 4 D+ H& q& |# J5 q
  39.   TIM_OCInitStructure.TIM_Pulse = Time1_Period / 2;//CCR2_Val;//占空比50%% _2 W: n) }$ A: X& q! h$ B9 B
  40.   TIM_OC2Init(TIM1,&TIM_OCInitStructure);
    : `$ ]% T! b+ {4 e9 ]5 t3 F! I
  41. ! G0 G8 H. W' d1 N- H: w
  42.   TIM_OCInitStructure.TIM_Pulse = Time1_Period / 2;//CCR3_Val;//占空比50%# k. ~2 T/ A' f! m5 d
  43.   TIM_OC3Init(TIM1,&TIM_OCInitStructure);
    : w& b2 D' C+ k
  44.     $ v3 ^' M! g2 H! R( g/ k( N; W
  45.    
    8 Q! \( S4 k& U! x0 W% W* t
  46. //   /* Channel 4 Configuration in OC */3 M+ }7 ]3 P$ z+ A9 v
  47. //   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;3 k; I' }9 \) D$ j! [& b
  48. //   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;/ W- s" }7 X7 E! ^& {0 c2 W
  49. //   TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;9 ^/ h! s1 ?" r2 i9 \) X9 j  q
  50. //   TIM_OCInitStructure.TIM_Pulse = 4000;//Time1_Period / 2;            //1500;//PERIOD - 1; 3 O. w; z% \" v5 R& A
  51. //   
    : @# v/ N( J5 Y# x0 ^: D3 H
  52. //   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; % R! |5 W, d: B# I2 {- b
  53. //   TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;         ' K! F( h) }3 O& Z5 x- R
  54. //   TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;8 w. l- ~- N9 R4 [2 S
  55. //   TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;            
    ) c  W+ j! V- N! J. Q
  56.   6 t1 D7 G+ ^& L: }& j
  57. //   TIM_OC4Init(TIM1,&TIM_OCInitStructure);    * X; G8 ]6 Q- s
  58.    
    - T! H8 x8 U" f* A8 `0 t* f2 w
  59.     /* TIMx->CCMR1的bit3设为1:输出比较寄存器预装载使能 */  // PWM占空比改变只在更新事件时生效
    5 q0 R. i) }. N' {* M
  60.   TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);//A相
    % o9 d* ~' [# C. p
  61.    
    , h$ J  D/ @% @- g6 c: n8 I
  62.     /* TIMx->CCMR1的bit11设为1:输出比较寄存器预装载使能 */ // PWM占空比改变只在更新事件时生效3 }" ~& U6 k3 Z7 I9 R7 S& c
  63.   TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);//B相  z! V  \9 x) T0 P1 `% I3 d- _
  64.    
    . \  U7 o9 z# T+ h. ~( Y( C7 v+ ?
  65.     /* TIMx->CCMR2的bit3设为1:输出比较寄存器预装载使能 */  // PWM占空比改变只在更新事件时生效" A$ |( U7 {: W3 O  w5 c/ f
  66.   TIM_OC3PreloadConfig(TIM1,TIM_OCPreload_Enable);//C相. C+ k9 a3 Z3 Q  F4 x0 s

  67. 5 F1 a+ q/ V5 w7 F  w2 f3 V
  68. //   TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);//电磁铁
    + c  ?+ N4 S  l2 C* W& p8 T. H
  69.    
    0 Z' C) u6 P2 y' r" ~& ~3 q/ |
  70.   /* Automatic Output enable, Break, dead time and lock configuration*/6 n: k6 y3 H) R
  71.   TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;8 I' C  A- B8 h, v$ o
  72.   TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;/ E8 }, b! G% ?7 d% d- k
  73.   TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; + q$ t- b7 C+ n- f/ _' q3 Z
  74.   TIM_BDTRInitStructure.TIM_DeadTime = 50;) L* t( ^  ^7 l. R  i, Y7 b" `
  75.   TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;//TIM_Break_Enable;
    / u& d  R% Y- H: p/ E- t$ W* D
  76.   TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
    , ?6 ?: W/ N, P8 g( T
  77.   TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;//TIM_AutomaticOutput_Enable;
    * F0 _' C/ P4 P

  78. ! w6 b( h0 d# B5 e- c/ s7 x2 @3 ]+ @1 D2 |
  79.   TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);( J' O0 M# X4 W/ q/ i1 d: @
  80.     1 y1 t: g- Z( a7 n/ J
  81.     TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update);% G  ~5 ^+ @6 U/ g
  82.     - E; o2 I/ a" p# O
  83.   /* TIM1 counter enable */
    * z2 |- {6 m6 y, V9 q/ o- R5 T/ E
  84. //   TIM_Cmd(TIM1,ENABLE);
    " |+ P: D/ P5 b# {* j  ?" }+ r/ W

  85. : @4 E) i+ U% _1 K/ Q( L
  86.   /* Main Output Enable */
    4 M8 ~, F' B, x, H! t; U
  87.    TIM_CtrlPWMOutputs(TIM1,ENABLE);//由于使用中间对齐模式,PWM频率为20K
    : O6 i3 [1 }+ \5 t! W+ h) x
  88.     # [: ^3 `& d; d. R* {/ c3 Z! ?
  89.   //TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);//定时器1的溢出中断
    0 ]5 {  B! f1 W' P
  90. }
复制代码

, l( ]8 P; B7 p0 A5 a; O& |0 h" K
, c* O5 J) T+ e& I5 I; H$ j: |
赞 收藏 评论0 发布时间:2022-1-23 19:24

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版