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

STM32实例-步进电机的速度控制

[复制链接]
STMCU小助手 发布时间:2022-9-16 18:01
640.png
项目需求: c! R$ Y( l  [9 x( t$ A5 Y+ x
    在制作一个使用全向轮的机器人底盘,对于全向轮,电机的精度是影响效果的重要因素。所以使用了步进电机,使用步进电机的优点是可以不使用编码器,开环控制即可达到高精度的效果。
  Y- Q* P- A/ ?1 ^: W( [
调整占空比或者调整周期
    众所周知,PWM有两个重要参数,周期与占空比。7 J1 h, m9 j) p' X7 k
    步进电机的运动方式是,每收到一个脉冲,就旋转指定的角度。因此影响电机速度的唯一参数就是PWM的频率。以下附图两张来说明调整占空比与调整周期的区别。

( w0 ^9 n  r$ U6 \  m0 n
周期固定,调整占空比
640 (1).png
- `7 B5 l) m- d+ G( k/ d
    上图中有4个PWM,它们的周期是一样的,不同之处是拥有从80%至20%的占空比。可以看出,无论占空比为多少,在1s内,它们产生的高电平的数量是一样的,即无论占空比为多少,PWM的频率都一致。因此也就无法调整步进电机的速度。因为步进电机的速度仅与PWM的频率有关。
5 I8 C, x- J. x6 G. f
占空比固定,调整周期
640 (2).png

; J6 z9 e( @6 X" \    上图中有4个PWM,它们的占空比都固定为50%,却拥有不同的周期。可以看出,即使占空比固定,只要动态调整周期,PWM就能在相同时间内产生数量不同的脉冲。因此,固定占空比,动态调整PWM周期,即可达到控制步进电机速度的效果。
4 p" y8 \1 G3 W8 R/ f: F7 f6 G
基于STM32的实现
    在STM32F1中,定时器具有PWM模式,可以用来产生PWM。相关文章:STM32中PWM的配置与应用详解。但是,STM32的PWM模式,只要确定了时基单元(即确定了PWM周期),改变输出比较寄存器,仅可改变PWM的占空比。
6 q! h% V: g9 E! H    若需要改变PWM周期,需不停地改变定时器的时基单元。但时基单元与硬件相关,不适合频繁变更。因此,步进电机的调速,不适合使用STM32下定时器的PWM模式来控制。
6 D; ]) M, ], B: _7 ?    在多方查找资料后,确定了一种利用输出比较精确控制PWM周期的方式。
2 ]. E4 K1 u% L8 o! J$ L8 ~0 g
利用输出比较产生频率可变的PWM
    利用输出比较产生频率可变的PWM,原理简单介绍如下:$ q' I1 s* P! z# w
    首先配置定时器时基单元,确定脉冲最小长度单位CK。
1 z) B% G( A3 {" p+ d    然后开启定时器的输出比较,设置模式为翻转模式,并开启输出比较中断。
2 [. Y4 m! y" I$ E2 ^& y    将定时器内计数器CNT当前值,加上脉冲长度X(单位为CK),写入输出比较寄存器。* N2 J2 N' {: L3 t
    在X个CK后,将会触发输出比较中断。同时电平翻转。
. z& J9 j: Z4 b" g: K/ I' _    在中断中再次将当前计数器CNT的值,加上脉冲长度X,写入输出比较寄存器。
' ~; d4 ]4 U3 R( i' n4 T    在X个CK后,将会触发输出比较中断。同时电平翻转。; y: w4 @4 U6 `& ^% o( Z( M
    在中断中再次将当前计数器CNT的值,加上脉冲长度X,写入输出比较寄存器。
, g0 r* O& J1 j$ \8 B    如此往复……& V1 [% m+ c2 U$ M' Z
    以此即可得到一个占空比为50%,周期为2X个CK的PWM。
+ y) T: F! [" E2 ]
确定最小单位CK,配置时基单元
    首先确定一个最小的间隔CK,规定PWM的高电平长度和低电平长度的单位都是CK。6 s, z, R; d# G9 u# ^/ Z0 _
    即高电平的长度一定是CK的整数倍。低电平亦然。$ V& n" h, S9 k- i# F  h5 |
    然后配置定时器的时基单元,通过CK的长度确定预分频系数。. l9 {6 x) g# c5 z" _; B0 d, |
    已知STM32F103的主频为72MHZ,则时基单元中预分频系数为
  1. <font face="Tahoma" size="3" color="#000000">PSC = 72M / (1/CK)</font>
复制代码

- B* X' o5 H4 [3 _$ G8 p. c
    例如,rtz所确定的CK长度为10us(0.00001s),即可得出方程。
( }1 X/ a6 F0 u9 L  W" e2 z$ O& l
& s; F5 ^, g+ V: [) Q) T( [
640 (3).png
* A: i) Z' M7 R1 [7 K( Y6 N
   预分频系数确定为720后,由高速晶振产生的72MHZ的时钟信号被720分频,得到100000HZ的时钟信号。即时钟信号每秒变动100000次。每次10us。同时可将重装载值设定为0XFFFF(16位定时器的最大值)。因为本次使用的输出比较模式不使用更新中断,该值可随意设置。
( @6 n# i) r% ~7 @, y' W7 [
开启输出比较通道,设置输出比较模式为翻转模式,并配置NVIC,开启输出比较中断,配置输出比较通道:
  1. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;" H; t  W  W3 n; n* D
  2. TIM_OCInitStructure.TIM_Pulse = 500;
    4 V/ N, O! F2 C: C
  3. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    0 t. j( c1 f! u# q( I
  4. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    0 J/ D! [7 M; M- i7 q
  5. TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
    + Y( n7 G- I, k+ a. r; S2 L/ E
  6. TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
    . f$ D+ k& P7 k+ \& P+ _3 U$ |
  7. TIM_OC1Init(TIM2, &TIM_OCInitStructure);
复制代码
( b# p# g0 ~- v( {4 L
    开启输出比较中断,配置NVIC优先级:
  1. TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);9 D: ~! \; Z; a
  2. NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;6 X' B- K" i6 H) b8 B3 B
  3. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    . Q  ~! N9 Y, }) T3 E3 R* f
  4. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;9 ~* ^9 `2 N: r9 c3 f
  5. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    / H0 a( R6 \) ~9 ]6 I0 u
  6. NVIC_Init(&NVIC_InitStructure);
复制代码

7 p) h0 n& {$ _
编写中断服务函数
    在输出比较中断中,唯一要做的事情就是把当前CNT的值取出,加上脉冲长度X,写入输出比较寄存器。
1 W7 H, ~. }& r& }( H$ o    当计数器达到0XFFFF(之前设定的重装载值)后,再加一会自动变为0.
0 v$ l! \6 Y: c* f* Z6 `4 A5 V' y    例如,当前CNT值为0XFFFF,脉冲长度为5,很明显,输出比较寄存器应设置为0X0004才可触发下一次中断,而不是0X10004,这样会造成溢出。: r# \, s7 S8 U& j7 F
    因此将CNT的值与脉冲长度相加后,需要取0XFFFF的余数后,再写入输出比较寄存器。
  1. 6 ^/ }0 E; |' h- a* f( ]8 d0 o
  2. int t_m=5;//低电平和高电平的长度' ]: W* a- O* Q1 G6 _
  3. void TIM2_IRQHandler(void)1 n7 h9 k! _. c( c* q9 [2 ]
  4. {6 w/ X/ ~& M2 H& T* l, T. r
  5. if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) {
    $ |' x$ _: ?: n( Q0 D4 O0 o
  6.     TIM_SetCompare1(TIM2,(TIM2->CNT+t_m)%0XFFFF);
    0 F8 f5 p8 F* g
  7.     TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
    6 P" v1 X4 _, p7 k/ p4 U: k
  8.   }
    ; Q+ ~8 o8 s$ O% q2 v% t2 x6 N
  9. }
复制代码

$ R3 U, u/ u$ q8 T) ~9 u
    动态调整中断服务函数中的变量t_m,即可达到修改PWM频率的效果。

9 `) u# B5 Y3 }8 n& u1 p" e1 J. D& w( {$ x2 \. {! i$ o
赞 收藏 评论0 发布时间:2022-9-16 18:01

举报

0个回答

所属标签

相似技术帖

官网相关资源

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