|
楼主 |
发表于 2017-12-22 09:55:36
|
显示全部楼层
本帖最后由 am3359 于 2017-12-22 10:00 编辑
用VB写了个测试程序
Sub Calculator()
Dim accel_count, step_delay, min_delay, decel_val, decel_start As Long '-2,147,483,648 ~ 2,147,483,647
Dim A_T_x100, T1_FREQ_148, A_SQ, A_x20000 As Long '-2,147,483,648 ~ 2,147,483,647
Dim ALPHA As Double '-1.67E+308 ~ 1.67E+308
Dim run_state As Integer 'STOP:0ACCEL:1DECEL:2RUN:3 '-32768 ~ 32767
Dim step&, accel&, decel&, speed&, max_s_lim&, accel_lim&
Dim step_count&, rest&, sum&, new_step_delay&, last_accel_delay&
ALPHA = Val(Worksheets("stepmoto1").Cells(11, 3).Value)
A_T_x100 = ALPHA * Val(Worksheets("stepmoto1").Cells(7, 3).Value) * 100
T1_FREQ_148 = Val(Worksheets("stepmoto1").Cells(7, 3).Value) * 0.676 / 100
A_SQ = ALPHA * 2 * 100000 * 100000
A_x20000 = ALPHA * 20000
step = Val(Worksheets("stepmoto1").Cells(20, 3).Value)
accel = Val(Worksheets("stepmoto1").Cells(21, 3).Value) * 100
decel = Val(Worksheets("stepmoto1").Cells(22, 3).Value) * 100
speed = Val(Worksheets("stepmoto1").Cells(23, 3).Value) * 100
If Val(Worksheets("stepmoto1").Cells(20, 3).Value) = 1 Then
' 如果只移动一步,直接减速
accel_count = -1
' 进入减速状态 DECEL=2
run_state = 2
' 走一步时c0设置为2000
step_delay = 2000
Else
' 最小计数值 min_delay是最大速度时对应的c值,最大速度时c最小,c0~cn都不能小于min_delay
' 1MHz信号计数至少循环20次产生一次PWM信号,TIM2->ARR=20
' 要保证计数值c=ALPHA*T1_FREQ*100/speed>=20,最大速度speed<=157_079/细分数
min_delay = Int(A_T_x100 / speed) 'c = (alpha / tt)/ w
' c0=(((T1_FREQ*0.676)) * sqrt((ALPHA*2*100) / accel))>=20,计算出整步时accel<=7_178_156_159.2,2细分时accel<=3_589_078_079.6
step_delay = Int((T1_FREQ_148 * Int(Sqr(A_SQ / accel))) / 100) 'c0 = 1/tt * sqrt(2*alpha/accel)
' max_s_lim使用accel加速到speed需要发送的步数
' 由于accel和speed都放大了100倍计算结果需要除100 max_s_lim = speed*speed/(2*alpha*accel*100)
max_s_lim = Int(speed * speed / ((A_x20000 * accel) / 100)) '//speed*speed/(2*alpha*accel)
' 至少要走一步
If max_s_lim = 0 Then
max_s_lim = 1
End If
' 计算多少步开始减速n1=accel_lim
' 推导过程n1*accel = n2*decel -> n1*accel = (n1+n2-n1)*decel -> n1 = (n1+n2)*decel/(accel+decel)=step*decel/(accel+decel)
accel_lim = Int((step * decel) / (accel + decel)) 'n1=step*decel/(accel+decel)
' 减速过程至少有一步
If accel_lim = 0 Then
accel_lim = 1
End If
' 计算减速需要走的步数,取负值
If accel_lim <= max_s_lim Then '速度曲线为三角形
decel_val = accel_lim - step 'step=n1+n2 -> -n2=n1-step
Else '速度曲线为梯形
decel_val = Int(-max_s_lim * accel / decel) 'max_s_lim*accel=decel_val*decel
End If
' 减速停止前至少走一步
If decel_val = 0 Then
decel_val = -1
End If
' 计算减速前走多少步
decel_start = step + decel_val
' 如果设置的最大速度很低可以不加速
If step_delay <= min_delay Then
step_delay = min_delay
run_state = 3
Else
run_state = 1
End If
' 复位计数器
accel_count = 0
End If
rest = 0
sum = 0
For step_count = 1 To step
Select Case run_state
Case 0 'STOP
'step_count = 0
rest = 0
sum = 0
Worksheets("stepmoto1").Cells(step_count + 1, 8).Value = step_count
Worksheets("stepmoto1").Cells(step_count + 1, 9).Value = "S"
Case 1 'ACCEL '一般运动先进这里
sum = sum + step_delay
Worksheets("stepmoto1").Cells(step_count + 1, 8).Value = step_count
Worksheets("stepmoto1").Cells(step_count + 1, 9).Value = "A"
Worksheets("stepmoto1").Cells(step_count + 1, 10).Value = step_delay
Worksheets("stepmoto1").Cells(step_count + 1, 11).Value = sum
'step_count++
accel_count = accel_count + 1
new_step_delay = step_delay - (((2 * step_delay) + rest) \ (4 * accel_count + 1)) '计算当前的c
rest = ((2 * step_delay) + rest) Mod (4 * accel_count + 1) '取整后的余数保留,在下次计算中加进去,减少误差
If step_count >= decel_start Then
'计数到减速开始位置
accel_count = decel_val
run_state = 2
ElseIf new_step_delay <= min_delay Then
'若 c<=min_delay 则 c=min_delay 匀速
'printf("B\t%d\t%d",new_step_delay,min_delay)
last_accel_delay = new_step_delay '保存最后一个加速值,此处保存的值可能超过设定的最高速度??
new_step_delay = min_delay
rest = 0
run_state = 3
End If
Case 3 'RUN '初始速度就是最高速度直接进这里
sum = sum + step_delay
Worksheets("stepmoto1").Cells(step_count + 1, 8).Value = step_count
Worksheets("stepmoto1").Cells(step_count + 1, 9).Value = "R"
Worksheets("stepmoto1").Cells(step_count + 1, 10).Value = step_delay
Worksheets("stepmoto1").Cells(step_count + 1, 11).Value = sum
'step_count++
new_step_delay = min_delay
If step_count >= decel_start Then
accel_count = decel_val
' Start decelration with same delay as accel ended with.
new_step_delay = last_accel_delay
run_state = 2
End If
Case 2 'DECEL '走1步进这里
sum = sum + step_delay
Worksheets("stepmoto1").Cells(step_count + 1, 8).Value = step_count
Worksheets("stepmoto1").Cells(step_count + 1, 9).Value = "D"
Worksheets("stepmoto1").Cells(step_count + 1, 10).Value = step_delay
Worksheets("stepmoto1").Cells(step_count + 1, 11).Value = sum
'step_count++
accel_count = accel_count + 1
new_step_delay = step_delay - (((2 * step_delay) + rest) \ (4 * accel_count + 1)) '计算当前的c
rest = ((2 * step_delay) + rest) Mod (4 * accel_count + 1) '取整后的余数保留,在下次计算中加进去,减少误差
If accel_count >= 0 Then
run_state = 0
End If
End Select
step_delay = new_step_delay
DoEvents
Next step_count
End Sub |
|