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

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

[复制链接]
攻城狮Melo 发布时间:2023-9-21 15:15
PWM控制电机速度的基本原理    PWM(Pulse Width Modulation),也就是脉冲宽度调制。
2 w- k' a  |7 e
    PWM中有一个比较重要的概念,占空比:是一个脉冲周期内有效电平在整个周期所占的比例。    为了实现IO口上电压的持续性变化,可以调节PWM的占空比。这也能够使外设的功率进行持续性变化,最终控制直流电机转速的快慢。如何调节PWM波形的输出就是重点。) {! Z0 m8 B4 R- b2 }" I  R1 d
1 U1 X- d- F  w/ C/ v% J
微信图片_20230921151526.png
8 X5 T' I* T" u
. A4 @& i/ J. Y6 Q2 K9 ]* a8 `4 @
8 V% n5 C5 f: S( c  v) E
6 G& S4 o0 e- S" y

7 @& w6 \9 d; e. S- |0 n7 s. M   上图中的ARR是我们给定时器的一个预装载值,CCRx的上下变化是产生PWM波的关键。我们假设ARR大于CCRx的部分输出为高电平(即t1-t2、t3-t4、t5-t6),ARR小于CCRx的部分输出为低电平(即0-t1、t2-t3、t4-t5),则改变CCRx的值就能改变输出PWM的占空比。因此,想要控制PWM的输出波形,重要的就是如何设置ARR与CCRx这两个寄存器的值了。
" J* i3 a% c6 F' Q8 x9 a5 w  l- o5 [) e6 F' U/ k$ l" \! \
) m( t% [5 t, ?! G" X, M
STM32定时器中断    * T5 O! W- Y& D( z' E4 n$ `
为了便于理解接下来关于PWM应用的内容,先插一段定时器中断的知识。    产生定时中断是定时器的用法之一,与定时器用来进行PWM输出和输入捕获相比,定时器中断更容易理解、掌握。) x2 k$ R; q2 n

( Q' q/ v' A5 D3 Y: y

- `# T+ I: l1 u9 q% `2 G5 {  J原理简介    4 `0 e+ B4 I+ t
使用通用定时器进行中断的原理,其实和开发板Systick定时器进行中断延时很相似(Stm32入门——Systick定时器),即:用psc(预分频系数)设置好定时器时钟后,arr(预装载值)在每个时钟周期内减1,当arr减为0时触发中断然后进入中断处理程序进行中断处理。以下代码为例:
$ q3 ]# {, K9 x9 A
% D+ n! [5 z4 b" Z2 k, H2 \. [

: w1 v- M3 s- i8 |$ {/ b) q 微信图片_20230921151520.png
' p/ @$ x- Q' H$ r* G- V* E3 I% X
! h0 C; |$ c6 G( J

6 B) l) A: B# L    解释一下上面这行代码,由于定时器3(TIM3)是挂在APB1上的外设,所以要打开APB1,这里的预分频器值psc是来设置TIM3的时钟频率的,如果系统时钟(SYSTICK)频率为72MHz、psc为7199,则TIM3的时钟频率就为:
7 A# R7 }3 @* C; O# L2 D/ w; t* {1 x' W, c1 z& U0 O8 u

5 B2 w, G, u# M8 l& m: e" d 微信图片_20230921151516.png
9 M( b* q( f, |2 [+ m# C! V; ~& {' _- [6 s" t; |& n/ N7 x( p
$ R  \# \  g  W% @4 V( f
    10KHz是什 么意思呢?就是一秒钟会产生10K个周期,那么一个周期的时间长度就是1/10KHz,如果你想将定时器中断的时间间隔设置为0.5秒,那么你将arr设置为5000即可,因为arr每减1就需要一个周期的时间,减5000次就经过了5000*(1/10KHz)=0.5秒。
6 b2 h9 r+ E" q; i1 }4 r& _& r5 f* C  s

( H! S1 V; G) c/ F! U) o 微信图片_20230921151511.png
$ I' u2 [, u6 K$ a1 Y8 u% D" {/ b: ?$ Q

5 ^- P- O7 z) ]5 H' w- Y) j- S- O+ ?    再解释下上面这一行,设置允许更新中断,即arr减到0以后可以触发更新中断,还有其他类型的中断。
; A) P& L9 g: W3 Y' ]  [% J8 ]" ^; F9 F4 h' `- b5 v) w

! q- j/ h$ y& P% T) |& Y# j 微信图片_20230921151506.png ! L2 q1 G5 B  L' [
  j/ |5 B8 u9 K  ?! B. A$ t3 g1 `
$ I% R6 B+ [2 q  r; m
    看上面这行代码,中断优先级有抢占优先级和响应(即子优先级)优先级两种,抢占优先级即:若程序1正在使用CPU,这时如果程序2要求使用CPU,并且程序2的抢占优先级高,则CPU被程序2抢占;若两者抢占优先级相同,则就算程序2的响应优先级高于程序1,CPU也不能被抢占;若程序1正在使用CPU,程序2和程序3的抢占优先级等于或低于程序1,且程序2的响应优先级高于程序三,则待CPU空出后,程序2先运行,程序3最后运行。TIM3_IRQn是指定将要运行的中断处理程序号。“组2”是设置中断优先级分组的,这是因为寄存器提供了四位来设置优先级,组2代表的是前两位给抢占优先级,后两位给响应优先级。
$ j& r0 X& [; W; s- R; g% s( y7 a# b+ h; }$ `9 H1 u: \$ L) K4 T
PWM模式、有效电平   . H% k9 t/ u; f$ ]5 ]' [, Z% I
前面介绍完中断,再说一下PWM工作原理。    假设上图中ARR大于CCRx时输出为高电平,ARR小于CCRx时输出为低电平,但在实际运用中可能并非如此,有可能是相反的情况——ARR大于CCRx时输出为低电平,ARR小于CCRx时输出为高电平,至于到底是哪种情况,还要看PWM是哪种模式、有效电平又设置的是何种极性了。
  • 模式1:ARR小于CCRx时输出为“有效”电平,ARR大于CCRx时输出为“无效”电平。
    " Y8 e9 W5 v6 z# g. |
  • 模式2:ARR小于CCRx时输出为“无效”电平,ARR大于CCRx时输出为“有效”电平。8 C/ s3 I8 ]7 X9 w0 i4 f: W
    这里说的是“有效”和“无效”,而不是“高”和“低”,也就是说有效电平可高可低,并非一定就是高电平。PWM模式、效电平极性,需要程序员自己配置相关的寄存器来实现。通过下面的代码来讲解。3 d- S4 b: ~- q& ?" T
  J9 ]9 x& h1 @% \1 G

% @7 x$ }/ I& w; G/ c3 g 微信图片_20230921151503.png 2 ]4 r( D5 `5 O/ H( i0 \

9 Q: d) w1 F: [6 x6 ^- Z

7 w* }+ H6 D7 U; @4 m- ~    上一小节讲过关于定时器参数的设置。使用定时器1的通道1来输出一路PWM波,这里的899设置的就是ARR的值,至于那个0是用来设置TIM1的频率的,不分频就代表TIM1的时钟频率和系统时钟相同,这里假设为72MHz。
& I/ }. l. A# s! u/ g
4 c) W4 e, D$ E5 m  p+ L

; q# j" c. k1 i/ c) _' v1 a, I* m7 P 微信图片_20230921151459.png
( K  E3 o: L& m  L9 u+ _5 r8 Q  m# ]7 ^) u3 P& X7 w
% A. o% r, }2 {3 X1 v; Y
    下文具体分析上面的代码。' p7 D; z  {7 m* U' P& |2 n5 G
    前面4-6行是用来配置GPIO口的。7 ~" @1 @* x8 ^7 E

! r1 I1 c* h; D" L7 u2 t2 Y+ T
$ g1 m2 A6 c; P0 \4 h& f# ~
微信图片_20230921151456.png 9 f$ S$ S; D, T
" c9 o9 O: G' H, B+ s" n5 |

9 {( P' r9 ]& S# f) g/ k0 b    这两行就是我上门提到的设置定时器的频率和重装载值。
% k6 y- C$ ^" o6 r
# m4 y7 }2 f$ u' K
: `8 X6 ~0 S9 `+ T: r" f" {9 y2 L3 v
微信图片_20230921151452.png   q* q0 h) T; J6 z. O
& K6 G2 f" O8 g9 r

& ~( b4 @  s) b6 }7 n& p0 d    这三行是用来设置PWM输出模式和设置通道的,通道是什么呢?简单地讲就是输出PWM波的GPIO口,代码一开始不是设置了PA8这个GPIO口嘛,这个PA8就是通道1。使用通道的话要先进行输入输出方向、通道使能的设置。: U. e+ t4 L$ F

, ?: ~# V7 h+ y# ?, b; h  U2 s

6 C7 a) `& g5 i2 l+ ] 微信图片_20230921151449.png
1 M- l  ?0 _9 m: q6 _+ K) {) F6 ?7 D  B. }

" _; a% l2 N* x* x    这行代码是用来设置“有效电平”极性的,根据手册,当TIM1->CCER[1]这位置1时,有效电平为低电平,置0时有效电平为高电平,而默认情况下置0。
# R8 o' M) o# X* C6 j
. b" X8 n% M8 J* Q+ f1 ?* A
+ N& v( c- X3 R' A
微信图片_20230921151446.png
+ H3 h1 B5 J' a  p2 I- T) Y& H! Y+ Y9 |% e

+ l" ~7 W! _0 c* h, I: L& y    这行代码只要对高级定时器进行设置,普通定时器无需设置。% S6 v* ^( W/ t* F+ V: m
. |: y, I% K7 W
. Q5 p0 j! _: e! M, o9 ~: i+ K
微信图片_20230921151442.png 5 M8 P  c! R& Q

( c' f3 H$ j; n) D/ y- K2 O" t

) ~; h3 c2 Q$ H6 \: l+ k    这行代码是用来使能ARPE,ARPE是什么呢,就是当它被置1时,你自己设置的CCRx会立即生效,如果它被置为0,那么你自己设置的CCRx值不会立即生效(可能之前ARPE已经有值了),而是当之前设置的CCRx生效后才会使用你最新设置的CCRx值。
- V) ~3 D: d" u" j' A' r
4 S; N4 e9 R1 K) d
上面的代码里没有对CCRx进行设置,这是因为CCRx常常是一个变化的值,你可以在主函数中用一个for循环+if判断语句对它进行++或–的操作,从而达到连续改变CCRx值得目的,例如:' l% R; u* X( I5 [' @( Z1 i: r
) H- l+ }! Q- N  S, S
! O. r3 }, ]- n  J6 X: I
微信图片_20230921151438.png
. L& P- }! E; v1 g- Q
. _2 J$ [3 j0 W5 d- v3 a  E0 }
& q+ U. ]" X. m5 J  T
    PWM波的周期是由定时器时钟频率和预装载值两者决定的,预装载值就是ARR。   
. ~$ @% P9 Y" _
3 ~- d; D( X2 S

5 Q1 n+ t5 A4 I7 q& B! `, E5 N 预装载值PSC设置为899,那么,当定时器的当前值val从0增加到899时,一共经过了900个时钟周期,这900个时钟周期会产生一个PWM波形,也就是说900个定时器时钟周期才相当于一个PWM周期,那么PWM的频率就为72MHz/900=80KHz,周期为1/80KHz。0 `+ K1 A2 v( ?$ q7 b. H0 m$ |
' @. x7 u9 Q+ S" f( S- t6 m8 ~$ W0 {

( K  Y! T4 c9 Y6 E
收藏 评论0 发布时间:2023-9-21 15:15

举报

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