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

STM32通过PWM控制电机速度

[复制链接]
STMCU小助手 发布时间:2022-11-2 22:21
做STM32智能小车的实验中会用到定时器PWM输出,来改变直流电机的转速。分享本文了解如何通过PWM实现对电机速度的控制。1 \8 A" D1 e1 Y. m

' G' S8 F7 m- @( p7 c/ ^
PWM控制电机速度的基本原理
    PWM(Pulse Width Modulation),也就是脉冲宽度调制。
0 f" n& d9 X% @3 A& }. h. Q! h
    PWM中有一个比较重要的概念,占空比:是一个脉冲周期内有效电平在整个周期所占的比例。
    为了实现IO口上电压的持续性变化,可以调节PWM的占空比。这也能够使外设的功率进行持续性变化,最终控制直流电机转速的快慢。如何调节PWM波形的输出就是重点。

; a9 ]7 U8 n5 C
微信图片_20221102222120.png
6 _4 C: E5 @  m) x. Z/ `  F8 ~. n
   上图中的ARR是我们给定时器的一个预装载值,CCRx的上下变化是产生PWM波的关键。我们假设ARR大于CCRx的部分输出为高电平(即t1-t2、t3-t4、t5-t6),ARR小于CCRx的部分输出为低电平(即0-t1、t2-t3、t4-t5),则改变CCRx的值就能改变输出PWM的占空比。因此,想要控制PWM的输出波形,重要的就是如何设置ARR与CCRx这两个寄存器的值了。
7 o- |0 q8 w0 l6 \" G4 v* S, w
STM32定时器中断
    为了便于理解接下来关于PWM应用的内容,先插一段定时器中断的知识。
    产生定时中断是定时器的用法之一,与定时器用来进行PWM输出和输入捕获相比,定时器中断更容易理解、掌握。
  A7 c: Y/ d5 Z" k+ ]
原理简介$ ~2 K1 P. a, E: M0 M, B2 R
    使用通用定时器进行中断的原理,其实和开发板Systick定时器进行中断延时很相似(Stm32入门——Systick定时器),即:用psc(预分频系数)设置好定时器时钟后,arr(预装载值)在每个时钟周期内减1,当arr减为0时触发中断然后进入中断处理程序进行中断处理。以下代码为例:
  1. void TIM3_Int_Init(u16 arr,u16 psc)
    , K' I; b2 F0 H4 b$ h: `* e# q
  2. {5 x3 n' Y, i* N
  3.   RCC->APB1ENR|=1<<1;  //TIM3时钟使能   
    1 [  m3 k$ ~! [1 T& p( H
  4.    TIM3->ARR=arr;    //设定计数器自动重装值
    & _2 m' h0 n1 K, L' y" h7 ^
  5.   TIM3->PSC=psc;    //预分频器设置% Q& v& m1 B- N( \! H1 g
  6.   TIM3->DIER|=1<<0;   //允许更新中断        
    " ?" P! n( _. j. D7 N; u
  7.   TIM3->CR1|=0x01;    //使能定时器3
    1 U" Q  g  A6 o" ?* Y+ }: d6 l0 S
  8.     MY_NVIC_Init(1,3,TIM3_IRQn,2);//抢占1,子优先级3,组2                  
    & m8 g# J. C; C0 P. G2 S' I
  9. }
复制代码
  1. RCC->APB1ENR|=1<<1
复制代码

' }; `" s: h( A' s
    解释一下上面这行代码,由于定时器3(TIM3)是挂在APB1上的外设,所以要打开APB1,这里的预分频器值psc是来设置TIM3的时钟频率的,如果系统时钟(SYSTICK)频率为72MHz、psc为7199,则TIM3的时钟频率就为:
  1. 72MHz/(7199+1)Hz = 10KHz    //这里的“+1”是手册中规定的。
复制代码
! A0 H0 r& Z8 U' H: M4 B; a) _, S! `
    10KHz是什 么意思呢?就是一秒钟会产生10K个周期,那么一个周期的时间长度就是1/10KHz,如果你想将定时器中断的时间间隔设置为0.5秒,那么你将arr设置为5000即可,因为arr每减1就需要一个周期的时间,减5000次就经过了5000*(1/10KHz)=0.5秒。
  1. TIM3->DIER|=1<<0
复制代码

* |% w7 [" f5 s7 D7 g8 |) `  g( ]
    再解释下上面这一行,设置允许更新中断,即arr减到0以后可以触发更新中断,还有其他类型的中断。
  1. MY_NVIC_Init(1,3,TIM3_IRQn,2);//抢占1,子优先级3,组2
复制代码
# Y# C* g, Y6 g5 m  r: G$ h0 `
    看上面这行代码,中断优先级有抢占优先级和响应(即子优先级)优先级两种,抢占优先级即:若程序1正在使用CPU,这时如果程序2要求使用CPU,并且程序2的抢占优先级高,则CPU被程序2抢占;若两者抢占优先级相同,则就算程序2的响应优先级高于程序1,CPU也不能被抢占;若程序1正在使用CPU,程序2和程序3的抢占优先级等于或低于程序1,且程序2的响应优先级高于程序三,则待CPU空出后,程序2先运行,程序3最后运行。TIM3_IRQn是指定将要运行的中断处理程序号。“组2”是设置中断优先级分组的,这是因为寄存器提供了四位来设置优先级,组2代表的是前两位给抢占优先级,后两位给响应优先级。
PWM模式、有效电平
    前面介绍完中断,再说一下PWM工作原理。
    假设上图中ARR大于CCRx时输出为高电平,ARR小于CCRx时输出为低电平,但在实际运用中可能并非如此,有可能是相反的情况——ARR大于CCRx时输出为低电平,ARR小于CCRx时输出为高电平,至于到底是哪种情况,还要看PWM是哪种模式、有效电平又设置的是何种极性了。
  • 模式1:ARR小于CCRx时输出为“有效”电平,ARR大于CCRx时输出为“无效”电平。
    + p- ~, {  H( A! k6 g' w
  • 模式2:ARR小于CCRx时输出为“无效”电平,ARR大于CCRx时输出为“有效”电平。

    4 Q9 r# c% e/ \$ H7 Z. ?
    这里说的是“有效”和“无效”,而不是“高”和“低”,也就是说有效电平可高可低,并非一定就是高电平。PWM模式、效电平极性,需要程序员自己配置相关的寄存器来实现。通过下面的代码来讲解。
  1. TIM1_PWM_Init(899,0);//不分频。PWM频率=72000/(899+1)=80Khz
复制代码
, L* d$ D0 ]  A) X
    上一小节讲过关于定时器参数的设置。使用定时器1的通道1来输出一路PWM波,这里的899设置的就是ARR的值,至于那个0是用来设置TIM1的频率的,不分频就代表TIM1的时钟频率和系统时钟相同,这里假设为72MHz。
" |5 K+ i- R; c% W/ g! G3 I( d% }+ \9 m
  1. void TIM1_PWM_Init(u16 arr,u16 psc)5 h& l: F# n" K" J- v/ a# K& ?
  2. {                ; M9 |( W: B% m* \( E$ S7 \5 T
  3. //此部分需手动修改IO口设置% q7 ^2 W& R$ W( p
  4.   RCC->APB2ENR|=1<<11;   //TIM1时钟使能   
    ) e( a8 d' Y  i4 r% o0 _/ s9 {4 c
  5.   GPIOA->CRH&=0XFFFFFFF0;  //PA8清除之前的设置
    / m& Q/ i  J! N9 T' @0 w* J
  6.   GPIOA->CRH|=0X0000000B;  //复用功能输出
    # t: h, o3 S$ }8 U% j9 Z
  7. 0 A4 g8 r' |& I) B7 F- B
  8.   TIM1->ARR=arr;      //设定计数器自动重装值
    , h& R8 A' ]' M; G& ^; J1 R' N" Y  ]
  9.   TIM1->PSC=psc;      //预分频器设置5 ~: C  a* J$ n5 V
  10. , |! a8 m- c' b# P7 p4 S4 l
  11.   TIM1->CCMR1|=7<<4;    //CH1 PWM2模式     , I7 P/ J4 i0 F5 h* _
  12.   TIM1->CCMR1|=1<<3;     //CH1预装载使能   
    # r$ W0 J4 y  H
  13.    TIM1->CCER|=0<<1;     //OC1 输出使能     2 s, p% v. u& o0 j" y  N
  14. //TIM1->CCER|=1<<1;- f  T9 A* v2 p9 u4 b5 ~/ q5 C' O1 X: D! g

  15. 6 M+ W' }. Q; z
  16.   TIM1->BDTR|=1<<15;     //MOE 主输出使能     
    4 [$ m9 A6 z5 R5 l' E/ b

  17. , @! [, k# h$ x, R6 W& b% V
  18.   TIM1->CR1=0x0080;     //ARPE使能
    . ^0 k* Y( t$ j; F9 d
  19.   TIM1->CR1|=0x01;      //使能定时器1                       : Y5 ^  M2 H5 w+ j" h
  20. }
复制代码
7 m0 g4 w' O9 F1 E3 N" \
    下文具体分析上面的代码。
/ e5 l! T: A( x/ D4 W( P
    前面4-6行是用来配置GPIO口的。; N; h3 L  x* N0 y1 l
  1. TIM1->ARR=arr; //设定计数器自动重装值: L, d$ Y- ^. k$ X
  2. TIM1->PSC=psc; //预分频器设置
复制代码
TIM1->ARR=arr; //设定计数器自动重装值TIM1->PSC=psc; //预分频器设置
    这两行就是我上门提到的设置定时器的频率和重装载值。9 [/ \8 D$ x6 Z+ I6 {3 _
  1. TIM1->CCMR1|=7<<4; //CH1 PWM2模式
    $ c% p" g8 t; {
  2. TIM1->CCMR1|=1<<3; //CH1预装载使能$ J) S5 Q! K" i
  3. TIM1->CCER|=0<<1; //OC1 输出使能
复制代码
8 K0 T  Q& J) O% ^1 ?6 |
    这三行是用来设置PWM输出模式和设置通道的,通道是什么呢?简单地讲就是输出PWM波的GPIO口,代码一开始不是设置了PA8这个GPIO口嘛,这个PA8就是通道1。使用通道的话要先进行输入输出方向、通道使能的设置。
  1. TIM1->CCER|=1<<1;
复制代码

+ x% }9 w" _( p% J) x9 A
    这行代码是用来设置“有效电平”极性的,根据手册,当TIM1->CCER[1]这位置1时,有效电平为低电平,置0时有效电平为高电平,而默认情况下置0。
  1. TIM1->BDTR|=1<<15; //MOE 主输出使能
复制代码

& u# `7 k. k( `* B* F8 F& K7 N
    这行代码只要对高级定时器进行设置,普通定时器无需设置。
  1. TIM1->CR1=0x0080; //ARPE使能
复制代码
# A) T9 k; H+ x7 C8 O% s
    这行代码是用来使能ARPE,ARPE是什么呢,就是当它被置1时,你自己设置的CCRx会立即生效,如果它被置为0,那么你自己设置的CCRx值不会立即生效(可能之前ARPE已经有值了),而是当之前设置的CCRx生效后才会使用你最新设置的CCRx值。
- i, m& Q% T( e/ R
上面的代码里没有对CCRx进行设置,这是因为CCRx常常是一个变化的值,你可以在主函数中用一个for循环+if判断语句对它进行++或–的操作,从而达到连续改变CCRx值得目的,例如:
  1. for(i=0;i<300;i++){- D3 J# m8 C5 T0 A5 \
  2.   TIM1->CCR1=i;
    0 X8 m  }$ l6 i/ ?
  3. if(i==300){8 S, U, Q/ `) r- V3 k+ S
  4.     i=0;( j3 w9 p; z- z0 s/ C$ ]+ s
  5.   }
    : {( Z7 r6 H8 R. W6 c& @" h
  6. }
复制代码
* d2 A4 q% s% ?, N  d
    PWM波的周期是由定时器时钟频率和预装载值两者决定的,预装载值就是ARR。
    预装载值PSC设置为899,那么,当定时器的当前值val从0增加到899时,一共经过了900个时钟周期,这900个时钟周期会产生一个PWM波形,也就是说900个定时器时钟周期才相当于一个PWM周期,那么PWM的频率就为72MHz/900=80KHz,周期为1/80KHz。

) U) k4 H) t3 Z5 x) U8 I  x- P8 }
转载自:单片机与嵌入式
8 G* Q1 p" M- O4 d
赞 收藏 评论0 发布时间:2022-11-2 22:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

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