你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
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外设
/**
* 函数功能: 定时器中断服务函数
* 输入参数: 无) l0 W @9 J/ W, t
* 返 回 值: 无+ E1 [3 ` j2 S2 n- X6 Y3 k
* 说 明: 实现加减速过程! R" {3 @4 `* K
*/( E/ ] Y2 _# T- }& C. C
void STEPMOTOR_TIMx_IRQHandler(void)//定时器中断处理
{
__IO uint16_t tim_count=0;7 m; E/ w) g# `7 r8 \4 Y+ }( W; {
// 保存新(下)一个延时周期
uint16_t new_step_delay=0;' Y+ i' A0 s8 O
// 加速过程中最后一次延时(脉冲周期).
__IO static uint16_t last_accel_delay=0;
// 总移动步数计数器
__IO static uint32_t step_count = 0;
// 记录new_step_delay中的余数,提高下一步计算的精度3 e0 W @ }$ f8 N2 o0 a$ D0 q5 X
__IO static int32_t rest = 0;! |: p5 R( b. H3 w5 E2 G
//定时器使用翻转模式,需要进入两次中断才输出一个完整脉冲1 L% o4 f D4 A, N+ H5 C+ l0 r
__IO static uint8_t i=0;$ }+ \ }3 j8 B/ A
* G) \$ L0 Z% ? b5 Z1 B/ K$ C3 ^
if(__HAL_TIM_GET_IT_SOURCE(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx) !=RESET)6 j, }3 L, N* }! P X3 Q: j/ r
{1 K4 W$ @# Z3 ~0 w5 I! o
// 清楚定时器中断
__HAL_TIM_CLEAR_IT(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx);( R9 u: k2 e0 z5 U
, s3 P0 S) a& M- U/ x& J
// 设置比较值
tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);- ]- m3 m8 _! o; L; X$ T
__HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay);
J, ^, h- B' M0 l7 k7 n8 K
i++; // 定时器中断次数计数值
if(i==2) // 2次,说明已经输出一个完整脉冲
{
i=0; // 清零定时器中断次数计数值1 h, ~! n+ r; C3 h
switch(srd.run_state) // 加减速曲线阶段
{
case STOP:
step_count = 0; // 清零步数计数器
rest = 0; // 清零余值* d0 F# H/ v1 `* q* Z* L8 R
// 关闭通道
TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_DISABLE); ! I0 K! t# M! r" \; n$ C: B6 g
__HAL_TIM_CLEAR_FLAG(&htimx_STEPMOTOR, STEPMOTOR_TIM_FLAG_CCx);/ |( P% n8 a! X" _& ^9 m
STEPMOTOR_OUTPUT_DISABLE();8 ?6 F* \' B e% w7 \
MotionStatus = 0; // 电机为停止状态
break;6 D5 T; C% L. y' z( h3 B
0 W% x7 \# R; Q6 G
case ACCEL:
step_count++; // 步数加1
if(srd.dir==CW)
{
step_position++; // 绝对位置加1
}8 n8 q( B7 m2 |' v) S. o
else
{( {3 c, z5 V2 B2 j A/ A* ^
step_position--; // 绝对位置减12 I( z5 K8 V6 U% x9 N2 W0 Q
}
srd.accel_count++; // 加速计数值加1, p! @2 z) H3 F8 d% |9 m4 K
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);// 计算余数,下次计算补上余数,减少误差/ @5 x. {0 W# C( O* ]
if(step_count >= srd.decel_start)// 检查是够应该开始减速4 G& O' W- e6 ]. c% ]4 D# c
{* T; l9 X3 f( W Q2 L! ?; n. _
srd.accel_count = srd.decel_val; // 加速计数值为减速阶段计数值的初始值
srd.run_state = DECEL; // 下个脉冲进入减速阶段( d @( t0 p3 o" |0 r: n- H1 O s
}+ F4 V' `4 N0 `1 q2 @; d
else if(new_step_delay <= srd.min_delay) // 检查是否到达期望的最大速度
{0 y+ p6 }, a! n; o
last_accel_delay = new_step_delay; // 保存加速过程中最后一次延时(脉冲周期)0 e* b" @9 h5 t% o0 M& }2 j* b
new_step_delay = srd.min_delay; // 使用min_delay(对应最大速度speed)
rest = 0; // 清零余值' j+ l$ s. X" w( n8 N& [2 T4 S
srd.run_state = RUN; // 设置为匀速运行状态
}
break;% F3 q8 K; ^/ {7 ]; L$ h
* V5 Q: A e+ ^" e5 T. T
case RUN:
step_count++; // 步数加1
if(srd.dir==CW)
{ 7 z; c" H+ {; ^$ h
step_position++; // 绝对位置加1! y/ K0 b j$ H! G8 R
}) B( D3 x. ?% M
else" V b7 `( y/ [+ E" \
{
step_position--; // 绝对位置减1
}3 G2 ]' d# j5 J \: w
new_step_delay = srd.min_delay; // 使用min_delay(对应最大速度speed)1 r3 d% P6 x3 v% g8 F" B4 t
if(step_count >= srd.decel_start) // 需要开始减速, d+ Y- D( Q* B9 r2 L
{
srd.accel_count = srd.decel_val; // 减速步数做为加速计数值8 E( M3 O: w( Z y" M! `) [7 {
new_step_delay = last_accel_delay;// 加阶段最后的延时做为减速阶段的起始延时(脉冲周期)9 C3 s$ A; T3 c3 _5 j
srd.run_state = DECEL; // 状态改变为减速* c% ?8 _" y# D
}; O8 B* ~3 O( I, Z
break;2 P" v8 \* _7 Q( M6 G. r' z
case DECEL:3 l! j+ |5 \' h6 R" i& c' O
step_count++; // 步数加1
if(srd.dir==CW); h7 ?9 I, ]5 R
{
step_position++; // 绝对位置加1$ D$ Q1 C, m/ V* h$ Z
}
else
{
step_position--; // 绝对位置减1
}
srd.accel_count++;2 Q& f" ?; H/ ]( l% z @
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 @* R# \& L8 e& @. z0 P1 u
7 P, c* f- M1 g0 {( U+ e6 x
//检查是否为最后一步
if(srd.accel_count >= 0)
{! f3 x- w$ V% D- l4 [+ l+ ?
srd.run_state = STOP;
}0 l' H/ y9 L' w# A% S3 e, M
break;
} & r; v6 [; L5 L9 L3 h# A* |
srd.step_delay = new_step_delay; // 为下个(新的)延时(脉冲周期)赋值
}3 l+ Y0 J8 d/ e
}
}6 t4 Y ^* x. l% l0 k: y
/**
* 函数功能: 相对位置运动:运动给定的步数
* 输入参数: step:移动的步数 (正数为顺时针,负数为逆时针).: R4 B$ I8 A5 M0 a) V S
accel 加速度,实际值为accel*0.1*rad/sec^2
decel 减速度,实际值为decel*0.1*rad/sec^2
speed 最大速度,实际值为speed*0.1*rad/sec/ S5 D; J% ~6 d- S% p
* 返 回 值: 无 k2 W- e( z; q0 M# U- V
* 说 明: 以给定的步数移动步进电机,先加速到最大速度,然后在合适位置开始. f9 G: i# s9 ?5 P z M3 n6 j
* 减速至停止,使得整个运动距离为指定的步数。如果加减速阶段很短并且
* 速度很慢,那还没达到最大速度就要开始减速
*/
void STEPMOTOR_AxisMoveRel(__IO int32_t step, __IO uint32_t accel, __IO uint32_t decel, __IO uint32_t speed)
{
__IO uint16_t tim_count;) f! X2 {, ]# s
// 达到最大速度时的步数
__IO uint32_t max_s_lim;
// 必须要开始减速的步数(如果加速没有达到最大速度)/ v0 d. R/ k& }- n8 R
__IO uint32_t accel_lim;
# W7 j. H4 s: y& i
if(step < 0) // 步数为负数
{
srd.dir = CCW; // 逆时针方向旋转
STEPMOTOR_DIR_REVERSAL();
step =-step; // 获取步数绝对值
}
else
{
srd.dir = CW; // 顺时针方向旋转
STEPMOTOR_DIR_FORWARD();
}/ y/ m* D' z6 S0 S" ]
if(step == 1) // 步数为1
{
srd.accel_count = -1; // 只移动一步# E3 q; L7 p. y8 y" ~5 G& {0 m
srd.run_state = DECEL; // 减速状态.
srd.step_delay = 1000; // 短延时
}4 k1 A$ }( L9 |0 K" ?) t" i) o) n
else if(step != 0) // 如果目标运动步数不为0
{* w, g3 d1 C9 _
// 我们的驱动器用户手册有详细的计算及推导过程0 T' j" b; f; a; _' k2 r
// 设置最大速度极限, 计算得到min_delay用于定时器的计数器的值。3 a, C# K: A) T3 w" a6 u( d( t
// min_delay = (alpha / tt)/ w
srd.min_delay = (int32_t)(A_T_x10/speed);2 O5 a0 r) \) N2 b# g4 w8 s
// 通过计算第一个(c0) 的步进延时来设定加速度,其中accel单位为0.1rad/sec^2! P0 Q" w7 P; N/ n6 M; g
// 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);
// 计算多少步之后达到最大速度的限制" L% f( v% _; d4 \# V2 J+ [
// max_s_lim = speed^2 / (2*alpha*accel), U9 ~8 O& z) J
max_s_lim = (uint32_t)(speed*speed/(A_x200*accel/10));. d! @- o; w1 k/ |5 y
// 如果达到最大速度小于0.5步,我们将四舍五入为0
// 但实际我们必须移动至少一步才能达到想要的速度 ]6 P1 Z$ j! o% v
if(max_s_lim == 0){ e/ @- n$ ^7 e/ d+ h% N' a; G
max_s_lim = 1;
}
// n1 = (n1+n2)decel / (accel + decel)5 V- ~3 R; t/ m
accel_lim = (uint32_t)(step*decel/(accel+decel));1 [$ R. v( z8 _3 m# J" N
// 我们必须加速至少1步才能才能开始减速. W# ^, S/ o/ }, R% Z
if(accel_lim == 0){4 {: M8 \$ a! F6 v& X8 e; a
accel_lim = 1;% e; I9 O1 D2 B# h- p, I
}
9 v0 x) N' k4 |8 g. G6 j8 a9 z
// 使用限制条件我们可以计算出减速阶段步数; Z. U/ f' @+ a2 O7 X7 N
if(accel_lim <= max_s_lim){0 d" W( {: c" B, [8 O
srd.decel_val = accel_lim - step;5 F0 {# ^3 _# W
}0 M5 S3 j/ E! O
else{6 R$ f- F# l& G5 r2 Y
srd.decel_val = -(max_s_lim*accel/decel);. W: \( s7 r. ^& H
}
// 当只剩下一步我们必须减速9 ^2 C7 }$ a. Z
if(srd.decel_val == 0){" c' A2 i/ a F1 j( R$ j
srd.decel_val = -1;5 c) |! G3 ^% n
}
// 计算开始减速时的步数0 ?; f( Z2 N" Y- N& O3 V
srd.decel_start = step + srd.decel_val;
# L: |" g8 X$ T( a. r
// 如果最大速度很慢,我们就不需要进行加速运动
if(srd.step_delay <= srd.min_delay){6 y) I$ c: \0 b/ g J+ l6 ]* K3 G* l) ^
srd.step_delay = srd.min_delay;: j4 e; t v& i8 n$ ~) {( @
srd.run_state = RUN;
}
else{
srd.run_state = ACCEL;
}
// 复位加速度计数值
srd.accel_count = 0;
}& K4 J2 F/ J Q- z; ]
MotionStatus = 1; // 电机为运动状态/ V" c1 |. ?' k: Y, @
tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);$ V' S" ~, ~8 O( 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); // 使能定时器通道 " E/ j8 e$ T1 A7 b/ ^% |; C/ F5 P
STEPMOTOR_OUTPUT_ENABLE();9 a4 a% R. H( f8 o$ B+ y
}7 |. N% L$ r8 u. n) v% {1 F$ L
1、机器人和工业驱动器9 p( S$ K" T* l/ ^- }
2、纺织、缝纫机9 b& ]3 V3 z+ m7 ?1 Y' U
3、包装机械2 L9 ^5 ?: Z0 u2 m( N# N
4、工厂和实验室自动化% [! n$ g" G3 O
5、高速 3D 打印机1 B6 C2 q& [4 [8 T1 d" r+ f
6、液体处理
7、医疗
8、办公自动化
9、有线闭路电视1 {4 i7 H" U5 j7 |# R g
10、自动取款机、现金回收) E0 l' ^0 O, z* m
11、泵和阀门
电机驱动主芯片采用TMC21607 N: a9 R F; H+ q
TMC2160和5160区别:5160带UART控制及智能定位控制(如速度控制、位置控制);5 S5 d- g0 m3 `% j' R1 t' h
TMC2160和TMC260 TMC262区别:以前版本需要通过SPI接口设置细分、电流等,新的TMC2160可通过拨码开关设置;9 L; Q$ Q6 b7 t, A; Z( K
有条件的输入输出最好加些滤波和保护,输出加脉冲整形(比如加74HC14)
拨码开关ON:设置为高电平1,反之低电平0
细分设置:CFG1、CFG0. h, ^$ j- l9 n& L. D, B
CFG1、CFG0:
11:64细分
10:32细分
01:16细分% Z4 Y4 ?) j0 S6 f \
00:8细分+ z. i) [, G. _( x
运行电流设置:CFG4、CFG3、CFG2
CFG4、CFG3、CFG2:0 S8 s1 @( p/ h* s! z
111:IRUN=31' Q* X% v) J1 G
110:IRUN=285 Z2 d& @5 u' U3 F
101:IRUN=269 p, B& v: e# D0 l% V) Y
100:IRUN=24
011:IRUN=22
010:IRUN=20
001:IRUN=185 W- o: B9 s1 z& b9 m. e) d
000:IRUN=16$ `) Y! i8 j$ W- ]3 l" U' }- J
Irms=Vfs/(IRUN/32)/(Rsense*1.414); , f6 E4 V- c+ G
Vfs =325mV,Rsense为0.05欧时,则最大电流为4.5A左右;( I) D1 z4 \+ k& t0 \$ }
CFG5:# w# j& l3 S: H* i+ D
1:SpreadCyle模式,低速、低平稳运行模式
0:SpreadCyle模式,高速、高运动稳定模式
保持电流设置:CFG6( n* J6 W! [( Q' {# f
CFG6:( w0 g5 z( z4 i- @' T6 s
1:保持电流=运行电流/21 o& T# f: V6 z2 I7 ~6 V8 p( y$ t
0:保持电流=运行电流6 b/ J- V( H' p! m4 u8 u5 [! Y
DIR+STEP接口模式位置控制(无需SPI接口)' M8 t& I0 H( T5 {( k2 m: r
COM端:接24V或12V或5V
DRV_ENN、STER、DIR:接集电极开路输出, f( B# o" b& j- V) W
为测试方便:
COM端:接3.3V
DRV_ENN:使能,接PB14
DIR:方向, PB15
STEP:脉冲,PA8' Y1 E% n$ o8 U# m1 _