步进电机S曲线的生成

步进电机S曲线的生成步进电机的速度从 0 变为一个比较大的速度 需要一个加速过程 否则会产生振动或是电机的堵转 电机加速通常有 T 型曲线和 S 型曲线两种方式 S 型曲线相对于 T 型曲线 S 型曲线的速度不会突变 S 型曲线的原始公式如下 y K 1 Exp a b x K0 b0 Exp 是指数函数 由这个公式可以看出 y 会随着 x 的增大 逼近 K 把这个公式应用到电机控制之中 K 看成最大的速度 Vmax x 看成时间 t 的变

S型曲线公式
步进电机的速度从0变为一个比较大的速度,需要一个加速过程,否则会产生振动或是电机的堵转。电机加速通常有T型曲线和S型曲线两种方式。S型曲线相对于T型曲线,S型曲线的速度不会突变。S型曲线的原始公式如下:
y=K/(1+Exp(a-b*x))(K>0,b>0)




Exp是指数函数,由这个公式可以看出y会随着x的增大,逼近K。把这个公式应用到电机控制之中,K看成最大的速度Vmax,x看成时间t的变量,那么t=0时,就是电机的初始速度,即V0=Vmax/(1+Exp(a-b*(0)))=Vmax/(1+Exp(a));反推求出a与V0,Vmax之间的关系,a=In((Vmax-V0)/V0).b决定曲线的快慢,b越大V变化越快,也就越快接近Vmax。

S型变化曲线

软件界面需要设置的数据有:晶振频率nXtal,预分频nPrevXtal,步进电机驱动器细分nPrevMotor,运行的最大速度nMaxSpeed,达到最大速度时的位置坐标(对应界面上的极限)nMaxPoint以及a,b参数是通过滑动条设置,a对应起始速度,b对应加速快慢.

速度与自动重装载寄存器的关系
电机的转速的单位一般是rpm,即一分钟多少转.如果电机的转速是V(rpm),那么自动重装载寄存器的数据应该是多少?步进电机驱动器细分为nPrevMotor,那么单片机发脉冲的速度是nPrevMotorV/60每秒,即定时器一秒钟产生中断的个数。
1/(Xload/(nXtal/nPrevXtal))=(nPrevMotor

V/60)
Xload=60nXtal/(nPrevXtalnPrevMotor*V)
其中V=Vmax/(1+Exp(a-bt)),即
Xload=60

nXtal*(1+Exp(a-bt))/(nPrevXtalnPrevMotor*Vmax)






Xload是自动重装载寄存器的数据,nXtal是晶振频率,nPrevXtal是预分频系数。

VC生成数组的代码如下:

int nMaxPoint,nXtal,nPrevXtal,nPrevMotor,nMaxSpeed; nMaxPoint = GetDlgItemInt(IDC_EDIT_MAX_POINT); nXtal = GetDlgItemInt(IDC_EDIT_XTAL); nPrevXtal = GetDlgItemInt(IDC_EDIT_PREV_XTAL); nPrevMotor = GetDlgItemInt(IDC_EDIT_MOTOR_F); nMaxSpeed = GetDlgItemInt(IDC_EDIT_SPEED_MAX); double k; k= (double)nMaxSpeed; CString strArray; unsigned short nTimerCount; strArray.AppendFormat(_T("/*============================================================================\r\n")); strArray.AppendFormat(_T("晶振频率 = %d;\r\n"),nXtal); strArray.AppendFormat(_T("预分频频率 = %d;\r\n"),nPrevXtal); strArray.AppendFormat(_T("极限点 = %d;\r\n"),nMaxPoint); strArray.AppendFormat(_T("极限转速 = %d;\r\n"),nMaxSpeed); strArray.AppendFormat(_T("周脉冲数 = %d;\r\n"),nPrevMotor); strArray.AppendFormat(_T("S型曲线\r\n")); strArray.AppendFormat(_T("============================================================================*/\r\nunsigned int code WaitTable[]={\r\n")); for(int i= 0;i 
  

这个S曲线的显示使用的是一个Picture控件显示,根据输入晶振频率,预分频,最大速度,极限点。。来绘制,使用GDI相关接口在Picture控件窗口面绘制.代码如下:

int CSCurveDlg::DrawCurve(void) { CWnd* pWnd = GetDlgItem(IDC_EDIT_DISPLAY); if(NULL!=pWnd) { RECT rect; pWnd->GetClientRect(&rect); int nHeight = rect.bottom-rect.top-4; int nWidth = rect.right-rect.left-4; CDC* pDC = pWnd->GetDC(); pDC->FillSolidRect(&rect,RGB(255,255,255)); POINT p1,p2; int i; double y1,y2; double k; k = (double)GetDlgItemInt(IDC_EDIT_SPEED_MAX); int nYmax=DrawTable(pDC,nWidth,nHeight); int nMaxPoint = GetDlgItemInt(IDC_EDIT_MAX_POINT); CSliderCtrl* pSlider1 = (CSliderCtrl*)GetDlgItem(IDC_SLIDER_ACC); b=(double)(((double)pSlider1->GetPos())/20); for (i=0;i 
  
    MoveTo(p1); pDC->LineTo(p2); } } return 0; } 
  

源码下载

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/203314.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午10:05
下一篇 2026年3月19日 下午10:06


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号