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

基于STM32通过PWM控制电机速度经验分享

[复制链接]
攻城狮Melo 发布时间:2023-9-21 15:15
PWM控制电机速度的基本原理    PWM(Pulse Width Modulation),也就是脉冲宽度调制。
% |+ s8 j( M: ?' t0 _) I
    PWM中有一个比较重要的概念,占空比:是一个脉冲周期内有效电平在整个周期所占的比例。    为了实现IO口上电压的持续性变化,可以调节PWM的占空比。这也能够使外设的功率进行持续性变化,最终控制直流电机转速的快慢。如何调节PWM波形的输出就是重点。
, V1 z) ]$ p- s

$ `+ t& R+ {4 v' k 微信图片_20230921151526.png 5 t7 o* ?0 r) z7 E( ~0 @

9 f  p. S% z) L  I% _6 B

& q+ L2 ^; o" `+ z) j0 k% K% j* R

) z: U+ B: U$ V: f  e6 T: g) D   上图中的ARR是我们给定时器的一个预装载值,CCRx的上下变化是产生PWM波的关键。我们假设ARR大于CCRx的部分输出为高电平(即t1-t2、t3-t4、t5-t6),ARR小于CCRx的部分输出为低电平(即0-t1、t2-t3、t4-t5),则改变CCRx的值就能改变输出PWM的占空比。因此,想要控制PWM的输出波形,重要的就是如何设置ARR与CCRx这两个寄存器的值了。
5 Q* Y: `0 l! }# K' u$ I0 ]9 F$ N* E
# n! Z0 u: S1 l  k
STM32定时器中断   
+ ^, b/ I; u- e% `8 ?6 t为了便于理解接下来关于PWM应用的内容,先插一段定时器中断的知识。    产生定时中断是定时器的用法之一,与定时器用来进行PWM输出和输入捕获相比,定时器中断更容易理解、掌握。8 z& V- J8 d- m: v+ B  o  a* _) [" d

0 s( Y) v" s& ?- L# T! B
8 |' B. j' K; M+ T% \
原理简介   
  I9 }8 k. h4 S3 F3 F0 H使用通用定时器进行中断的原理,其实和开发板Systick定时器进行中断延时很相似(Stm32入门——Systick定时器),即:用psc(预分频系数)设置好定时器时钟后,arr(预装载值)在每个时钟周期内减1,当arr减为0时触发中断然后进入中断处理程序进行中断处理。以下代码为例:
/ z( s5 ~! m4 i, N( }5 Z+ @& D$ `0 Y& C4 s0 S; B5 g

! ~  g: ?8 R4 Z- m; P 微信图片_20230921151520.png
& s; C. D* X4 F3 m0 ~
  W0 v4 d6 o% q8 b  Y, g
4 ^6 f! [( f' \. w" Z
    解释一下上面这行代码,由于定时器3(TIM3)是挂在APB1上的外设,所以要打开APB1,这里的预分频器值psc是来设置TIM3的时钟频率的,如果系统时钟(SYSTICK)频率为72MHz、psc为7199,则TIM3的时钟频率就为:
2 I) r# _5 j' Z) M7 X/ v  q* l3 w) Y

0 l8 P: z  Z7 K! g3 }7 c 微信图片_20230921151516.png 6 }- ?2 ^0 x0 {" Z& Z
( x7 q: y9 x1 q+ D, U* Z: K; A

  n( b! \; R0 r3 Q( L: m4 R  s1 H    10KHz是什 么意思呢?就是一秒钟会产生10K个周期,那么一个周期的时间长度就是1/10KHz,如果你想将定时器中断的时间间隔设置为0.5秒,那么你将arr设置为5000即可,因为arr每减1就需要一个周期的时间,减5000次就经过了5000*(1/10KHz)=0.5秒。' a( H; _3 T7 e3 y

+ w  w$ W- @  f' s) `

0 s9 a. L" m5 t* A8 | 微信图片_20230921151511.png
! T$ N, h6 l/ s9 I1 r( j+ @2 m& B, u( O9 H+ z

, C; t0 Q1 x, Z# y& {" i2 _) L" j    再解释下上面这一行,设置允许更新中断,即arr减到0以后可以触发更新中断,还有其他类型的中断。
1 M8 h6 y6 i! M# A# d) b1 F  |
0 F, h: D, s6 @( q' n" Z( E! N' N
6 i: y3 K6 J5 {% K# z$ F: ?
微信图片_20230921151506.png 9 N! W& b- e3 K
$ B8 j- Q2 y- e  r

- y5 i8 E6 a; K9 [4 g5 _    看上面这行代码,中断优先级有抢占优先级和响应(即子优先级)优先级两种,抢占优先级即:若程序1正在使用CPU,这时如果程序2要求使用CPU,并且程序2的抢占优先级高,则CPU被程序2抢占;若两者抢占优先级相同,则就算程序2的响应优先级高于程序1,CPU也不能被抢占;若程序1正在使用CPU,程序2和程序3的抢占优先级等于或低于程序1,且程序2的响应优先级高于程序三,则待CPU空出后,程序2先运行,程序3最后运行。TIM3_IRQn是指定将要运行的中断处理程序号。“组2”是设置中断优先级分组的,这是因为寄存器提供了四位来设置优先级,组2代表的是前两位给抢占优先级,后两位给响应优先级。
# r* f& f- D7 Q1 Q
, z. p: c/ F0 l9 Y- |& FPWM模式、有效电平   
5 e8 P5 O0 R+ v) |" d前面介绍完中断,再说一下PWM工作原理。    假设上图中ARR大于CCRx时输出为高电平,ARR小于CCRx时输出为低电平,但在实际运用中可能并非如此,有可能是相反的情况——ARR大于CCRx时输出为低电平,ARR小于CCRx时输出为高电平,至于到底是哪种情况,还要看PWM是哪种模式、有效电平又设置的是何种极性了。
  • 模式1:ARR小于CCRx时输出为“有效”电平,ARR大于CCRx时输出为“无效”电平。  _' x: _2 e: [% U
  • 模式2:ARR小于CCRx时输出为“无效”电平,ARR大于CCRx时输出为“有效”电平。3 c" b/ C% h) f  b# O2 u1 O  S8 w
    这里说的是“有效”和“无效”,而不是“高”和“低”,也就是说有效电平可高可低,并非一定就是高电平。PWM模式、效电平极性,需要程序员自己配置相关的寄存器来实现。通过下面的代码来讲解。+ M. s0 J9 C4 X/ \0 J- ~
* S4 Y$ d$ `  G, P  \% |

/ Z9 m5 z9 g. J9 p% x 微信图片_20230921151503.png
# h0 `+ I0 h3 A2 e5 w
, X  n4 D  j' D4 b- j, O4 f7 G

( z, f. x, Z4 a: V6 }! w3 ]    上一小节讲过关于定时器参数的设置。使用定时器1的通道1来输出一路PWM波,这里的899设置的就是ARR的值,至于那个0是用来设置TIM1的频率的,不分频就代表TIM1的时钟频率和系统时钟相同,这里假设为72MHz。
& Y' d! Q0 y0 R- Q# N- ^
# C& b$ |) w4 i! X! ^& O
, X1 _) N! }( O6 R; l/ w' Q1 }# j
微信图片_20230921151459.png
1 J' V: x/ h! i; f! w* P% U( @* A: B& ~1 k/ e; U5 a4 C) j/ p) F

$ U* E7 _  h' h    下文具体分析上面的代码。
; [2 Y: m/ S9 z4 n( a* R
    前面4-6行是用来配置GPIO口的。5 K; C; B# r) ^+ H2 B7 x
0 _' G# l$ z2 A6 `  I$ U
! Y- Y+ O" Z0 D, l% G/ _
微信图片_20230921151456.png * l+ o) S0 ]: g7 D# U
& T; n) Z4 \% K; m, e

/ w9 F" R4 p' V" O3 x1 H+ N    这两行就是我上门提到的设置定时器的频率和重装载值。% o9 y0 Z- t/ ?4 i/ a
- w4 v0 n2 t9 s2 C, Q2 y. x& _

/ p5 Q* u$ T5 T' l9 x+ W 微信图片_20230921151452.png 0 k: n0 l+ l+ z$ Y. L

, G6 R: z% Q2 x% e

$ V- E0 C0 |  o- |! J    这三行是用来设置PWM输出模式和设置通道的,通道是什么呢?简单地讲就是输出PWM波的GPIO口,代码一开始不是设置了PA8这个GPIO口嘛,这个PA8就是通道1。使用通道的话要先进行输入输出方向、通道使能的设置。
5 M( S* ^0 F+ t
/ H: q: d7 v4 `9 U0 Z# ?) M
( T' ^3 _4 p- w$ d% G% B
微信图片_20230921151449.png
' K2 h, u6 X" N1 n  E, B
$ M; r  l1 x5 E; `7 D% t
$ F! X. q. h# `; p
    这行代码是用来设置“有效电平”极性的,根据手册,当TIM1->CCER[1]这位置1时,有效电平为低电平,置0时有效电平为高电平,而默认情况下置0。
: M& a; c' x$ h) F6 R2 A
# M$ A2 ~; ~9 a: P5 w

& ^! p6 O! N# L! ? 微信图片_20230921151446.png $ A2 T/ t1 ^6 g5 F, i
& G7 W1 v8 [3 {8 d1 e, T! r+ |

% m$ d$ H0 L& }    这行代码只要对高级定时器进行设置,普通定时器无需设置。
0 p, c0 Y, u" p' t$ j
/ T* m' g! p- x0 k! e: K- z
) W9 r0 J/ a% ?, w8 U6 C# @4 P
微信图片_20230921151442.png 6 P! k1 Q' E0 i8 i
: }" N5 C# W' l6 \& H) J

) ^' N) M" \- i4 y. }# h    这行代码是用来使能ARPE,ARPE是什么呢,就是当它被置1时,你自己设置的CCRx会立即生效,如果它被置为0,那么你自己设置的CCRx值不会立即生效(可能之前ARPE已经有值了),而是当之前设置的CCRx生效后才会使用你最新设置的CCRx值。
' t1 g6 A! H, I' ?, R+ _7 ?
$ Z# {& B) r$ D: d  S% n6 j7 v
上面的代码里没有对CCRx进行设置,这是因为CCRx常常是一个变化的值,你可以在主函数中用一个for循环+if判断语句对它进行++或–的操作,从而达到连续改变CCRx值得目的,例如:3 ?9 P0 B$ x+ t) g, ]/ w

" n( r$ e* ?& ^% D' j

8 b7 b$ H' `+ I2 P& Y4 g, _6 D4 y7 O 微信图片_20230921151438.png
$ i/ }9 A& e- d2 y" O' E' Q( \1 h$ z6 S. F* B& H: Z* {/ `! h
! |% x6 f) [/ h8 h# M% \6 X
    PWM波的周期是由定时器时钟频率和预装载值两者决定的,预装载值就是ARR。   ; J4 {. X3 d+ r6 `" `
2 O, _* j2 r6 Y6 ?2 |  C  n

$ n0 F( j: y  R: E- f) _& h" q 预装载值PSC设置为899,那么,当定时器的当前值val从0增加到899时,一共经过了900个时钟周期,这900个时钟周期会产生一个PWM波形,也就是说900个定时器时钟周期才相当于一个PWM周期,那么PWM的频率就为72MHz/900=80KHz,周期为1/80KHz。5 f4 j: p- g) X
5 B6 W2 J$ m8 [) C

( z+ ^( h$ n! c, h: I' r
赞 收藏 评论0 发布时间:2023-9-21 15:15

举报

0个回答

所属标签

相似技术帖

官网相关资源

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