你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
TMC2160_T(CODE).rar
2020-4-29 12:17 上传
点击文件名下载附件
11.41 MB, 下载次数: 232
TMC2160-86Step(åçå¾).pdf
807.07 KB, 下载次数: 285
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, 下载次数: 43
举报
小马哥STM32F103开源小四轴RoboFly全部资料大放送
【MCU实战经验】+STM32F103的uCOSII详细移植
STM32中BOOT的作用
STM32如何分配原理图IO
STM32的I2S外设
STM32电路知识学习
基于STM32F1的CAN通信之DMA
STM32怎么选型
简单分析STM32和51的区别
简单聊聊STM32的SPI外设
/**% C2 _8 K* P. Q( v1 O6 F
* 函数功能: 定时器中断服务函数: s( ?5 | h$ R# F3 G% B
* 输入参数: 无
* 返 回 值: 无
* 说 明: 实现加减速过程, ]; b% S. [" O" k0 O' @4 Q
*/ z% _) M. G; q2 n3 T! _. a
void STEPMOTOR_TIMx_IRQHandler(void)//定时器中断处理* [6 o M% g( X( K4 x
{ , a! M/ D) E) z& |, c ]5 G
__IO uint16_t tim_count=0;& h) q9 M; j; B; ~7 r
// 保存新(下)一个延时周期! R) V1 R8 y/ c3 n+ r( u5 ?
uint16_t new_step_delay=0;
// 加速过程中最后一次延时(脉冲周期).1 v6 e7 j0 \. |- l) g5 ^ P
__IO static uint16_t last_accel_delay=0;( p/ s1 P* _. |( ]4 k! A) Q5 c
// 总移动步数计数器
__IO static uint32_t step_count = 0;# `1 A: \: j' F2 @
// 记录new_step_delay中的余数,提高下一步计算的精度. s/ Z8 M# t* ^ ^
__IO static int32_t rest = 0;
//定时器使用翻转模式,需要进入两次中断才输出一个完整脉冲5 v. b R+ g! X% v1 |
__IO static uint8_t i=0;
; ?! S; b7 n/ ~' ~: l- |7 r9 N
if(__HAL_TIM_GET_IT_SOURCE(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx) !=RESET)1 ?# `7 B6 v. Z. M
{
// 清楚定时器中断
__HAL_TIM_CLEAR_IT(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx);5 l _! O& p2 w5 _; E; i1 O
// 设置比较值/ _7 R8 ~/ w T5 i, {4 r
tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);
__HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay);
i++; // 定时器中断次数计数值7 F% g: J" F0 T# r1 S* `- M! e/ ~+ w
if(i==2) // 2次,说明已经输出一个完整脉冲2 [3 l% }, W. w& o) F3 P
{& n( |% u/ Z3 B& j+ O5 t7 ~
i=0; // 清零定时器中断次数计数值: C; A* r# b: M& W$ t! W) H
switch(srd.run_state) // 加减速曲线阶段0 R/ j7 k* a2 \' C$ j. Y" h) J
{
case STOP:' W# v. i# F+ i% q/ o+ h' S" @
step_count = 0; // 清零步数计数器, ]) P3 H8 _* F& M& }6 |
rest = 0; // 清零余值$ {3 o* O/ M' e! J4 D- Z2 l1 J* |
// 关闭通道" P! b# X4 n- O q
TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_DISABLE); 0 V- S. I: ^5 Q. j! M. {& t
__HAL_TIM_CLEAR_FLAG(&htimx_STEPMOTOR, STEPMOTOR_TIM_FLAG_CCx);9 N* s6 M8 J7 c: j; s6 J
STEPMOTOR_OUTPUT_DISABLE();6 s) D2 x9 \, }0 h
MotionStatus = 0; // 电机为停止状态 + c$ p1 g4 p# Y
break;8 l1 [! V) w o0 x. v" G' H& ]
. U, G6 i$ J- o2 X i
case ACCEL:
step_count++; // 步数加11 Z* W3 L& F q: W& H2 ~7 U
if(srd.dir==CW)
{ # ] j; @% Z- g# L" q$ L
step_position++; // 绝对位置加1
}
else
{1 g. J" n0 f! l. D( V/ h0 u8 |
step_position--; // 绝对位置减1
}1 d9 m1 X! Q: N/ t# g3 H
srd.accel_count++; // 加速计数值加1
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);// 计算余数,下次计算补上余数,减少误差! f, V! Q4 g- ~1 ]" X7 Z: F4 V
if(step_count >= srd.decel_start)// 检查是够应该开始减速7 P! T& `' h# x" F" V e9 B- p
{
srd.accel_count = srd.decel_val; // 加速计数值为减速阶段计数值的初始值1 O- \+ N3 @! B1 ^# v- A0 b. @
srd.run_state = DECEL; // 下个脉冲进入减速阶段
}" a) G+ K7 I# E* g
else if(new_step_delay <= srd.min_delay) // 检查是否到达期望的最大速度
{0 H) P& E( B; ^
last_accel_delay = new_step_delay; // 保存加速过程中最后一次延时(脉冲周期)) O, m8 W! p& i$ }2 c& W# N" w( H; P
new_step_delay = srd.min_delay; // 使用min_delay(对应最大速度speed)6 K+ p9 x. Q' u$ d. R/ i8 v0 z9 D
rest = 0; // 清零余值- R ~* \! ^( R! p0 v# K
srd.run_state = RUN; // 设置为匀速运行状态9 s6 j* R3 Q* r6 N5 W9 y5 k+ |
}- p5 K4 E. [& l5 ?
break;
& o) Z3 z$ {. m( `8 b# l' D. o
case RUN:
step_count++; // 步数加1+ h: f' Z' L4 i6 x$ m
if(srd.dir==CW)
{
step_position++; // 绝对位置加1
}% X% Z4 d0 N( X7 q
else
{' M* j ?8 E/ H% v# r/ X
step_position--; // 绝对位置减1& m* s) h: t. b$ t- F) n/ D+ k9 J
}
new_step_delay = srd.min_delay; // 使用min_delay(对应最大速度speed)
if(step_count >= srd.decel_start) // 需要开始减速/ ^: U$ E, x8 Q0 c6 w" @
{/ ~4 k D: t: J- B- f
srd.accel_count = srd.decel_val; // 减速步数做为加速计数值7 z) P; {8 A1 Z
new_step_delay = last_accel_delay;// 加阶段最后的延时做为减速阶段的起始延时(脉冲周期)) T0 c7 W" K9 o2 N: m
srd.run_state = DECEL; // 状态改变为减速
}8 d& A/ P! ?9 U$ J# P
break;1 H6 X; v4 u4 e. F0 z
4 {" Q- V! a! L0 D3 E2 v1 E. J) W
case DECEL:) h ~9 T: p. `9 r
step_count++; // 步数加1
if(srd.dir==CW)4 \: ]" q% ?& `) g& ~ N
{
step_position++; // 绝对位置加1
}
else
{8 B$ Y' b0 _6 J! d5 i3 G @. m9 e4 _/ R
step_position--; // 绝对位置减16 W9 s `) |$ [
}* e! M% X( H3 s" I" B! Y' A
srd.accel_count++;9 m s9 E3 G7 T% K5 R& Y
new_step_delay = srd.step_delay - (((2 * srd.step_delay) + rest)/(4 * srd.accel_count + 1)); //计算新(下)一步脉冲周期(时间间隔)( @5 v0 A7 G+ i2 V4 ]
rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
//检查是否为最后一步 Y; @/ e ]6 ~% i9 b) t
if(srd.accel_count >= 0)& A0 ?2 }; f9 h( L: P: V3 s
{* X9 ?* D+ D8 E3 x2 e) G" j& k6 x) i2 Z
srd.run_state = STOP;
}% z9 _$ b% O' \8 C& b
break;
} + T1 o* q$ C7 N+ I
srd.step_delay = new_step_delay; // 为下个(新的)延时(脉冲周期)赋值
}
}& f, v7 B+ f7 W3 r
}9 z1 Z" W) f7 B, n1 J k b( |
/**- V0 {# L6 p. A$ Q& X
* 函数功能: 相对位置运动:运动给定的步数
* 输入参数: step:移动的步数 (正数为顺时针,负数为逆时针).5 E8 R, h7 R( L' A N" \
accel 加速度,实际值为accel*0.1*rad/sec^2' y( o7 }& j6 _( A( ^0 a& C% N* ~2 p
decel 减速度,实际值为decel*0.1*rad/sec^2( U! H+ P1 o! F. b3 i
speed 最大速度,实际值为speed*0.1*rad/sec) e( M5 I& k5 R/ V4 E- j, H# K( O6 J) v
* 返 回 值: 无
* 说 明: 以给定的步数移动步进电机,先加速到最大速度,然后在合适位置开始
* 减速至停止,使得整个运动距离为指定的步数。如果加减速阶段很短并且2 L0 M/ {' `3 i' s. s
* 速度很慢,那还没达到最大速度就要开始减速& ]1 t2 L9 G m, m, Y5 r1 v
*/
void STEPMOTOR_AxisMoveRel(__IO int32_t step, __IO uint32_t accel, __IO uint32_t decel, __IO uint32_t speed)
{
__IO uint16_t tim_count;, e U: R9 L0 |: p$ v: ?
// 达到最大速度时的步数7 v6 ~/ D' v: c3 P _
__IO uint32_t max_s_lim;
// 必须要开始减速的步数(如果加速没有达到最大速度)( N8 w) l5 b3 g9 U. I; e6 d& ]+ D
__IO uint32_t accel_lim;. n m; Z3 t$ o" K
if(step < 0) // 步数为负数) |2 z* {6 t0 t) q
{
srd.dir = CCW; // 逆时针方向旋转7 m. K$ G% H% p8 B# k; w
STEPMOTOR_DIR_REVERSAL();( T" M a9 M0 ~0 f
step =-step; // 获取步数绝对值
}4 @2 @. f5 c; r; @) c
else
{
srd.dir = CW; // 顺时针方向旋转 a+ t1 `) P3 C; h. m$ i- j) d
STEPMOTOR_DIR_FORWARD();
}
if(step == 1) // 步数为1
{
srd.accel_count = -1; // 只移动一步2 `0 h0 [! c K, `2 q" W6 T0 W
srd.run_state = DECEL; // 减速状态.
srd.step_delay = 1000; // 短延时
}1 V" B2 P% X1 v+ i" D( ?# q2 b# K
else if(step != 0) // 如果目标运动步数不为0 u* s6 U ]5 w# k: [* J" d
{7 A- p+ J; d" w7 F2 q
// 我们的驱动器用户手册有详细的计算及推导过程
// 设置最大速度极限, 计算得到min_delay用于定时器的计数器的值。. D* T/ m8 ~" Q7 S
// min_delay = (alpha / tt)/ w
srd.min_delay = (int32_t)(A_T_x10/speed);+ U4 \ W4 q) o3 w O4 |
; `" a% G* N# @( p6 T/ N
// 通过计算第一个(c0) 的步进延时来设定加速度,其中accel单位为0.1rad/sec^2. A8 |' O; a, X; R: Q
// step_delay = 1/tt * sqrt(2*alpha/accel)
// 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);
// 计算多少步之后达到最大速度的限制9 g5 E/ s2 Y6 i" X" [: f- A/ g
// max_s_lim = speed^2 / (2*alpha*accel)
max_s_lim = (uint32_t)(speed*speed/(A_x200*accel/10));
// 如果达到最大速度小于0.5步,我们将四舍五入为0/ e: f% `! h3 t0 u
// 但实际我们必须移动至少一步才能达到想要的速度
if(max_s_lim == 0){* o# x u$ D: q
max_s_lim = 1;; w8 X) l* z' _. X1 O, q
}
// n1 = (n1+n2)decel / (accel + decel)
accel_lim = (uint32_t)(step*decel/(accel+decel));
// 我们必须加速至少1步才能才能开始减速.- e1 Z ^0 X) M1 c& P
if(accel_lim == 0){4 J, L9 p7 m/ ^& ^* `' ^
accel_lim = 1;
}; ^+ C/ ]4 t) S G) e7 y% [
3 x8 ^8 O& S8 n/ L: z# ^# m
// 使用限制条件我们可以计算出减速阶段步数2 A( a, v! f6 i& a- h
if(accel_lim <= max_s_lim){
srd.decel_val = accel_lim - step;8 y, c) R: Y7 Z& o5 [8 {
}
else{
srd.decel_val = -(max_s_lim*accel/decel);
}6 B- b* |8 o9 B3 l1 ~3 j
// 当只剩下一步我们必须减速) Y6 c( e( K e& U: m
if(srd.decel_val == 0){
srd.decel_val = -1;
}
// 计算开始减速时的步数+ b; I; J, Q- @& l6 _
srd.decel_start = step + srd.decel_val;, {5 i0 ]! O; Y9 n4 U" x3 N4 ]
// 如果最大速度很慢,我们就不需要进行加速运动* r( l7 E6 x0 ?( x' U$ L2 E4 @
if(srd.step_delay <= srd.min_delay){
srd.step_delay = srd.min_delay;
srd.run_state = RUN;/ F# D ?5 U" n# |" A
}( F. { \, x, T( u$ ]3 Y; s8 ~
else{( T, k- C& N, e0 Q/ T" c4 s
srd.run_state = ACCEL;
} : O% ^$ f F( v0 i
// 复位加速度计数值# e; c. R( W, x( T6 x
srd.accel_count = 0;
}; p7 {& K5 q+ ?* o$ m1 U
MotionStatus = 1; // 电机为运动状态- }6 N3 I0 V1 ^: E5 X
tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);6 p5 p! s& d& u
__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); // 使能定时器通道 9 Q- S5 h4 ^5 C5 e+ w
STEPMOTOR_OUTPUT_ENABLE();, t9 ?; s" \& C
}
1、机器人和工业驱动器7 L) `2 k- S! s! v6 a: d' t& O
2、纺织、缝纫机
3、包装机械
4、工厂和实验室自动化
5、高速 3D 打印机$ k9 }' N& s2 T
6、液体处理
7、医疗+ h! {) t. [, s6 r$ v
8、办公自动化( w( x, `5 z7 k" j5 V, y" q9 r3 j
9、有线闭路电视
10、自动取款机、现金回收
11、泵和阀门
电机驱动主芯片采用TMC2160
TMC2160和5160区别:5160带UART控制及智能定位控制(如速度控制、位置控制);
TMC2160和TMC260 TMC262区别:以前版本需要通过SPI接口设置细分、电流等,新的TMC2160可通过拨码开关设置;
有条件的输入输出最好加些滤波和保护,输出加脉冲整形(比如加74HC14)
拨码开关ON:设置为高电平1,反之低电平0
细分设置:CFG1、CFG0
CFG1、CFG0:
11:64细分# U" r0 S- ^' a! I) P+ f2 J2 @+ k
10:32细分
01:16细分
00:8细分
运行电流设置:CFG4、CFG3、CFG2
CFG4、CFG3、CFG2:
111:IRUN=31, T! l1 W F+ a; `5 e
110:IRUN=280 m, E. x/ C7 D
101:IRUN=26
100:IRUN=24
011:IRUN=22) S. W( P) h# x* [+ Y- o
010:IRUN=206 l3 x# M: z: Z) V( L0 }+ ~* F
001:IRUN=18
000:IRUN=16( Z# A( e" x/ T& B, p7 A: S
Irms=Vfs/(IRUN/32)/(Rsense*1.414); 2 Y, m% z: {4 C" r, g( Z1 h' @
Vfs =325mV,Rsense为0.05欧时,则最大电流为4.5A左右;; T3 _- _) I1 K# a
CFG5:* k0 A/ h/ Z' w/ I
1:SpreadCyle模式,低速、低平稳运行模式
0:SpreadCyle模式,高速、高运动稳定模式
保持电流设置:CFG6
CFG6:& H* u* n/ l2 n; M2 a, A
1:保持电流=运行电流/2
0:保持电流=运行电流7 _# l$ i" ]5 x, T h: _
DIR+STEP接口模式位置控制(无需SPI接口)
COM端:接24V或12V或5V
DRV_ENN、STER、DIR:接集电极开路输出( R# q! _; J2 {, g% s8 H
为测试方便:
COM端:接3.3V
DRV_ENN:使能,接PB14. p. P' d/ x0 V0 b* B% U
DIR:方向, PB15
STEP:脉冲,PA8