搜索
bottom↓
回复: 19

如何用FPGA实现直线插补和圆弧插补控制多轴联动?

[复制链接]

出0入0汤圆

发表于 2017-2-18 09:41:17 | 显示全部楼层 |阅读模式
本帖最后由 王涛 于 2017-2-18 14:01 编辑

本人想做一个脱机的CNC系统用的是ARM+FPGA架构。ARM端做UI和G代码解析以及前瞻处理和路径规划,FPGA实现直线插补控制和圆弧插补控制多轴联动。现在ARM 端的程序基本OK。问题就在FPGA这边有做过的能不给点提示要怎么搞?
ARM用的是STM32F4开DSP和FPU速度感觉还可以,FPGA的DDA插补模块希望有直线插补和圆弧插补两部分,两种插补方式在一次插补过程中,只能有一种处于工作状态。直线插补能够实现3个轴的脉冲输出,完成二维或三维的直线轨迹,而圆弧插补是实现两轴的脉冲输出,实现二维的圆弧轨迹。

下面是直线插补
`timescale 1ns/100ps
module dda(s_clk,start,x_start,x_end,puls_x,sign_x,
                       y_start,y_end,puls_y,sign_y);
                                                         
input  s_clk,start;                                 //s_clk为时钟信号,start=1时正常运行
output reg puls_x,sign_x;                //puls_x为输出脉冲信号,sign_x为工作方式信号(正转还是反转)
output reg puls_y,sign_y;        
input[3:0] x_start,x_end;                 //为输入坐标信号
input[3:0] y_start,y_end;

reg[3:0] coun_x=0;
reg[3:0] state_x;
reg[3:0] coun_y=0;
reg[3:0] state_y;

parameter S0 = 1'h0,
          S1 = 1'h1,
                         S2 = 1'h2,
                         S3 = 1'h3;
                        
parameter M0 = 1'h0,
          M1 = 1'h1,
                         M2 = 1'h2,
                         M3 = 1'h3;

always@(posedge s_clk)
begin
  if(!start)
    begin
           puls_x = 0;
                sign_x = 0;
                state_x = S0;
                if(x_end >=x_start)
                  begin
                    sign_x = 1'b1;
                         coun_x = x_end - x_start;
                        end
       else
        begin
          sign_x = 1'b0;
          coun_x = x_start - x_end;
        end                        
        
         end
  else
    begin
      case(state_x)
                  
                          S0:
                             begin
                             if(coun_x)
                                     begin
                                            coun_x = coun_x-4'b0001;
                                                 puls_x = 1'b1;
                                                 state_x = S1;
                                                 end
                                        end
                                       
                                 S1:
                                     begin
                                     puls_x = 1'b0;
                                          state_x = S2;
                                          end
                                          
                                 S2:
                 begin
                  if(coun_x)
                                     begin
                                            coun_x = coun_x-4'b0001;
                                                 puls_x = 1'b1;
                                                 state_x = S3;
                                                 end
                                         //else          state_x <= S0;
                              
                                        end                                          
                                       
                                        S3:
                                     begin
                                     puls_x = 1'b0;
                                          state_x = S0;
                                          end
                        
                        default: puls_x =1'bZ;
                        
                 endcase
        end
end

/*--------------Y轴方向-----------------------------*/

always@(posedge s_clk)
begin
  if(!start)
    begin
           puls_y = 0;
                sign_y = 0;
                state_y = S0;
                if(y_end >=y_start)
                  begin
                    sign_y = 1'b1;
                         coun_y = y_end - y_start;
                        end
       else
        begin
          sign_y = 1'b0;
          coun_y = y_start - y_end;
        end                        
        
         end
  else
    begin
      case(state_y)
                  
                          M0:
                             begin
                             if(coun_y)
                                     begin
                                            coun_y = coun_y-4'b0001;
                                                 puls_y = 1'b1;
                                                 state_y = S1;
                                                 end
                                        end
                                       
                                 M1:
                                     begin
                                     puls_y = 1'b0;
                                          state_y = S2;
                                          end
                                          
                                 M2:
                 begin
                  if(coun_y)
                                     begin
                                            coun_y = coun_y-4'b0001;
                                                 puls_y = 1'b1;
                                                 state_y = S3;
                                                 end                       
                                        end                                          
                                       
                                        M3:
                                     begin
                                     puls_y = 1'b0;
                                          state_y = S0;
                                          end
                        
                        default: puls_y =1'bZ;
                        
                 endcase
        end
end

endmodule        
                                          
下面为仿真效果

(原文件名:fz.JPG)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入131汤圆

发表于 2017-2-18 10:08:55 | 显示全部楼层
lz你好,我最近也在研究这个

出0入442汤圆

发表于 2017-2-18 10:36:06 | 显示全部楼层
其实你这可以上运动控制芯片了,就是芯片比较贵。插补都可以通过查表去做,耗不了几个资源。多轴联动应该是控制轨迹吧,这个我不清楚。(PS:我也准备做一款控制系统,我前一段买了台DIY的桌面贴片机,精度惨不忍睹,准备改选成高精度全光学定位、超高速运动控制等一体化控制系统,目标是达到600PCS的贴片速度)

出0入0汤圆

发表于 2017-2-18 10:52:05 来自手机 | 显示全部楼层
这个工程感觉挺大,能动很容易,但是要实现减速,插补,运动规划就难了。而且没有这些根本没多大实用价值

出100入85汤圆

发表于 2017-2-18 21:31:42 来自手机 | 显示全部楼层
顶,支持你继续。

出0入0汤圆

发表于 2017-2-21 17:30:14 | 显示全部楼层
fpga 做这个是费力不讨好,插补运算要用到乘除法,挺耗资源的,做产品的话不如专用型dsp

出0入0汤圆

发表于 2017-2-21 18:09:56 来自手机 | 显示全部楼层
LinuxCNC之类的不是挺成熟的了吗,直接用就好了

出0入0汤圆

 楼主| 发表于 2017-2-22 10:33:08 | 显示全部楼层
本帖最后由 王涛 于 2017-2-22 10:37 编辑
SuBingEn 发表于 2017-2-21 18:09
LinuxCNC之类的不是挺成熟的了吗,直接用就好了


请问有在嵌入式上跑的LINUXCNC吗?有这方面的资料吗?如果有的话给个链接参考一下,谢谢。其实AVR上的GRBL就是一个很好的开源数控方案,里面就有直线和圆弧插补我移植到F4 168M上跑OS开FPU和DSP速度可以,用的是bresenham画线算法。属于软件插补,这里想用FPGA做硬件插补。

出0入300汤圆

发表于 2017-2-22 10:41:31 来自手机 | 显示全部楼层
我一直反对这种折腾,根本没有意义。因为你最后还是要带上电机才有意义。先不要说插补了,怎样调试电机先要搞清楚再回过头来看插补,就会发现以前的算法比较幼稚。另外,调试这个必须要有一个平台,起码20W起步吧。因为如果你的机架不行,你电机的刚性就调不上去,调高一点都嗡嗡响。刚性调不上去你滞后就大,滞后都大了,折腾各种插补干啥。然后电机的品种那就多了去了,起码典型的十几种要试一下吧,每一种的前馈调起来都区别很大。把条件准备好了,基本在你资金完全不成问题的情况下要18个月。然后再去研究插补,否则都是纸上谈兵。

出0入0汤圆

 楼主| 发表于 2017-2-22 11:03:52 | 显示全部楼层
ibmx311 发表于 2017-2-22 10:41
我一直反对这种折腾,根本没有意义。因为你最后还是要带上电机才有意义。先不要说插补了,怎样调试电机先要 ...

多读点书再聊。

出0入300汤圆

发表于 2017-2-22 11:18:20 来自手机 | 显示全部楼层
不就是起步走吗,你要咋地。你把你带上加减速的跑的最好的亮出来看看。

出0入0汤圆

 楼主| 发表于 2017-2-22 11:27:29 | 显示全部楼层
本帖最后由 王涛 于 2017-2-22 14:21 编辑
ibmx311 发表于 2017-2-22 11:18
不就是起步走吗,你要咋地。你把你带上加减速的跑的最好的亮出来看看。


最烦你这种一副高高在上不屑一顾的人

出0入300汤圆

发表于 2017-2-22 11:30:43 来自手机 | 显示全部楼层
自己感觉能做的不错的,都基本是没有测试条件的。最终平台要用激光干涉仪和激光跟踪仪看。这两件买到手130多就不见了。如果只是一个齐步走根本就不用这样折腾。这两件东西我十年前就自己花钱买了。到时候就知道了,就算是两轴的直线插补不用几年你都做不好。光是测试方案,就不知道做了多少。

出0入0汤圆

发表于 2017-2-22 12:08:54 | 显示全部楼层
ibmx311是老司机 听他的没错

出0入0汤圆

发表于 2017-2-22 12:19:45 | 显示全部楼层
本帖最后由 3DA502 于 2017-2-22 12:21 编辑
王涛 发表于 2017-2-22 11:27
最烦你这种一副高高在上不屑一顾的人,这种人要么就是书读的少不知道自己不知道浮躁,要么就是岁数太小幼 ...


小屁孩     

你态度不对,骂人之前至少要看看这个人发过什么帖子

出0入0汤圆

发表于 2017-2-22 12:20:44 来自手机 | 显示全部楼层
grbl  marlin   linuxcnc 可以学习学习  实用都不行   不接设备试试,都不知道问题在哪,反向间隙都有好几种方式

出0入300汤圆

发表于 2017-2-22 12:32:00 | 显示全部楼层
反向间隙肯定是都会有的,只不过设备越精密越不明显而已。全新的大畏卧加反向间隙0.5丝左右,全新的DMG5轴反向间隙也差不多是这个数。这样的数据可以补也可以不补。惯量较大的时候有微量的反向间隙不见得是坏事。这些东西都没有电机带来的危害大。就电机而言,无论其编码器吹牛逼是多好,其实装配上就不可能达到很高的形位公差,垂直度稍微差一点,就极大的恶化了定位精度,所以好一点的机器都要用光栅尺再闭环。

出0入0汤圆

 楼主| 发表于 2017-2-22 12:37:54 | 显示全部楼层
本帖最后由 王涛 于 2017-2-22 14:21 编辑
3DA502 发表于 2017-2-22 12:19
小屁孩     

你态度不对,骂人之前至少要看看这个人发过什么帖子


看来都是老工程师了,可惜不是工程师的老师,我并没有骂人.

出0入300汤圆

发表于 2017-2-22 12:46:28 | 显示全部楼层
王涛 发表于 2017-2-22 12:37
看来都是老工程师了,可惜不是工程师的老师,我并没有骂人,什么事情喜欢习惯性否定,其实这种人已经老态 ...

我是一把年纪了,不过每天仍然在搬铁,就是这个苦逼的命,不会有翻身之日了。
不过,我一直信奉一句话,我们是绝对不可能超越前人的。
当然了,前人是一定会被超越的,但一定不是我们。

出0入0汤圆

发表于 2017-2-22 12:54:19 | 显示全部楼层
王涛 发表于 2017-2-22 12:37
看来都是老工程师了,可惜不是工程师的老师,我并没有骂人,什么事情喜欢习惯性否定,其实这种人已经老态 ...

先驱翻翻google 万方吧     DDA这个算法有讲义    灌水论文一大堆
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 15:29

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表