打印
[应用方案]

单片机直线圆弧插补程序

[复制链接]
134|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jonas222|  楼主 | 2025-3-22 06:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
通过调用line(x1,y1,x2,y2,v)函数以及cytu(x1,y1,x2,a,b,r,v)和cyao(x1,y1,x2,a,b,r,v)三个命令便可实现任意圆弧和直线的插补,注意任意二字,比如直线命令,可以是水平线可以是竖直线,可以是从左往右也可从右往左,可以当做一个绘图仪使用,如果愿意进一步升级,简单修改加个Z轴做成数控铣床的控制器亦未尝不可。下面是整个源程序,有兴趣的可以参考参考。

#include <REG51.h>
#include <FLOAT.h>
#include <MATH.h>
sbit mai0=P1^0;
sbit mai1=P1^1;
sbit shuru=P0^0;
sbit dir0=P1^6;
sbit dir1=P1^7;
void delay(unsigned int t){
         unsigned int g;
                      while(t!=0){
                       for(g=0;g++;g<600);
           t--;
           }
        }
void mc_p0(signed long m0,unsigned int n0)
                       {if(m0<0){
               m0=-m0;
         dir0=1;
         }
      else{dir0=0;}
      while(m0--!=0){
                     mai0=0;
                     delay(n0/2);
            mai0=1;
            delay(n0/2);
                 }
        }
void mc_p1(signed long m1,unsigned int n1)
                       {if(m1<0){
               m1=-m1;
         dir1=1;
         }
      else{dir1=0;}
      while(m1--!=0){mai1=0;
                     delay(n1/2);
            mai1=1;
            delay(n1/2);
                 }
        }

void line(float x0,float y0,float x1,float y1,unsigned int v0){
     float k=0;
     float x=0;
     float y=0;
     float ys=0;
     signed long yc=0;
     x=x0;
     ys=y0;
     k=(y1-y0)/(x1-x0);
     if(x0==x1){
                mc_p1((y1-y0)*2,50000/v0);}
     if(y0==y1){
                mc_p0((x1-x0)*2,50000/v0);}
     if((x0!=x1)&&(y0!=y1)){
       if(x0<x1){    while(x<x1){
              mc_p0(2,50000/v0);
        x=x+1;
        y=k*(x-x1)+y1;
        yc=y-ys;
        ys=y;
        mc_p1(yc*2,50000/v0);
           }
        }
       if(x0>x1){    while(x>x1){
              mc_p0(-2,50000/v0);
        x=x-1;
        y=k*(x-x1)+y1;
        yc=y-ys;
        ys=y;
        mc_p1(yc*2,50000/v0);
           }
        }
           }
     }


void cytu(float x3,float y3,float x4,float a1,float b1,
          float r1,unsigned int v1){
                float xx;
          float yy;
          float yys;
          signed int yyc;
    xx=x3;
    yys=y3;
    if(x3<x4){
        while(xx<x4){
              mc_p0(2,50000/v1);
        xx=xx+1;
        yy=b1+sqrt(r1*r1-(xx-a1)*(xx-a1));
        yyc=yy-yys;
        yys=yy;
        mc_p1(yyc*2,50000/v1);
          }
           }
     if(x3>x4){
        while(xx>x4){
              mc_p0(-2,50000/v1);
        xx=xx-1;
        yy=b1+sqrt(r1*r1-(xx-a1)*(xx-a1));
        yyc=yy-yys;
        yys=yy;
        mc_p1(yyc*2,50000/v1);

          }
           }
        }
void cyao(float x5,float y5,float x6,float a2,float b2,
          float r2,unsigned int v2){
                float xxx;
          float yyy;
          float yyys;
          signed int yyyc;
    xxx=x5;
    yyys=y5;
    if(x5<x6){
        while(xxx<x6){
              mc_p0(2,50000/v2);
        xxx=xxx+1;
        yyy=b2-sqrt(r2*r2-(xxx-a2)*(xxx-a2));
        yyyc=yyy-yyys;
        yyys=yyy;
        mc_p1(yyyc*2,50000/v2);
          }
           }
     if(x5>x6){
        while(xxx>x6){
              mc_p0(-2,50000/v2);
        xxx=xxx-1;
        yyy=b2-sqrt(r2*r2-(xxx-a2)*(xxx-a2));
        yyyc=yyy-yyys;
        yyys=yyy;
        mc_p1(yyyc*2,50000/v2);
          }
           }
        }

void main (void){
                while(1){
         while(shuru==0){
       line(0,0,10,10,5); //直线命令,调用格式line(起点坐标x1,y1,终点坐标x2,y2,速度v)
       delay(100000);  //延时
       line(10,10,0,0,5);
       delay(100000);
       line(0,0,-20,0,5);
       delay(60000);
        cytu(-20,0,20,0,0,20,5); //位于本身圆心上面的圆弧命令,调用格式cytu(起点x1,y1,终点x2,圆心a,b,半径r,速度v)
       delay(60000);
        cyao(20,0,60,40,0,20,5);  //位于本身圆心下面的圆弧命令,调用格式cyao(起点x1,y1,终点x2,圆心a,b,半径r,速度v)
       delay(60000);
        cytu(60,0,20,40,0,20,5);
       delay(60000);
        cyao(20,0,-20,0,0,20,5); }

使用特权

评论回复
沙发
lidi911| | 2025-3-23 19:48 | 只看该作者
UI显示的函数库有标准处理方式

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

1494

帖子

0

粉丝