你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
TMC2160_T(CODE).rar
2020-4-29 12:17 上传
点击文件名下载附件
11.41 MB, 下载次数: 233
TMC2160-86Step(åçå¾).pdf
807.07 KB, 下载次数: 286
TMC2160A_Rev1.05ï¼æ°æ®æåï¼.pdf
2.53 MB, 下载次数: 224
TMC2160æç¨è¯´æ.pdf
1 MB, 下载次数: 132
游åç§æäº§åç®å½ï¼2020-7-21ï¼.pdf
2020-7-27 14:23 上传
1.05 MB, 下载次数: 44
举报
小马哥STM32F103开源小四轴RoboFly全部资料大放送
【MCU实战经验】+STM32F103的uCOSII详细移植
STM32中BOOT的作用
STM32如何分配原理图IO
STM32的I2S外设
STM32电路知识学习
基于STM32F1的CAN通信之DMA
STM32怎么选型
简单分析STM32和51的区别
简单聊聊STM32的SPI外设
/**8 _6 k" U' H; P& i7 v1 p5 T' G
* 函数功能: 定时器中断服务函数
* 输入参数: 无
* 返 回 值: 无) a" v' ]. G$ x6 S; T1 y
* 说 明: 实现加减速过程' d7 V& c7 {0 W' L; r" _: P
*/+ \. o+ B+ Y2 z/ _' H7 f6 h& I
void STEPMOTOR_TIMx_IRQHandler(void)//定时器中断处理
{
__IO uint16_t tim_count=0;0 L, w0 x. I9 W3 X$ R6 }
// 保存新(下)一个延时周期
uint16_t new_step_delay=0;; L7 d- s) o; e/ c' _0 R, f
// 加速过程中最后一次延时(脉冲周期).
__IO static uint16_t last_accel_delay=0;
// 总移动步数计数器
__IO static uint32_t step_count = 0;
// 记录new_step_delay中的余数,提高下一步计算的精度
__IO static int32_t rest = 0;! e% U: P8 k+ n
//定时器使用翻转模式,需要进入两次中断才输出一个完整脉冲) R7 m3 _. k) [1 W) C
__IO static uint8_t i=0;0 E# c8 }! A: T/ p* w4 S
if(__HAL_TIM_GET_IT_SOURCE(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx) !=RESET)
{
// 清楚定时器中断
__HAL_TIM_CLEAR_IT(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx);6 k$ R) \1 X5 i6 U
8 e/ Q8 C6 Z _# ]' ^% o
// 设置比较值- u( _5 _; t& p+ D) J4 ^
tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);# T- H; u! S. m- S0 C& @- Y" J' x
__HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay);
9 ]+ a$ Z( t1 V# J( q/ h4 W3 Z
i++; // 定时器中断次数计数值
if(i==2) // 2次,说明已经输出一个完整脉冲7 F/ J. x7 d5 A3 W6 G" ~: K
{
i=0; // 清零定时器中断次数计数值# F7 x" }! d) Q* z( v, D& Y
switch(srd.run_state) // 加减速曲线阶段$ @* l/ {8 W0 {0 y( S* A O7 {
{3 Y7 t. O' ~' [+ @3 _
case STOP:+ K- r; ~! z/ M) p9 D: h/ o
step_count = 0; // 清零步数计数器
rest = 0; // 清零余值
// 关闭通道
TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_DISABLE); / W8 c" S: X; z6 M- {1 p/ M
__HAL_TIM_CLEAR_FLAG(&htimx_STEPMOTOR, STEPMOTOR_TIM_FLAG_CCx);
STEPMOTOR_OUTPUT_DISABLE();( x4 l Z5 L& q: W3 l7 a7 ]4 E: B* J
MotionStatus = 0; // 电机为停止状态 7 j6 m' M( I( r# b) ]% d4 g
break;/ O7 B# E9 A6 w7 ~: A4 U3 h+ `
case ACCEL:
step_count++; // 步数加1) m* Z# |& c2 U* L; U
if(srd.dir==CW)
{
step_position++; // 绝对位置加1
}
else
{
step_position--; // 绝对位置减1
}
srd.accel_count++; // 加速计数值加16 c3 O0 X ^5 T+ R' p
new_step_delay = srd.step_delay - (((2 *srd.step_delay) + rest)/(4 * srd.accel_count + 1));//计算新(下)一步脉冲周期(时间间隔)
rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差1 ]$ P0 }& M4 W# J( q3 \3 }: Q; t* a/ l
if(step_count >= srd.decel_start)// 检查是够应该开始减速7 t% s! Y' N7 u) Z/ D
{7 e( b) m$ u- }. K" T- z
srd.accel_count = srd.decel_val; // 加速计数值为减速阶段计数值的初始值# W/ b. N) e& `8 ^; p& q; Q
srd.run_state = DECEL; // 下个脉冲进入减速阶段" L$ c9 A) i: y+ t4 b
}
else if(new_step_delay <= srd.min_delay) // 检查是否到达期望的最大速度: k) @5 f* u, e- V, U/ K
{5 g! C% [ S+ G% S$ c" b8 K
last_accel_delay = new_step_delay; // 保存加速过程中最后一次延时(脉冲周期)
new_step_delay = srd.min_delay; // 使用min_delay(对应最大速度speed)# ~/ T/ }" t( W2 `
rest = 0; // 清零余值
srd.run_state = RUN; // 设置为匀速运行状态
}) d0 q% g- }* ^( y2 i+ K
break;
/ R# N4 e* I1 ?2 U$ R/ |5 z3 p) x
case RUN:
step_count++; // 步数加1
if(srd.dir==CW)
{ + s9 W5 E; a7 b3 v0 \, P
step_position++; // 绝对位置加1: J) W r4 R. U2 T
}0 Q @9 G0 B7 f3 ] B
else
{
step_position--; // 绝对位置减1
}$ O# v* ]5 ] T( t* S
new_step_delay = srd.min_delay; // 使用min_delay(对应最大速度speed)8 x7 y+ }7 s# @; U h5 [" u
if(step_count >= srd.decel_start) // 需要开始减速
{
srd.accel_count = srd.decel_val; // 减速步数做为加速计数值4 |7 k5 y: N4 {" P7 I4 \
new_step_delay = last_accel_delay;// 加阶段最后的延时做为减速阶段的起始延时(脉冲周期)# d8 h l" |0 l E" K
srd.run_state = DECEL; // 状态改变为减速
}/ g: X0 W% u: e1 a
break;
+ n4 ~ R( S1 e5 {+ F
case DECEL:- B7 t" a1 n9 K' W; C
step_count++; // 步数加1
if(srd.dir==CW)
{
step_position++; // 绝对位置加1
}* r, o- K3 l' {7 P9 r N( g
else
{
step_position--; // 绝对位置减1( p- q8 Q' X* U: x, o6 E# @% l
}7 @0 Y% e' D9 c& \0 Q B
srd.accel_count++;, @ _( D/ a# Z7 b L. s
new_step_delay = srd.step_delay - (((2 * srd.step_delay) + rest)/(4 * srd.accel_count + 1)); //计算新(下)一步脉冲周期(时间间隔)
rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差0 z7 i* F0 g- T
' O, @ g6 e$ z7 Q* L
//检查是否为最后一步
if(srd.accel_count >= 0)- a6 d7 E; ^! B9 R
{! ]. |: o8 W. U1 v7 y
srd.run_state = STOP;
}! q: |3 B h: T2 P+ E
break;
} ! k) q: f$ m. y# `6 ^/ ^1 G4 n
srd.step_delay = new_step_delay; // 为下个(新的)延时(脉冲周期)赋值+ R/ q9 v0 O3 H' c. R
}( E9 v5 ~! y# b/ D% T5 v
}0 i5 X1 m7 F* t) d
}/ I3 P0 w0 d7 _+ z7 ^' ]& \! m
/**
* 函数功能: 相对位置运动:运动给定的步数, t* U+ F4 o& r' T& R" `! u. W
* 输入参数: step:移动的步数 (正数为顺时针,负数为逆时针).
accel 加速度,实际值为accel*0.1*rad/sec^2
decel 减速度,实际值为decel*0.1*rad/sec^2+ F' |' R& A" ^0 s: Q9 e* P! o& s, |
speed 最大速度,实际值为speed*0.1*rad/sec) Z: d+ X X: Y1 P- i
* 返 回 值: 无0 V, f h* C) }
* 说 明: 以给定的步数移动步进电机,先加速到最大速度,然后在合适位置开始
* 减速至停止,使得整个运动距离为指定的步数。如果加减速阶段很短并且
* 速度很慢,那还没达到最大速度就要开始减速
*/) r1 @" A0 L7 F3 m: ^
void STEPMOTOR_AxisMoveRel(__IO int32_t step, __IO uint32_t accel, __IO uint32_t decel, __IO uint32_t speed); y* v! B J* s5 I! z2 s1 p
{
__IO uint16_t tim_count;4 O: Q2 P; e8 v6 U
// 达到最大速度时的步数6 p1 s: h O& ] E1 _
__IO uint32_t max_s_lim;3 M- N9 V p4 [, B
// 必须要开始减速的步数(如果加速没有达到最大速度)# `1 r% a8 C2 u+ l% o+ M
__IO uint32_t accel_lim;
0 ~3 N. v8 C A3 n
if(step < 0) // 步数为负数
{( D. a6 ~: p# |7 N0 e" n6 i- r
srd.dir = CCW; // 逆时针方向旋转
STEPMOTOR_DIR_REVERSAL();% s; Y! u" B3 g/ K( x8 c
step =-step; // 获取步数绝对值; W7 h9 L* O3 g2 \/ H
}$ H9 o1 ~/ L3 c* u7 i9 P; c
else/ A9 Q9 ]6 i9 O$ R, P0 J
{
srd.dir = CW; // 顺时针方向旋转' E4 Q5 V& \5 T6 }9 j9 W) m9 U2 Y
STEPMOTOR_DIR_FORWARD();
}
if(step == 1) // 步数为1
{6 w" Z0 K" @* q0 p: t- V9 ~/ E
srd.accel_count = -1; // 只移动一步
srd.run_state = DECEL; // 减速状态.
srd.step_delay = 1000; // 短延时
}
else if(step != 0) // 如果目标运动步数不为0
{0 K5 u; l- s/ K/ g$ J" Y
// 我们的驱动器用户手册有详细的计算及推导过程$ U- M& g4 j5 Y2 I; ~& Y( M3 J, ]; K
: a9 u T$ W! P- `" ~
// 设置最大速度极限, 计算得到min_delay用于定时器的计数器的值。
// min_delay = (alpha / tt)/ w
srd.min_delay = (int32_t)(A_T_x10/speed);
3 o6 w" Z9 O& _
// 通过计算第一个(c0) 的步进延时来设定加速度,其中accel单位为0.1rad/sec^2
// step_delay = 1/tt * sqrt(2*alpha/accel) s+ d$ ~" h3 h a% A
// step_delay = ( tfreq*0.676/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100
srd.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10);
, I" J* ]8 S/ w; l8 D% M* ]
// 计算多少步之后达到最大速度的限制5 q: I( U: H+ j
// max_s_lim = speed^2 / (2*alpha*accel)# B0 P* r# z0 M) `2 m( T
max_s_lim = (uint32_t)(speed*speed/(A_x200*accel/10));3 }+ X7 v5 T' D; H y9 c3 G
// 如果达到最大速度小于0.5步,我们将四舍五入为0
// 但实际我们必须移动至少一步才能达到想要的速度
if(max_s_lim == 0){* Z9 s9 ?3 M1 N5 A* ?7 z
max_s_lim = 1;& v" R( S* x. P: p1 ` i3 V3 l: P: \
}
// n1 = (n1+n2)decel / (accel + decel)
accel_lim = (uint32_t)(step*decel/(accel+decel));
// 我们必须加速至少1步才能才能开始减速.. M/ _. `9 |* r7 d) t. Q( B1 {
if(accel_lim == 0){% P1 t Q- b1 D
accel_lim = 1;
}& [5 S3 g) f$ ~4 p( n: B" q
// 使用限制条件我们可以计算出减速阶段步数2 t4 k9 Y a" q+ e$ E
if(accel_lim <= max_s_lim){8 r! g* X+ Z1 \% s- a+ o' Z
srd.decel_val = accel_lim - step;/ @' w9 W3 I8 c( X4 R: X% U
}4 z1 q2 K: U5 q- h
else{
srd.decel_val = -(max_s_lim*accel/decel);
}
// 当只剩下一步我们必须减速
if(srd.decel_val == 0){7 L2 J" D6 G9 c1 ]! F* u- v3 W' {
srd.decel_val = -1;
}
; Z# q8 n- ]2 i4 r+ D3 D- x
// 计算开始减速时的步数7 B# M3 L/ y4 a( x' K7 o- m# m
srd.decel_start = step + srd.decel_val;1 v8 w$ ^3 a9 ?! y* ?- z
1 ~$ ~/ D$ _, b: m
// 如果最大速度很慢,我们就不需要进行加速运动
if(srd.step_delay <= srd.min_delay){* }( m2 r- d3 c/ W5 u
srd.step_delay = srd.min_delay;
srd.run_state = RUN;8 `- \% E- ^, T8 F3 g% ?
}# ?7 e, J1 @. S" r0 r
else{
srd.run_state = ACCEL;
}
// 复位加速度计数值
srd.accel_count = 0;
}5 `. \ o& ^! _8 c4 N
MotionStatus = 1; // 电机为运动状态
tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);6 n" e) w" O! w1 S* r- G& j
__HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay); // 设置定时器比较值
TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_ENABLE); // 使能定时器通道 ( c* J" w' ]- a+ z2 e4 B/ H3 r
STEPMOTOR_OUTPUT_ENABLE();
}8 G) u- }: t/ C4 \! z& M
1、机器人和工业驱动器. ^8 z- M! c1 ^' f
2、纺织、缝纫机
3、包装机械& G! R6 r; [. M8 {
4、工厂和实验室自动化
5、高速 3D 打印机
6、液体处理
7、医疗
8、办公自动化
9、有线闭路电视3 G0 s: I5 j: ]4 F' k+ M; y
10、自动取款机、现金回收
11、泵和阀门
电机驱动主芯片采用TMC2160
TMC2160和5160区别:5160带UART控制及智能定位控制(如速度控制、位置控制);/ e. V0 C6 ]+ m8 E. \) v
TMC2160和TMC260 TMC262区别:以前版本需要通过SPI接口设置细分、电流等,新的TMC2160可通过拨码开关设置;
有条件的输入输出最好加些滤波和保护,输出加脉冲整形(比如加74HC14)% O8 n# f) Z, s2 l" z
, h# a$ X4 v' ^+ _; X( z
拨码开关ON:设置为高电平1,反之低电平0
细分设置:CFG1、CFG0
CFG1、CFG0:1 F5 Z0 i' Z: \) x
11:64细分7 C: c$ r( B& P' s: s5 R* d
10:32细分* E* S; V) Z- [ S1 v5 H4 l
01:16细分
00:8细分
运行电流设置:CFG4、CFG3、CFG2
CFG4、CFG3、CFG2:) e2 u' L2 ]# |1 Q' F# L7 x
111:IRUN=313 f- A3 t' M6 x5 ^/ z. e
110:IRUN=28& d8 T( r& j+ r0 Y& j" a
101:IRUN=26# o" D; q) A+ q, d0 e3 i
100:IRUN=24: B# j! m5 A- I+ x5 U1 K- w
011:IRUN=22
010:IRUN=20
001:IRUN=18
000:IRUN=16; b1 F& N4 h" S% `7 }3 j
Irms=Vfs/(IRUN/32)/(Rsense*1.414); + E& G- u" {% v6 u: _' `% |
Vfs =325mV,Rsense为0.05欧时,则最大电流为4.5A左右;5 v: n: ^3 u6 A8 H
CFG5:3 I1 v( L5 ?6 W0 U
1:SpreadCyle模式,低速、低平稳运行模式, F. q% j. h0 {" C2 `2 E% \$ V
0:SpreadCyle模式,高速、高运动稳定模式( f! r( X. E+ ]5 u+ k
保持电流设置:CFG6" d5 H; h) N# b5 L$ B7 m, n6 D
CFG6:' M( ]' {4 m8 W U, X% |* N2 J
1:保持电流=运行电流/2& k! O6 b) G$ i0 L
0:保持电流=运行电流* f2 Q$ R- M1 C" u
DIR+STEP接口模式位置控制(无需SPI接口)
COM端:接24V或12V或5V# N- i8 S% N7 \1 l- q2 R1 Y- q
DRV_ENN、STER、DIR:接集电极开路输出$ V3 q* ^5 O3 |" E L6 Y# k5 t
为测试方便:
COM端:接3.3V5 q; b, e, P/ T
DRV_ENN:使能,接PB14
DIR:方向, PB15
STEP:脉冲,PA8