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

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

[复制链接]
攻城狮Melo 发布时间:2023-9-21 15:15
PWM控制电机速度的基本原理    PWM(Pulse Width Modulation),也就是脉冲宽度调制。& @0 k9 o% E3 _7 B; s, d1 T4 Q2 P  {
    PWM中有一个比较重要的概念,占空比:是一个脉冲周期内有效电平在整个周期所占的比例。    为了实现IO口上电压的持续性变化,可以调节PWM的占空比。这也能够使外设的功率进行持续性变化,最终控制直流电机转速的快慢。如何调节PWM波形的输出就是重点。/ _4 X; s! J  H1 \

7 }- k# l* T3 p& _1 z* v0 D 微信图片_20230921151526.png
, J1 G# c) z9 @6 X
0 S% O1 b& C& s( t% ~

/ d) E  X! o5 E6 r$ E$ w. }0 J0 J- J) z, v8 i6 l- \9 i
' k- F9 \; C1 t
   上图中的ARR是我们给定时器的一个预装载值,CCRx的上下变化是产生PWM波的关键。我们假设ARR大于CCRx的部分输出为高电平(即t1-t2、t3-t4、t5-t6),ARR小于CCRx的部分输出为低电平(即0-t1、t2-t3、t4-t5),则改变CCRx的值就能改变输出PWM的占空比。因此,想要控制PWM的输出波形,重要的就是如何设置ARR与CCRx这两个寄存器的值了。
( A5 P. w. J' _9 T8 G9 G: [) j( ?# z4 x8 y

0 @4 P! U8 K# e8 p! ]STM32定时器中断   
+ D! ^, ^  B" b9 L6 G  b: ~为了便于理解接下来关于PWM应用的内容,先插一段定时器中断的知识。    产生定时中断是定时器的用法之一,与定时器用来进行PWM输出和输入捕获相比,定时器中断更容易理解、掌握。
( t4 U) |, q5 I  c+ Z- _1 i! j) H' M' m3 w: J$ O) A" j% j

4 H% ?* M& }4 @原理简介    / I  |* _" ?: T/ X
使用通用定时器进行中断的原理,其实和开发板Systick定时器进行中断延时很相似(Stm32入门——Systick定时器),即:用psc(预分频系数)设置好定时器时钟后,arr(预装载值)在每个时钟周期内减1,当arr减为0时触发中断然后进入中断处理程序进行中断处理。以下代码为例:
" E: I& f0 a) p- q, U% j0 I7 H* ]7 M; b+ a0 B- b9 M
) L9 S* J+ r6 _7 X- y
微信图片_20230921151520.png
* [' |1 w  @* N8 w# ~, Y, c! `
" o$ m2 \4 V1 n8 n/ l
7 G% S8 ?/ P/ k0 `- u6 d2 D
    解释一下上面这行代码,由于定时器3(TIM3)是挂在APB1上的外设,所以要打开APB1,这里的预分频器值psc是来设置TIM3的时钟频率的,如果系统时钟(SYSTICK)频率为72MHz、psc为7199,则TIM3的时钟频率就为:
9 r, Y! K/ T& x. ]" u6 t" Z$ w
. f9 ?; G" M  C  V% y$ y
$ \4 a: y( }, [: w! q
微信图片_20230921151516.png   \$ |6 `5 H$ e  h# t: C

% C2 E3 z% I  @$ b) O
/ v' v) g5 E/ I+ T" A5 B9 G
    10KHz是什 么意思呢?就是一秒钟会产生10K个周期,那么一个周期的时间长度就是1/10KHz,如果你想将定时器中断的时间间隔设置为0.5秒,那么你将arr设置为5000即可,因为arr每减1就需要一个周期的时间,减5000次就经过了5000*(1/10KHz)=0.5秒。
3 S( I# x! q/ m3 J1 M2 a# `% v1 d0 K: |; ^: r& [! h) m- G
( s& n$ |- e+ {. |
微信图片_20230921151511.png
8 E# v. g. ^. E! T+ t6 W3 M" z  _' w" w. ~7 i# @

: Z% P) U/ I! x8 J; C    再解释下上面这一行,设置允许更新中断,即arr减到0以后可以触发更新中断,还有其他类型的中断。5 C0 o, e9 s% ~0 c) n8 j; L( P
6 p1 s& J' f, d# n
) V+ C$ j8 ?, y% ^- L
微信图片_20230921151506.png 0 I  N- R! x3 V% w3 c( z

. K8 \0 Y6 r- h. n5 T9 h: ~' H; M2 L

% _* `- N" i1 \" F) N    看上面这行代码,中断优先级有抢占优先级和响应(即子优先级)优先级两种,抢占优先级即:若程序1正在使用CPU,这时如果程序2要求使用CPU,并且程序2的抢占优先级高,则CPU被程序2抢占;若两者抢占优先级相同,则就算程序2的响应优先级高于程序1,CPU也不能被抢占;若程序1正在使用CPU,程序2和程序3的抢占优先级等于或低于程序1,且程序2的响应优先级高于程序三,则待CPU空出后,程序2先运行,程序3最后运行。TIM3_IRQn是指定将要运行的中断处理程序号。“组2”是设置中断优先级分组的,这是因为寄存器提供了四位来设置优先级,组2代表的是前两位给抢占优先级,后两位给响应优先级。
) J: T: c. ?! r/ D3 Q( G, z" @7 m+ Q9 p% [! t' _; E
PWM模式、有效电平   
: S. }# l6 U) _8 |; ~% |前面介绍完中断,再说一下PWM工作原理。    假设上图中ARR大于CCRx时输出为高电平,ARR小于CCRx时输出为低电平,但在实际运用中可能并非如此,有可能是相反的情况——ARR大于CCRx时输出为低电平,ARR小于CCRx时输出为高电平,至于到底是哪种情况,还要看PWM是哪种模式、有效电平又设置的是何种极性了。
  • 模式1:ARR小于CCRx时输出为“有效”电平,ARR大于CCRx时输出为“无效”电平。  y' w$ n9 B2 ^$ I
  • 模式2:ARR小于CCRx时输出为“无效”电平,ARR大于CCRx时输出为“有效”电平。
    ) y! P* A8 |  }! g0 @
    这里说的是“有效”和“无效”,而不是“高”和“低”,也就是说有效电平可高可低,并非一定就是高电平。PWM模式、效电平极性,需要程序员自己配置相关的寄存器来实现。通过下面的代码来讲解。( d/ C3 v# n6 |" N: W, `/ K

9 e7 j7 d. G6 u! a

5 @0 J: u/ I& p! k9 F 微信图片_20230921151503.png
0 N  V# D8 M0 M; C7 z, O2 [' ]- ]- b8 S. Z" C9 ?

9 `3 |- U* A/ B. U% Y* q    上一小节讲过关于定时器参数的设置。使用定时器1的通道1来输出一路PWM波,这里的899设置的就是ARR的值,至于那个0是用来设置TIM1的频率的,不分频就代表TIM1的时钟频率和系统时钟相同,这里假设为72MHz。# @* Z( s8 T$ T& r$ \
+ R7 L; R; |' `# w& I5 H3 u

* r. t, s# Z4 Z% [5 k% H 微信图片_20230921151459.png
) \3 m+ Y' G: ^
" y5 E& d' P0 d8 l  ^! d

0 D4 F& m0 d$ k. P; e    下文具体分析上面的代码。  [$ ^$ t& }& w' Q8 F
    前面4-6行是用来配置GPIO口的。
& W: Y$ c: _' q+ w6 ], E# b
6 `' }: Q4 ^) Q% X2 q3 ]

2 l1 Y  ]$ G+ V& C& {' a; A) O 微信图片_20230921151456.png 0 Q. T, A) h, W* _' \6 K3 y3 Z
: i) R& S( G4 g9 i8 J4 i2 J) W+ I0 Z
7 w# x+ E+ p$ |8 C8 k- g: o
    这两行就是我上门提到的设置定时器的频率和重装载值。
! X: g7 E1 p% K/ Q/ {' `
5 u( z, n9 Z3 w4 Z/ M
6 k7 t5 }6 d2 P3 u2 v5 l; K
微信图片_20230921151452.png
/ O1 j3 e, b# ~6 y. E0 M8 v$ Y4 B  r& o$ q. }8 k
7 B! |/ v- H1 V& ~& F. k' D* S
    这三行是用来设置PWM输出模式和设置通道的,通道是什么呢?简单地讲就是输出PWM波的GPIO口,代码一开始不是设置了PA8这个GPIO口嘛,这个PA8就是通道1。使用通道的话要先进行输入输出方向、通道使能的设置。; E2 K: U- X# w
  B6 L+ [+ e' ?  |/ L6 Z, }
/ G6 M! V( m% c# U; J! W
微信图片_20230921151449.png
1 U3 q# C; Q. @! _4 q6 Y+ c  ~+ l4 u4 D
! l# v" U2 {1 ?9 b  j, K

; o5 {) m9 w+ e: C' T7 b7 K7 I    这行代码是用来设置“有效电平”极性的,根据手册,当TIM1->CCER[1]这位置1时,有效电平为低电平,置0时有效电平为高电平,而默认情况下置0。1 f! p3 V3 r5 {2 Q4 B! ?
3 n% N4 U. h% Q0 k7 j. p  Y

4 }, h. w, d  K- F1 T  ]5 ` 微信图片_20230921151446.png
% {" X2 h1 `3 \( b* S8 O  t$ n* G. H% J* m. s' ]

6 ?& a' s# E1 s' X7 y% w3 [$ j0 e8 m    这行代码只要对高级定时器进行设置,普通定时器无需设置。1 Q& C5 b% P* ?  ?7 U' Q' y4 {
" b4 B. \! A; T( k0 H  \

- Q; s; Y4 e( M 微信图片_20230921151442.png
- B) P  L9 n( a* \9 t! e, S- d0 b0 N; L- X& k* D, I- x

# A0 ^" e3 m! y4 [( P8 w' a3 m    这行代码是用来使能ARPE,ARPE是什么呢,就是当它被置1时,你自己设置的CCRx会立即生效,如果它被置为0,那么你自己设置的CCRx值不会立即生效(可能之前ARPE已经有值了),而是当之前设置的CCRx生效后才会使用你最新设置的CCRx值。
( z( T! c. [4 n) ?3 i! Q) g4 ?" D" u# w" I
上面的代码里没有对CCRx进行设置,这是因为CCRx常常是一个变化的值,你可以在主函数中用一个for循环+if判断语句对它进行++或–的操作,从而达到连续改变CCRx值得目的,例如:
; [* \. v% q1 E' j# X/ s9 s6 `. ?0 ]8 z" I

& l4 I9 F; I4 e; n4 F2 X 微信图片_20230921151438.png , a, A0 [" z( Z0 V
+ u3 r* L, z9 s7 c
0 O8 P) A1 v+ x7 \
    PWM波的周期是由定时器时钟频率和预装载值两者决定的,预装载值就是ARR。   
1 @, Y% A# f0 j  H
$ O% q0 H5 Z+ \9 M6 [+ h7 M/ r
. q3 b8 n, B: x! u* Z8 X: Q
预装载值PSC设置为899,那么,当定时器的当前值val从0增加到899时,一共经过了900个时钟周期,这900个时钟周期会产生一个PWM波形,也就是说900个定时器时钟周期才相当于一个PWM周期,那么PWM的频率就为72MHz/900=80KHz,周期为1/80KHz。
" X2 w: ^) m1 U# D' `9 @4 l6 U9 y* x8 r  z) x1 {( T# I! ~) d

0 D6 W1 e& |0 ]0 k8 M5 q% {
收藏 评论0 发布时间:2023-9-21 15:15

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版