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

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

[复制链接]
攻城狮Melo 发布时间:2023-9-21 15:15
PWM控制电机速度的基本原理    PWM(Pulse Width Modulation),也就是脉冲宽度调制。! |! @2 B& l; Z0 {
    PWM中有一个比较重要的概念,占空比:是一个脉冲周期内有效电平在整个周期所占的比例。    为了实现IO口上电压的持续性变化,可以调节PWM的占空比。这也能够使外设的功率进行持续性变化,最终控制直流电机转速的快慢。如何调节PWM波形的输出就是重点。  [) G+ F$ M7 f& |) i/ w$ t  A
) K( Z: P/ ]% c! E$ }
微信图片_20230921151526.png + S! C3 r+ B5 K- _
* y1 G7 u; M' x$ A/ b( D) A
) L( [) b* @- y8 u* h% F. y: ^% y$ ~
3 e" ]3 s6 l8 G( |2 y; M

+ G. }8 h9 M0 B1 r: a   上图中的ARR是我们给定时器的一个预装载值,CCRx的上下变化是产生PWM波的关键。我们假设ARR大于CCRx的部分输出为高电平(即t1-t2、t3-t4、t5-t6),ARR小于CCRx的部分输出为低电平(即0-t1、t2-t3、t4-t5),则改变CCRx的值就能改变输出PWM的占空比。因此,想要控制PWM的输出波形,重要的就是如何设置ARR与CCRx这两个寄存器的值了。! B7 w$ A9 f! R3 y5 u  \0 `# F" {
6 T0 c, i1 {. G; ?$ a& c

7 n( Q  q4 H! qSTM32定时器中断    , m9 t: e6 s. I6 ^7 o" O' B
为了便于理解接下来关于PWM应用的内容,先插一段定时器中断的知识。    产生定时中断是定时器的用法之一,与定时器用来进行PWM输出和输入捕获相比,定时器中断更容易理解、掌握。( D; p$ f7 @3 X- \" k1 V
8 _6 ?2 d# x+ S$ m" W, g; {# e5 |5 m9 N

( D# v8 C) F" M原理简介    + R2 `+ X" |& p  s9 b
使用通用定时器进行中断的原理,其实和开发板Systick定时器进行中断延时很相似(Stm32入门——Systick定时器),即:用psc(预分频系数)设置好定时器时钟后,arr(预装载值)在每个时钟周期内减1,当arr减为0时触发中断然后进入中断处理程序进行中断处理。以下代码为例:8 g( m) i- G- P0 L2 x

4 M8 b5 o2 w: M. D# M9 _

) B9 _: e- n* H  X5 R2 L 微信图片_20230921151520.png - F% l- ^! O0 R3 E
9 }& r$ U6 a) u, W: Q8 t

. b) N) f0 g" M6 Y4 \4 I    解释一下上面这行代码,由于定时器3(TIM3)是挂在APB1上的外设,所以要打开APB1,这里的预分频器值psc是来设置TIM3的时钟频率的,如果系统时钟(SYSTICK)频率为72MHz、psc为7199,则TIM3的时钟频率就为:
+ e! l8 C% ]/ q& u7 o$ E) A2 o$ a0 u7 k# A0 A% G. b! M; P% c
/ j- F' g& ?4 D5 k& x, r; D/ ^  d
微信图片_20230921151516.png # j) y4 T1 `* s1 u. W, K. H

# r1 B' d- m% ^! a, c' f, m

/ U7 ]2 B' E. |, N; ~, S    10KHz是什 么意思呢?就是一秒钟会产生10K个周期,那么一个周期的时间长度就是1/10KHz,如果你想将定时器中断的时间间隔设置为0.5秒,那么你将arr设置为5000即可,因为arr每减1就需要一个周期的时间,减5000次就经过了5000*(1/10KHz)=0.5秒。
. {% @& }% Y3 F6 e/ ]' O2 {2 r% ]; C. ^+ Q& v+ P" A

3 b3 N! O& |1 _; s5 ~0 G6 i 微信图片_20230921151511.png
- J" z8 D' G, i
) q# [. B# \: P9 B0 b) o

' U3 A5 V2 U3 ?    再解释下上面这一行,设置允许更新中断,即arr减到0以后可以触发更新中断,还有其他类型的中断。- c4 K/ `. W6 u3 M- o, A3 H& f  ]/ _0 m
- Z4 r* H- }4 Z) b& L
; g. R! @, f# `# v+ S% f
微信图片_20230921151506.png 2 K6 K, ?+ V; q% |& `* X

1 B) |2 m; x3 X2 K4 p; O
, `6 w, H5 ?* {& N  k% e. N7 y
    看上面这行代码,中断优先级有抢占优先级和响应(即子优先级)优先级两种,抢占优先级即:若程序1正在使用CPU,这时如果程序2要求使用CPU,并且程序2的抢占优先级高,则CPU被程序2抢占;若两者抢占优先级相同,则就算程序2的响应优先级高于程序1,CPU也不能被抢占;若程序1正在使用CPU,程序2和程序3的抢占优先级等于或低于程序1,且程序2的响应优先级高于程序三,则待CPU空出后,程序2先运行,程序3最后运行。TIM3_IRQn是指定将要运行的中断处理程序号。“组2”是设置中断优先级分组的,这是因为寄存器提供了四位来设置优先级,组2代表的是前两位给抢占优先级,后两位给响应优先级。! F; b( D! K' C( f2 C( T# c( B

; u9 l9 j4 @( I. i1 l. rPWM模式、有效电平   
- X# L, Q4 T5 h/ Y7 F$ k前面介绍完中断,再说一下PWM工作原理。    假设上图中ARR大于CCRx时输出为高电平,ARR小于CCRx时输出为低电平,但在实际运用中可能并非如此,有可能是相反的情况——ARR大于CCRx时输出为低电平,ARR小于CCRx时输出为高电平,至于到底是哪种情况,还要看PWM是哪种模式、有效电平又设置的是何种极性了。
  • 模式1:ARR小于CCRx时输出为“有效”电平,ARR大于CCRx时输出为“无效”电平。# T) P" _% L  t1 d7 S, ?2 H! l
  • 模式2:ARR小于CCRx时输出为“无效”电平,ARR大于CCRx时输出为“有效”电平。' w9 S' C6 v1 g5 ~% n
    这里说的是“有效”和“无效”,而不是“高”和“低”,也就是说有效电平可高可低,并非一定就是高电平。PWM模式、效电平极性,需要程序员自己配置相关的寄存器来实现。通过下面的代码来讲解。
' S; ?- F' B: q3 P& N/ s) E3 ~# F' T. h( I, \
2 M& {8 k1 w" V/ O( Z% p7 }$ r( N
微信图片_20230921151503.png
- N* ?) ]( |& Q! X8 M9 A, t8 s- F' O: F! M" n9 J2 s
, [. Z$ L- m$ ]/ a% r1 a
    上一小节讲过关于定时器参数的设置。使用定时器1的通道1来输出一路PWM波,这里的899设置的就是ARR的值,至于那个0是用来设置TIM1的频率的,不分频就代表TIM1的时钟频率和系统时钟相同,这里假设为72MHz。
, ^, ~( M9 D+ i$ K# _

) n# k5 c. }5 S" F

7 ~9 M) t) a' G5 a 微信图片_20230921151459.png
$ _7 \& ^6 ~* k2 s0 Y" f% Q1 a9 R7 T) e8 p- ]) o- \

. e  T' D4 j; b( m; _4 v9 j/ t    下文具体分析上面的代码。
3 {& v. v# [4 [6 S4 m/ n
    前面4-6行是用来配置GPIO口的。
' Y9 q0 h1 S4 Y  I3 o; V
& I) J9 T5 d- H$ X# q9 b
* A# [$ J5 }6 G
微信图片_20230921151456.png
2 Z5 ]# v9 C- [# T1 t. V9 b' i' N! r1 t" k/ F3 I1 \6 G) L
8 C- a* L( j: i+ y" Z
    这两行就是我上门提到的设置定时器的频率和重装载值。
; P& q, n# x( Y7 e5 p! `3 U2 _8 V
% o& T- k) K. x7 Q

+ ?2 t( B9 L- n, w 微信图片_20230921151452.png
! Z; N3 @# @' ?* d
5 U5 W! |$ J) m  P

3 a4 E- e2 y9 N/ o0 k2 y$ p    这三行是用来设置PWM输出模式和设置通道的,通道是什么呢?简单地讲就是输出PWM波的GPIO口,代码一开始不是设置了PA8这个GPIO口嘛,这个PA8就是通道1。使用通道的话要先进行输入输出方向、通道使能的设置。
: s2 `  A8 p1 c7 E
5 d4 P; [8 w% |1 c
  S) C. f" }# p6 E! q9 z
微信图片_20230921151449.png
1 q# H* r, w, o6 {: w2 K  d5 n$ V
' \( U% b0 [# a1 [
1 a& Y! _, L; x- z% T
    这行代码是用来设置“有效电平”极性的,根据手册,当TIM1->CCER[1]这位置1时,有效电平为低电平,置0时有效电平为高电平,而默认情况下置0。
/ ~, W& J* U/ G: }* F

7 l, U* @4 x1 V( |

2 V, ~1 K1 W, s4 U6 c 微信图片_20230921151446.png - f1 J4 z+ _5 r# K  ~, D( `

4 L& o# J0 b! Z% ]$ m

# r2 S: W9 w0 D$ ?+ o) i( y# f    这行代码只要对高级定时器进行设置,普通定时器无需设置。3 F; \" h0 b- x

1 V; V! p. y) F: y8 j3 r( }
# L) i! C- B- G6 y0 F1 ^4 U2 _
微信图片_20230921151442.png 4 z! ?" p* z& V7 M
, r1 T* T, o4 j. M7 }6 S6 m* j

0 s0 t; W, {8 R! c) c+ t1 H    这行代码是用来使能ARPE,ARPE是什么呢,就是当它被置1时,你自己设置的CCRx会立即生效,如果它被置为0,那么你自己设置的CCRx值不会立即生效(可能之前ARPE已经有值了),而是当之前设置的CCRx生效后才会使用你最新设置的CCRx值。
! W5 m7 \0 B! @. ~; \
  z) F9 R* X; I4 _. d, f8 q0 J7 ~
上面的代码里没有对CCRx进行设置,这是因为CCRx常常是一个变化的值,你可以在主函数中用一个for循环+if判断语句对它进行++或–的操作,从而达到连续改变CCRx值得目的,例如:
, x$ O3 b5 E) M" J
1 @" [) k9 k0 b- m& @5 u
7 s8 r8 t) A( m% g) R
微信图片_20230921151438.png
, m$ {' q5 F  p& w; ?4 W% R& ^4 J/ |/ g2 ^
5 Q  \- C: L. K- s- M( ~) ~  ~
    PWM波的周期是由定时器时钟频率和预装载值两者决定的,预装载值就是ARR。   
( A! z- a# A3 P  V/ k# q1 \( t- g
' y# E. o- @' E8 R2 K# t  y! q

: P; ^4 H7 y& `* ^2 D* E 预装载值PSC设置为899,那么,当定时器的当前值val从0增加到899时,一共经过了900个时钟周期,这900个时钟周期会产生一个PWM波形,也就是说900个定时器时钟周期才相当于一个PWM周期,那么PWM的频率就为72MHz/900=80KHz,周期为1/80KHz。
0 O$ R. @$ C) M
/ W/ x3 O7 {- r+ K+ s2 i
+ t3 ?5 d) u6 O$ i8 N
收藏 评论0 发布时间:2023-9-21 15:15

举报

0个回答

所属标签

相似技术帖

官网相关资源

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