搜索
bottom↓
回复: 33

用stc15w和旧光驱移植arduino写字机GRBL之三:Bresenham算法

  [复制链接]

出0入0汤圆

发表于 2018-11-11 14:39:19 | 显示全部楼层 |阅读模式
本帖最后由 XTXB 于 2018-11-12 11:42 编辑

用stc15w4k32s4和旧光驱移植arduino写字机GRBL连载:
用stc15w和旧光驱移植arduino写字机GRBL之一:机架搭建
https://www.amobbs.com/thread-5701202-1-1.html

用stc15w和旧光驱移植arduino写字机GRBL之二:PCB制作
https://www.amobbs.com/thread-5701573-1-1.html

用stc15w和旧光驱移植arduino写字机GRBL之三:Bresenham算法
写了一个测试程序验证Bresenham算法,没有加减速,没有FIFO循环队列,运动时程序就傻等着,先跑起来增加点信心:

GRBL软件框架图:

步进电机驱动用定时器0完成,没有加减速,意外地,4988电机模块的step脉冲竟然用一句代码就搞定了:

  1. /***************************************************
  2. 定时器0溢出中断处理函数 步进电机step脉冲产生
  3. ***************************************************/
  4. void Insert_ISR_Timer0_Code(void)
  5. {
  6.         if(x_steper_out_flag==1)  //如果有x轴输出请求
  7.         {
  8.                 x_steper_out_flag=0;//清x轴输出请求标记
  9.                 X_STEP_BIT=0;  //驱动4988竟然只需极短的低电平脉冲
  10.                 if((K3_UP==1)&(K4_DOWN==1))X_STEP_BIT=1;
  11.                         //按键未按下才有Xstep脉冲输出                       
  12.         }
  13.         if(y_steper_out_flag==1) //如果有y轴输出请求
  14.         {               
  15.                 y_steper_out_flag=0;//清y轴输出请求标记
  16.                 Y_STEP_BIT=0;                       
  17.                 if((K1_LEFT==1)&(K2_RIGHT==1))Y_STEP_BIT=1;
  18.                         //按键未按下才有 Ystep脉冲输出       
  19.         }       
  20.                 TL0=0x0F; //步进电机以固定速度运行,24M时钟
  21.                 TH0=0xA1;
  22. }
  23. //
复制代码

Bresenham线段插补算法详解,下图是第一象限,其他象限改变步进电机方向即可获得:

C语言实现Bresenham线段插补算法,较DDA算法Bresenham避免了浮点运算:
  1. void plan_buffer_line(u16 x, u16 y){ //(x,y)为当前点的绝对坐标
  2.         static u16 step_event_count=0;//总步数
  3.         static u16 counter_x=0; static u16 counter_y=0; static u16 step_events_completed=0;//循环计数器       
  4.         if(x>=last_x){   //当前点在上一点的右边,(last_x,last_y)为上一点的绝对坐标
  5.                 X_DIRECTION_BIT=0;//第一四象限X电机旋转方向
  6.                 target_x= (x-last_x);//求相对坐标的绝对值
  7.         }else {  //当前点在上一点的左边
  8.                 X_DIRECTION_BIT=1;//第二三象限X电机旋转方向
  9.                 target_x= (last_x-x);//求相对坐标的绝对值
  10.         }//以上一点为原点的直角坐标系中,判断当前点在哪个象限从而决定xy电机的旋转方向
  11.         if(y>=last_y) {    //当前点在上一点的上边
  12.                 Y_DIRECTION_BIT=1;//第一四象限电机Y旋转方向
  13.                 target_y= (y-last_y);
  14.         }else {  //当前点在上一点的下边
  15.                 Y_DIRECTION_BIT=0;//第二三象限Y电机旋转方向
  16.                 target_y= (last_y-y);
  17.         }       
  18.         //DDA/Bresenham直线插补算法
  19.         if(target_x>=target_y)   step_event_count=target_x;
  20.                 else  step_event_count=target_y;//比较起点到终点xy坐标差,取最大坐标作为步进电机总运转步数
  21.         counter_x=step_event_count/2; counter_y=step_event_count/2;//右移1位,没有四舍五入
  22.         X_STEPPER_DISABLE_BIT=0;  Y_STEPPER_DISABLE_BIT=0;   //使能电机运转
  23.         last_x=x; last_y=y;  //保存当前点坐标,作为下一点的原点
  24.         for(step_events_completed=0;step_events_completed<step_event_count;step_events_completed++){
  25.                 counter_x+=target_x; counter_y+=target_y;
  26.                 if(counter_x>=step_event_count){
  27.                         x_steper_out_flag=1;        //X步进电机走一步标记
  28.                         counter_x-=step_event_count;
  29.                 }
  30.                 if(counter_y>=step_event_count){
  31.                         y_steper_out_flag=1;        //Y步进电机走一步标记
  32.                         counter_y-=step_event_count;
  33.                 }
  34.                 while(x_steper_out_flag);//等待步进电机脉冲输出完成,没有用环形队列FIFO,在这里傻等
  35.                 while(y_steper_out_flag);
  36.          }//循环直到线段的所有步数完成
  37.         X_STEPPER_DISABLE_BIT=1; Y_STEPPER_DISABLE_BIT=1; //禁止运转
  38. }
复制代码

舵机驱动用定时器2完成:
舵机的使用可参照贴子:https://www.amobbs.com/thread-5687693-1-1.html
  1. void write_Angle(unsigned char Channel,unsigned char value)
  2.         //舵机驱动函数,channel=通道,value=角度(0-180)
  3. {       
  4.         AUXR |= 0x10;                //定时器2开始计时
  5.         PWM_Value[Channel]=(value*27+1200);
  6. }

  7. ////定时器2,12T模式时钟24MHz ,输出1路高电平脉冲,剩下的时间为低电平补足20ms
  8. void timer2(void) interrupt 12
  9. {
  10.         AUXR &= B1110_1111;                //定时器2开始停止计时
  11.         switch(order)
  12.         {
  13.                 case 1:   
  14.                         SERVO_BIT=1; //开第0路
  15.                         TL2=(-PWM_Value[0])%256;
  16.                                 //(-PWM_Value[0])=(65536-PWM_Value[0]) 定时时间会更精准
  17.                         TH2=(-PWM_Value[0])/256; //赋值高电平时间
  18.                         break;
  19.                 case 2:
  20.                         SERVO_BIT=0;//关第0路
  21.                         TL2=(25536+PWM_Value[0])%256;
  22.                                 //1路脉冲输出完毕,凑足20ms剩下的低电平时间
  23.                         TH2=(25536+PWM_Value[0])/256;   
  24.                         order=0;
  25.                         break;
  26.         }
  27.                 AUXR |= 0x10;        //定时器2开始计时
  28.                 order++;
  29.                 AUXR |= 0x10;        //定时器2开始计时                       
  30. }
复制代码

下面是函数调用方法,点的坐标是手工算出的,傻瓜力大,是吧
画圆弧函数可参照帖子https://www.amobbs.com/thread-5687693-1-1.html
  1.   switch(ucKeySec) //按键服务状态切换
  2.   {       
  3.     case 1:// K1_Start键
  4.                 write_Angle(0,SERVO_put_value);        //落笔
  5.                 delay_ms(120);       
  6.                 plan_buffer_line(0,30*53.5);
  7.                 //53.5是丝杆的参数,4988 设置:MS1=1,MS2=1,MS3悬空,8分频
  8.                 plan_buffer_line(30*53.5,30*53.5);
  9.                 plan_buffer_line(30*53.5,0);
  10.                 plan_buffer_line(0,0);
  11.                 write_Angle(0,SERVO_lift_value);//抬笔       
  12.                 plan_buffer_line(0,15*53.5);
  13.                 write_Angle(0,SERVO_put_value);        //落笔
  14.                 delay_ms(120);
  15.                 bogenGZS(15*53.5, 15*53.5, 14.5*53.5, 3.14,  0);//画圆                       
  16.                 bogenGZS(15*53.5, 15*53.5, 14.5*53.5, 6.28,  3.14);       
  17.                 write_Angle(0,SERVO_lift_value);//抬起               
  18.                 plan_buffer_line(0.87*53.5,19.59*53.5);        //E               
  19.                 write_Angle(0,SERVO_put_value);        //落笔
  20.                 delay_ms(120);                                       
  21.                 plan_buffer_line(29.13*53.5,19.59*53.5);//C                                                       
  22.                 plan_buffer_line(6.27*53.5,2.98*53.5);//A                               
  23.                 plan_buffer_line(15*53.5,30*53.5);//D                                               
  24.                 plan_buffer_line(23.73*53.5,2.98*53.5);//B                                                       
  25.                 plan_buffer_line(0.87*53.5,19.59*53.5);        //E                       
  26.                 write_Angle(0,SERVO_lift_value);//抬起                               
  27.                 plan_buffer_line(0,0);                       
  28.                 ucKeySec=0;  
  29.         break;   
  30.     case 2:// K2_Stop键
  31.                 ip=~ip;
  32.                 if(ip==0)
  33.                         write_Angle(0,SERVO_put_value);        //落笔       
  34.                 else
  35.                         write_Angle(0,SERVO_lift_value);//抬笔
  36.                 ucKeySec=0;  
  37.         break;  
  38.   }   
复制代码

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2018-11-11 14:41:29 来自手机 | 显示全部楼层
楼主厉害

出0入0汤圆

发表于 2018-11-11 14:49:44 | 显示全部楼层
哇,感觉这个精度很好啊

出0入0汤圆

 楼主| 发表于 2018-11-11 15:04:07 | 显示全部楼层
贴子发错版块了,咋办?

出0入0汤圆

发表于 2018-11-11 15:39:49 | 显示全部楼层
不错  顶一个

出0入0汤圆

发表于 2018-11-11 15:52:56 来自手机 | 显示全部楼层
顶一个,厉害

出0入0汤圆

发表于 2018-11-11 16:21:45 | 显示全部楼层
必须顶一下!

出0入0汤圆

发表于 2018-11-11 16:30:16 | 显示全部楼层
不错 !!

出0入0汤圆

发表于 2018-11-11 17:19:17 | 显示全部楼层
楼主相当厉害

出0入0汤圆

发表于 2018-11-11 19:43:39 | 显示全部楼层
不错哦                     

出0入0汤圆

发表于 2018-11-11 20:17:07 来自手机 | 显示全部楼层
顶贴,好帖子

出0入0汤圆

发表于 2018-11-11 21:28:55 来自手机 | 显示全部楼层
顶一个!!

出0入0汤圆

发表于 2018-11-11 22:25:47 | 显示全部楼层
顶楼主,做得真不错。

出40入42汤圆

发表于 2018-11-11 22:42:06 | 显示全部楼层
好帖,顶撸主一个

出0入0汤圆

发表于 2018-11-12 09:41:12 | 显示全部楼层
厉害,支持一下


出0入0汤圆

发表于 2018-11-12 10:27:20 | 显示全部楼层
这个太溜了,顶楼主,期待更新~

出0入0汤圆

发表于 2018-11-12 12:18:47 | 显示全部楼层
顶楼主,做得真不错。

出0入0汤圆

发表于 2018-11-21 10:05:53 | 显示全部楼层
楼主相当厉害。顶楼主!

出0入0汤圆

发表于 2018-11-25 18:39:16 | 显示全部楼层
厉害的楼主,这个框架也是给力的。。

出0入0汤圆

发表于 2018-11-25 19:01:58 | 显示全部楼层
看着精度很好

出0入76汤圆

发表于 2018-11-26 08:16:41 | 显示全部楼层
手上还有好几个迷你DVD机的机芯组件, 没拆开看不知道能不能折腾

出0入0汤圆

发表于 2018-11-26 18:08:12 | 显示全部楼层
控制的很好,敬佩。

出0入0汤圆

发表于 2018-11-26 21:11:10 来自手机 | 显示全部楼层
厉害,顶起来

出0入0汤圆

发表于 2018-12-17 07:53:35 | 显示全部楼层
厉害,这个是高手

出0入0汤圆

发表于 2018-12-18 00:10:09 | 显示全部楼层
不错,顶一个

出0入0汤圆

发表于 2019-10-12 16:29:18 来自手机 | 显示全部楼层
楼主,能发整个工程文件?谢谢

出0入0汤圆

 楼主| 发表于 2019-10-16 09:02:09 | 显示全部楼层
ZJetWay 发表于 2019-10-12 16:29
楼主,能发整个工程文件?谢谢

我的代码太乱,只是实现了功能而已,拿不出手,GRBL是开源的,原版的代码更严谨,花时间啃原版更合算。

出0入0汤圆

发表于 2019-10-17 20:47:54 | 显示全部楼层
楼主谦虚了

出0入0汤圆

发表于 2020-1-30 13:34:16 | 显示全部楼层
楼主算法是自己写的吧,GRBL好像用的不是Bresenham算法吧!

出0入0汤圆

发表于 2020-1-30 14:37:09 | 显示全部楼层
很厉害。

出0入0汤圆

发表于 2020-2-7 21:01:03 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2020-2-7 23:04:58 | 显示全部楼层
谢谢分享 值得学习

出0入0汤圆

发表于 2020-6-22 09:16:55 | 显示全部楼层
太赞了,

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-4-21 00:32

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

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