概述
+ q; u' }4 P: t3 }! s正在做的项目需要用STM32控制步进电机,本篇主要讲解利用STM32定时器外设输出脉冲来控制步进电机转动。
v' I/ V- S: ?& a F% y5 `% s/ X
STM32定时器. y: }; ?# D4 x* J* k
使用STM32芯片类型:STM32c8t6。" _ Q- E8 E o' n/ @ {1 R
6 @: O' W4 v- L$ F, a' O
" O( T: M. A' H! ^' A
5 |1 m ^6 f/ ]' n+ I: F0 R9 J
使用外设接口:选用TIM4的CH1通道,对应输出脉冲IO口为PB6。
4 p5 [. o8 [* q y- R6 S. z. O% o
: K6 O8 s! J% \7 u
, }# o, n c% f3 p% L! w" u8 S
, z2 n# a7 T5 t步进驱动器介绍
' e2 C% c, d$ q3 [ ~(这里以两相步进驱动器为例,详细见说明书)
# S! O9 y x. Q6 a% V% c3 R1 j( x [/ [ e9 r
接口
% P% v, l: B4 Z5 J& N) X! Z步进驱动器可分为两部分:环形分配器、功率放大器。7 z& C: T' \2 c( T: O8 H
环形分配器:接收3种信号分别为:脉冲信号(PUL),方向信号(DIR),脱机信号(ENA)。
, w; t0 G9 A' o8 f2 h0 w- j脉冲信号:环形分配器对脉冲信号进行分配,去控制功率放大器相应的晶体管,使步进电机的线圈得电。所以,步进电机要运转就必须有脉冲输入,所以需要一个驱动器来给步进电机的各项绕组依次通电。
V& R6 ]! \7 L$ _! s方向信号:控制AB通电的相序,A-B顺时针,B-A逆时针% v7 ?6 v' p4 ?6 ] _3 p2 y# P$ j2 @: F
脱机信号:步进电机停止时,AB线圈有一相得电,得电的功能使转子锁住,使转子不能动,需要收去拨动转子的时候,需要给脱机信号,使AB相绕组完全断电,转子处于自由转动状态。(也就是说控制电机停止除了不给脉冲之外,还可以控制脱机信号来锁死电机,此处用不着脱机信号)+ ?# f1 U& {3 J' m% c
0 y: s9 `( a: N7 r" S
- L2 J& f- S! \0 o J' t- N" u1 b& ^" a- ?# U5 f8 u
细分+ j& \1 G8 T% ^; {
为了提高步进电动机控制的精度,现在的步进驱动器都有细分的功能,所谓细分,就是通过驱动器中电路的方法把步距角减小。比如把步进驱动器设置成5细分,假设原来步距角1.8°那么设成5细分后,步距角就是0.36°。也就是说原来一步可以走完的,设置成细分后需要走5步。一般步进电动机的细分表在驱动器上可以直接看到。(设置合适细分能够避免电机转动时震动过大,但过高的细分数会导致电机输出力矩减小)
. T2 I6 V0 j0 v! c2 _/ W% R( T( k' M+ `% `) s" e' l
0 [ ^# u$ w7 l+ ^9 S
- m( P! H" W2 G2 H) Y' p驱动电源:
" O' a; B+ Q2 J) T' t需要9-42V直流电源,需要使用变压器将220V交流电转为24V直流电! Y6 Y0 ^" s" V' h) L- d
' Y9 |. s. d6 i |+ q
) d6 C# {3 t0 B8 O% n' t8 x+ f2 i, h4 g% q' K! J8 R0 O/ ?
定时器频率与步进电机的关系7 M. w1 @/ L% P
接线2 }5 m7 s0 ]; R7 i! B
将驱动器PUL+端接入STM32输出脉冲的IO口(PB6),PUL-端接地! a7 h- L6 w3 y% `
将驱动器DIR+端接入STM32的任意一个闲置IO口(这里选PB5),DIR-端接地
+ [) W9 I, l R* j. c/ r. b: d7 ?驱动器ENA±端不接# e) q. f* g7 g) \+ C4 u- ~
A+、A-、B+、B-接入步进电机, n: ]6 c, v6 i
电源接到变压器
, Q! M1 `, ^* r6 |9 o' K! ]% E" {; V1 p/ u
5 X5 Q; N9 [% [4 e, h! e* j9 f, d
频率与速度的关系
3 q" L6 d Z2 b' `- r1 g确定输出脉冲频率与电机转速的关系,对于两相步进电机而言:4 X, I8 s9 V. R: T+ g' b
转速 = 脉冲频率 * 60 /((360/T)*x). J9 ^3 t! t! X; M# x b
T是步进电机步距角(1.8°),x是驱动器细分倍数(16)
3 C" E) I F! r% `, d( i: ^0 h脉冲频率= 时钟频率(72Mhz)/ ((arr+1)*(psc+1))- I4 D G1 H. Z% s0 |/ t
根据以上公式,可以得到:
, ]1 X0 R9 h s, J4 O4 i# ^* TSpeed = 15r/min时,若确定arr为199,则psc为449
" A4 M% ?- l. M; ~, u$ a其他速度可根据需要自行设定。& ?& q4 M, M9 ~' H! a
* P0 c( H2 M; s5 s+ D
4 C) W$ U8 G( G6 q. _代码
1 k9 k$ ~2 K% Y+ ?" B) t: o编写流程:TIM4配置 -> DIR对应IO口配置 -> main调用初始化函数并设置占空比) m& v9 E; F P2 _4 ]- y
. }1 F' x) _1 h Y$ }- g
8 ?9 i% k) o5 e: x* P# Z- //TIM4配置
" j) l8 H' _+ v- S/ ~' [+ E. z- [ - void TIM4_PWM_Init(u16 arr,u16 psc) //初始化arr=200,psc = 450得到电机速度为15r/min9 R: Q: n5 x# ]9 I. S2 |* ]; k
- {
+ J( x N; p5 a* E% `& q - //初始化结构体& \0 C0 C7 f/ q, [! i
- NVIC_InitTypeDef NVIC_InitStructure;
1 ]# v$ ^' a Q - GPIO_InitTypeDef GPIO_InitStructure;
8 p0 m+ \. n+ M1 i7 l( @ - TIM_OCInitTypeDef TIM_OCInitStructure;# l# a* }# J2 S
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; Q! z6 b+ ^' D+ o4 W* A. P
-
7 ]. S7 B* R5 J+ o; R) E2 S - //使能时钟
- ^! j" V3 |+ r5 X4 z5 T7 f - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);, K% l' f" a1 @! w' L
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); 6 [1 L$ l, Z& G/ v& n5 j* F
- - Z; e# `7 R2 A% j. H! K
- //设置该引脚为复用输出功能,输出TIM4 CH1的PWM脉冲波形 GPIOB.6
( I, @! o# t+ r# F& w7 Z - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //TIM4_CH1$ Q0 {+ V# p( m( ?: I
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; , E8 n; |2 e+ P" x4 D
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;9 [( J6 t: D4 d4 o, h8 I
- GPIO_Init(GPIOB, &GPIO_InitStructure);* u( K) v4 W7 I
- //计数模式1 {3 S, S- Z q& V, b, G
- TIM_TimeBaseStructure.TIM_Period = arr;
; ^9 w, N5 V% _9 Y. O* [ W - TIM_TimeBaseStructure.TIM_Prescaler =psc;
- W% ~$ R+ t7 W* t1 Z - TIM_TimeBaseStructure.TIM_ClockDivision = 0;
C8 l6 s( K' ]* n* n - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - h0 I/ l' y3 s
- TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
4 x" s$ B) Z H' d! i -
: ?) E0 o, j& _1 l) [% G' L/ W% G - //定时中断配置0 z9 y& @) x; r+ x, D% k: v9 V
- TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); /* i5 {6 _1 u% T+ w# t. i
- NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; : j( Z2 g1 Y1 E
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; ' e( G* S$ r: a3 o, }
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 9 I6 y9 m/ n+ Y0 O% N/ z6 b4 a6 v
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; & \2 N( f+ ^0 Q) p- U G
- NVIC_Init(&NVIC_InitStructure); 9 s+ U; X5 x( g# m
- 7 S+ t7 k3 J9 ~# F0 x7 @
- //初始化TIM4 Channel1 PWM模式
* U, \6 b9 j! X/ v- W3 o6 w - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;) X2 Q8 L+ e0 B
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; / y# S! k- X! J; W6 O) A8 @6 P
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
. x% e$ d. ^* s; x2 l) p - TIM_OC1Init(TIM4, &TIM_OCInitStructure);
- N4 Q: D) w' K* F! f
% W) D9 ?% e7 e+ L, } E- TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
0 \3 i# V5 e# I J1 E - TIM_Cmd(TIM4,ENABLE); //使能定时器1 S1 J! F* y: e) q7 @/ Q w
- }
2 a. F( v' Q3 k! e! G: q
复制代码- /*PB5电机方向引脚配置*/, |; e5 U/ n: y2 X* q' d( W
- void DIR_Init(void) 9 m$ c: w& i" {" w, @0 r
- {
z& H! j! [2 g# S6 j - GPIO_InitTypeDef GPIO_InitStructure;
& E1 Y. m: Y' ?7 C- f; z - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
: |' J% \& ~5 T - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
' F# N1 C" H! g4 i3 }9 r/ q - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
1 }* l0 N/ D4 h2 ` - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; ( z* B# m- P% n1 a
- GPIO_Init(GPIOB, &GPIO_InitStructure); ! O3 e; G* \& ^! |
- }
6 P% J7 K8 u4 k# ^7 {
复制代码- int main()
. b: b' A+ t2 c - {6 v/ u) f* u% W! j3 d
- DIR_Init();
b5 g4 f3 d% i1 E# f) J! W; ? - TIM4_PWM_Init(200,450);
# }) A. E0 D3 ~( v9 C1 N" }1 Z! Y( A - TIM_SetCompare1(TIM4,200/2); //设置占空比为50%(=arr/2),不设置的话电机启动不了
' D0 \6 Y3 f4 N7 i" z - while()
& B2 _# P. H+ w5 Q7 X$ } - {
) b% ^; C# c8 H6 V3 R; ^0 N2 C6 ]$ \ - ;) |( ~- H$ l; G
- }
) r0 Z( K, b, M1 [) |6 S" E - }
; ?3 i. |+ `* l# F" E3 q0 e n }
复制代码 - x9 d: k/ I# Z3 P- @
( R( ~ z5 B K0 k, u& }) T————————————————
9 [! _- P9 ^" s4 [版权声明:Efic
- p& z4 Z2 A! w6 k: V: f/ `
% X6 [3 {, W" e! A1 D9 `( X/ K
+ {. h1 X, q9 l |