写段直线插补算法,做CNC控制可用,欢迎拍砖
闲来无事,写段直线插补算法,做CNC控制可用,欢迎拍砖#define AXIS_X 0
#define AXIS_Y 1
#define AXIS_Z 2
typedef struct _line_t
{
int32_t x1;
int32_t y1;
int32_t x2;
int32_t y2;
}line_t;
typedef struct
{
int32_t x;
int32_t y;
int32_t z;
}state_t;
typedef struct
{
int32_t f;
int8_t dir_x;
int8_t dir_y;
int8_t dir_z;
int32_t delta_x;
int32_t delta_y;
int32_t delta_z;
int32_t len;
int32_t pos;
}line_drv_t;
line_drv_t drv;
state_t cnc_state;
void draw_moveto(x2,y2)
{
drv.f = 0;
if(x2>cnc_state.x)
{
drv.delta_x = x2 - cnc_state.x;
drv.dir_x = 1;
}else
{
drv.delta_x = cnc_state.x - x2;
drv.dir_x = -1;
}
if(y2>cnc_state.y)
{
drv.delta_y = y2 - cnc_state.y;
drv.dir_y = 1;
}else
{
drv.delta_y = cnc_state.y - y2;
drv.dir_y = -1;
}
drv.len = drv.delta_x + drv.delta_y;
drv.pos = 0;
//if(drv.f >= 0)
drv.f = drv.f - drv.delta_y;
}
void cnc_step(uint8_t axis)
{
switch(axis)
{
case AXIS_X:
cnc_state.x += drv.dir_x;
break;
case AXIS_Y:
cnc_state.y += drv.dir_y;
break;
}
printf("%d,%d\n",cnc_state.x,cnc_state.y);
}
void draw_move()
{
if(drv.f >= 0)
{
//move x
cnc_step(AXIS_X);
drv.f = drv.f - drv.delta_y;
}else
{
//move y
cnc_step(AXIS_Y);
drv.f = drv.f + drv.delta_x;
}
drv.pos++;
}
void cnc_int()
{
cnc_state.x = 100;
cnc_state.y = 100;
cnc_state.z = 0;
}
void test_cnc()
{
cnc_int();
draw_moveto(0,0);
while(drv.pos < drv.len)
{
draw_move();
}
printf("cnc\n");
} 看不明白 采用逐点比较法,用控制台输出结果
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_671594ZIQS8Q.JPG
(原文件名:1.JPG)
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_671595SCL8BO.JPG
(原文件名:2.JPG)
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_671596Z2ZJTS.JPG
(原文件名:3.JPG)
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_671597NB5GD2.JPG
(原文件名:4.JPG)
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_671598XDUDJR.JPG
(原文件名:5.JPG)
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_671599CUKNDU.JPG
(原文件名:6.JPG)
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_671600U9YR5P.JPG
(原文件名:轨迹.JPG) 两个坐标开环的CNC系统中应用比较普遍,不能实现多轴联动 这是两轴直线插补算法,改动一下可以驱动XY,YZ,XZ平面直线运动 不错顶顶!我刚按你的这个思路也写了个,请你给看看?
void line (u8 F,s32 X0,s32 Y0,s32 X1,s32 Y1)//F:进给速度 X0,Y0:X,Y轴起点坐标 X1,Y1:X,Y轴终点坐标
{
u8 x,y;
u32 i,j;
x=1;
y=1;
while(!(x|y)) //如果x,y都为0就说明位置到了
{
if(X1>X0) //终点坐标大于起点坐标
{
XS=1; //方向信号为高,电机正转
x=1;
}
else if (X1<X0)//起点坐标大于终点坐标
{
XS=0; //方向信号为0,电机反转
x=1;
}
else x=0; //起点坐标等于终点坐标,X轴不动
if(Y1>Y0)
{
YS=1; //方向信号为高,电机正转
y=1;
}
else if(Y1<Y0)
{
YS=0; //方向信号为0,电机反转
y=1;
}
else y=0;//起点坐标等于终点坐标,Y轴不动
i=X1*Y0-X0*Y1;
if(i>=0)
{
XP=1; //脉冲输出引脚
X0++;
}
else
{
YP=1; //脉冲输出引脚
Y0++;
}
delay(F); //吧速度值先在主程序转为倒数,然后直接当做延时值传递给延时函数
X0=0; //脉冲引脚拉低,一个脉冲输出完成。
Y0=0;
}
} 回复【5楼】xiaomage_2000
-----------------------------------------------------------------------
写段测试程序试试,我那段程序通过控制台输出,查看结果是不是预期输出就行
draw_move();是准备中断中调用的,通过修改中断触发周期就可以控制速度 bucuo 回复【6楼】superrf
回复【5楼】xiaomage_2000
-----------------------------------------------------------------------
写段测试程序试试,我那段程序通过控制台输出,查看结果是不是预期输出就行
draw_move();是准备中断中调用的,通过修改中断触发周期就可以控制速度
-----------------------------------------------------------------------
哦,呵呵,回头试试看,多谢你的资料! mark mark 不错顶顶 寻找加减速算法,希望高手们提供些资料,梯形,S形的都行 关注一下 mark 准备试试! mark 看来是个软件高手了。看不懂虽然。 mark 哥哥。写程序给个注释啊?眼睛花了。有点累。 楼主你好,可以给我们广大爱好者普及下什么是插补吗。 不错,今天刚好看到这 值得学习…… 高手就是不一样 谢谢 数字积分法 谢谢分享谢谢 逐点比较法 插补怎样? 谢谢分享。 谢谢分享! 谢谢分享···
页:
[1]