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

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

[复制链接]
STMCU小助手 发布时间:2022-9-16 18:01
640.png
项目需求7 t4 W- `# |5 T
    在制作一个使用全向轮的机器人底盘,对于全向轮,电机的精度是影响效果的重要因素。所以使用了步进电机,使用步进电机的优点是可以不使用编码器,开环控制即可达到高精度的效果。
7 w: C/ B2 [$ o/ S. F+ l
调整占空比或者调整周期
    众所周知,PWM有两个重要参数,周期与占空比。
8 F, H7 m- ?. F$ M    步进电机的运动方式是,每收到一个脉冲,就旋转指定的角度。因此影响电机速度的唯一参数就是PWM的频率。以下附图两张来说明调整占空比与调整周期的区别。

. F6 z! @" J' S6 Z) e- w2 T1 _
周期固定,调整占空比
640 (1).png

2 h" t9 P  n5 s8 U3 k) `( m    上图中有4个PWM,它们的周期是一样的,不同之处是拥有从80%至20%的占空比。可以看出,无论占空比为多少,在1s内,它们产生的高电平的数量是一样的,即无论占空比为多少,PWM的频率都一致。因此也就无法调整步进电机的速度。因为步进电机的速度仅与PWM的频率有关。
3 C; L! U2 v1 S  o
占空比固定,调整周期
640 (2).png
/ F9 G9 Z. M9 O0 H% ~" A2 N: Q* b
    上图中有4个PWM,它们的占空比都固定为50%,却拥有不同的周期。可以看出,即使占空比固定,只要动态调整周期,PWM就能在相同时间内产生数量不同的脉冲。因此,固定占空比,动态调整PWM周期,即可达到控制步进电机速度的效果。

' D. ~% ~/ K* N* |$ P  k5 L' C1 Q
基于STM32的实现
    在STM32F1中,定时器具有PWM模式,可以用来产生PWM。相关文章:STM32中PWM的配置与应用详解。但是,STM32的PWM模式,只要确定了时基单元(即确定了PWM周期),改变输出比较寄存器,仅可改变PWM的占空比。; s1 R0 P- _9 U, l: t
    若需要改变PWM周期,需不停地改变定时器的时基单元。但时基单元与硬件相关,不适合频繁变更。因此,步进电机的调速,不适合使用STM32下定时器的PWM模式来控制。7 W4 v) ]4 l- [" E! N
    在多方查找资料后,确定了一种利用输出比较精确控制PWM周期的方式。

  I! L, I+ L0 q- h4 y# a: `* d7 T/ @) v
利用输出比较产生频率可变的PWM
    利用输出比较产生频率可变的PWM,原理简单介绍如下:2 Z& a/ {$ P  L  i3 S
    首先配置定时器时基单元,确定脉冲最小长度单位CK。
) V$ \& y- q7 x    然后开启定时器的输出比较,设置模式为翻转模式,并开启输出比较中断。
1 T) s1 r0 M5 x    将定时器内计数器CNT当前值,加上脉冲长度X(单位为CK),写入输出比较寄存器。
$ D6 }" e9 X1 P! }    在X个CK后,将会触发输出比较中断。同时电平翻转。, P' x% X, m. J9 t2 ~
    在中断中再次将当前计数器CNT的值,加上脉冲长度X,写入输出比较寄存器。; H( [/ T* z9 n0 H, ?* m
    在X个CK后,将会触发输出比较中断。同时电平翻转。
* q7 ]% q) d# `8 L3 g    在中断中再次将当前计数器CNT的值,加上脉冲长度X,写入输出比较寄存器。
" ~  ]% N+ U, H5 y# P! |* [$ Z/ C    如此往复……
1 P; m: Y+ f4 ?- N, i    以此即可得到一个占空比为50%,周期为2X个CK的PWM。

2 D8 y. F- I/ q7 c
确定最小单位CK,配置时基单元
    首先确定一个最小的间隔CK,规定PWM的高电平长度和低电平长度的单位都是CK。1 }9 f7 o" e' y8 F4 V/ e
    即高电平的长度一定是CK的整数倍。低电平亦然。4 U- R, n' X# V& ~, l6 G
    然后配置定时器的时基单元,通过CK的长度确定预分频系数。4 k* l1 G3 e! q/ o; }' |
    已知STM32F103的主频为72MHZ,则时基单元中预分频系数为
  1. <font face="Tahoma" size="3" color="#000000">PSC = 72M / (1/CK)</font>
复制代码
  ?% o2 f# P8 K4 r" J/ O
    例如,rtz所确定的CK长度为10us(0.00001s),即可得出方程。
# H$ T, v1 o3 \) L
  q9 T' X2 @2 q5 U( h
640 (3).png
9 l3 |1 L2 B$ K( _) }/ i
   预分频系数确定为720后,由高速晶振产生的72MHZ的时钟信号被720分频,得到100000HZ的时钟信号。即时钟信号每秒变动100000次。每次10us。同时可将重装载值设定为0XFFFF(16位定时器的最大值)。因为本次使用的输出比较模式不使用更新中断,该值可随意设置。
9 f8 s0 a4 S" \& l3 Y5 ?6 m# A8 ~
开启输出比较通道,设置输出比较模式为翻转模式,并配置NVIC,开启输出比较中断,配置输出比较通道:
  1. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;4 e9 J( p+ I+ K+ x* H
  2. TIM_OCInitStructure.TIM_Pulse = 500;2 }; m4 F7 G0 o( r% J$ p9 q
  3. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;- W) L$ f. h/ s5 W
  4. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    , b/ \* W& ~2 p: d
  5. TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
    3 x5 w# z  o& y% H; }
  6. TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
    - y7 `& l& O1 B+ V$ k% x
  7. TIM_OC1Init(TIM2, &TIM_OCInitStructure);
复制代码

7 V) k+ ~6 A# u8 z6 t) ?4 r$ z. Y1 x6 m
    开启输出比较中断,配置NVIC优先级:
  1. TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
    1 I5 _: u7 d( U( C: y9 z
  2. NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;4 u2 K! m" d/ Q5 T# _; I' @' Q
  3. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    * N, A" s2 e/ |' p0 ^0 a  N# i
  4. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    ' G% V3 S' T) X% f- ^0 `7 \
  5. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;6 U, f9 x9 A! o# i8 X9 R! N
  6. NVIC_Init(&NVIC_InitStructure);
复制代码

; K  Y, ?0 y6 F. |( @9 z" a! e4 }1 x3 J5 u
编写中断服务函数
    在输出比较中断中,唯一要做的事情就是把当前CNT的值取出,加上脉冲长度X,写入输出比较寄存器。6 _% _% }2 Q, }- L8 H
    当计数器达到0XFFFF(之前设定的重装载值)后,再加一会自动变为0.
1 Z0 T; l; W" h$ G1 v    例如,当前CNT值为0XFFFF,脉冲长度为5,很明显,输出比较寄存器应设置为0X0004才可触发下一次中断,而不是0X10004,这样会造成溢出。. E$ o& c5 E7 C3 P0 }7 w; B
    因此将CNT的值与脉冲长度相加后,需要取0XFFFF的余数后,再写入输出比较寄存器。
  1. ; M, a3 s8 b, j. f' v$ t
  2. int t_m=5;//低电平和高电平的长度
    ( V* z" }9 e4 E* v0 L3 e
  3. void TIM2_IRQHandler(void)/ J& {9 h+ O& l; H/ v
  4. {" T! x( a. I: R' x# V7 ~9 I" p; Q
  5. if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) {
    $ `( }. X) j3 G( H- z% j
  6.     TIM_SetCompare1(TIM2,(TIM2->CNT+t_m)%0XFFFF);
    * E5 x: i1 S$ @7 y/ T+ @
  7.     TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
    - ~" p* r( E7 P% E% \2 R+ E. I
  8.   }
    $ x. p. U4 G# r2 W! \' @
  9. }
复制代码

  S' K2 X3 Q+ i0 h
    动态调整中断服务函数中的变量t_m,即可达到修改PWM频率的效果。

2 J, v9 g) u7 W0 C5 v# n
- U4 @+ m' C# @* e3 `1 L
收藏 评论0 发布时间:2022-9-16 18:01

举报

0个回答

所属标签

相似分享

官网相关资源

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