6741|5

5

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

自制绘图仪 [复制链接]

绘图仪结构图:

















[local]1[/local]
走直线和画圆的程序:
#include "reg52.h"
#include "math.h"
sbit P00=P0^0;  //
sbit P01=P0^1;  //起笔、提笔控制端口
sbit P02=P0^2;  //上移
sbit P03=P0^3;  //下移
sbit P04=P0^4;  //左移
sbit P05=P0^5;  //右移
sbit P06=P0^6;  //提笔
sbit P07=P0^7;   //落笔
bit  atzqd=0;   //A电机停止启动    默认停止
bit  btzqd=0;   //B电机停止启动    默认停止
bit fz=0;   //是否给x,y赋值    默认否
bit qr=0;  //赋值后是否确认   默认否
bit qb=0; //是否起笔标志 默认否
bit tb=0; //是否提笔标志 默认否
unsigned char xian=0,hy=0;   //切换画不同线
unsigned char m,n,k,g;
float a=0;  //计算得到的A电机步数   
float b=0;  //计算得到的B步进电机的步数
bit azf=0;  //A运转方向  
bit bzf=0;  //B运转方向
bit yx=1; //按键重复允许   默认否
bit yw=1; //按键重复允许   默认否
bit yl=0; //落笔重复允许   默认否
float r;  //给x,y赋值的中间变量
unsigned char p=0,q=0;  //赋值和确认中间标志
float x1=0,x2=0;  //x坐标   //或起点和圆心坐标
float y1=0,y2=0;  //y坐标
float banjin=0,bj=0;   //圆的半径和半径步数
float x=0,y=0,e=0,f=0,u=0,v=0,o1=0,o2=0;
int s=25;//定义转动速度,数值越大电机转速越慢反之则快      
code unsigned char arunz[4]={0xf7,0xfb,0xfd,0xfe};  //A电机正转  
code unsigned char arunf[4]={0xfe,0xfd,0xfb,0xf7};  //A电机反转
code unsigned char brunf[4]={0xef,0xdf,0xbf,0x7f};  //B电机正转  
code unsigned char brunz[4]={0x7f,0xbf,0xdf,0xef};  //B电机反转   
void delay10ms(void) //延时程序     键盘的延时   
{
  unsigned char i,j;
  for(i=20;i>0;i--)
  for(j=248;j>0;j--);
}
void delay(m)//延时函数      步进电机的延时   
{
      for(n=0;n       for(k=0;k<50;k++);
}
void delay14s()
{
  unsigned char i,j,k;
  for(i=250;i>0;i--)
  for(j=250;j>0;j--)
  for(k=60;k>0;k--);
}
void qibi()
{
   P00=0; P01=1;
   delay14s();
   P00=1; P01=1;qb=0;tb=0;yl=1;
}
void tibi()
{
   P00=1; P01=0;
   delay14s();
   P00=1; P01=1;qb=0;tb=0;yl=0;
}
void azrun()// A正转运行  
{
   for(g=0;g<4;g++)
        {
         P1=arunz[g];
         delay(s);
        }
}
void afrun()// A反转运行   
{
     for(g=0;g<4;g++)
        {
         P1=arunf[g];
         delay(s);
        }
}
void bzrun()// B正转运行  
{
   for(g=0;g<4;g++)
       {
        P1=brunz[g];
        delay(s);
       }
}
void bfrun()// B反转运行   
{
  for(g=0;g<4;g++)
        {
         P1=brunf[g];
         delay(s);
        }
}
void fuzhi()  //x,y赋值函数
{
  if(q==0)   //起点x的值
  {
  if(p==0) x1=r;    //一位数
  if(p==1) x1=x1*10+r;  //两位数
  p++;
  }
    if(q==1)   //起点y的值
  {
  if(p==0) y1=r;    //一位数
  if(p==1) y1=y1*10+r;   //两位数
  p++;
  }
    if(q==2)  //终点x的值
  {
  if(p==0) x2=r;    //一位数
  if(p==1) x2=x2*10+r;   //两位数
  p++;
  }
    if(q==3)  //终点y的值
  {
  if(p==0) y2=r;    //一位数
  if(p==1) y2=y2*10+r;  //两位数
  p++;
  }
    if(q==4)
  {
  if(p==0) banjin=r;    //一位数
  if(p==1) banjin=banjin*10+r;  //两位数
  p++;
  }
  fz=0; //运行完毕后跳出
}
void queren()  //确认函数  每输入一个坐标点的x或y值就确认一下
{
  p=0;
  q++;
  if(xian==0){       //直线计算公式
           if(q==4){
                       q=0;
                       if(x1>x2) {azf=1;a=41.9*(x1-x2);}       //
                       if(x2>x1) {azf=0;a=41.9*(x2-x1);}  //求a的值并确定A电机正、反转   
                       if(y1>y2) {bzf=1;b=62.7*(y1-y2);}     //
                       if(y2>y1) {bzf=0;b=62.7*(y2-y1);} //求b的值并确定B电机正、反转  
                       x=41.9*x1; //求起点x值,单位为 /步
                       y=62.7*y1; //求起点y值,单位为 /步
                       u=x; //铅笔位置x轴
                       v=y; //铅笔位置y轴
                       if(x1==x2) e=(41.9*(x2-x1))/(62.7*(y2-y1));   //
                       else e=(62.7*(y2-y1))/(41.9*(x2-x1));   //求直线斜率 k y=kx+b
                       f=y-(e*x);    //求直线偏量 b
                      }
     }
  if(xian==1){   //画圆计算公式
        if(q==5){
                 q=0;
              x=41.9*x1; //求起点x值,单位为 /步
                       y=41.9*y1; //求起点y值,单位为 /步
        o1=41.9*x2;  //求圆心x值,单位为 /步
        o2=41.9*y2;  //求圆心y值,单位为 /步
        bj=41.9*banjin; //求圆的半径
        u=x; //铅笔位置x轴
                       v=y; //铅笔位置y轴
        if(x1>x2) {azf=1;a=41.9*(x1-(x2-bj));}       //
                       if(x2>x1) {azf=0;a=41.9*((x2-bj)-x1);}  //求a的值并确定A电机正、反转   
                       if(y1>y2) {bzf=1;b=62.7*(y1-y2);}     //
                       if(y2>y1) {bzf=0;b=62.7*(y2-y1);} //求b的值并确定B电机正、反转  
        if(x1==x2) e=(41.9*(x2-x1))/(62.7*(y2-y1));   //
                       else e=(62.7*(y2-y1))/(41.9*(x2-x1));   //求直线斜率 k y=kx+b
                       f=y-(e*x);    //求直线偏量 b
          }
    }
  if(xian==2){   //
    }
  if(xian==3){  //
    }
           
  qr=0;   //运行完毕后跳出
}
void Getch()  //矩阵键盘程序
{
unsigned char X,Y,Z;
P3=0xff;
P3=0x0f; //先对P3置数 行扫描   
if(P3!=0x0f) //判断是否有键按下   
           {delay10ms(); //延时,软件去干扰   
           if(P3!=0x0f) //确认按键按下X = P3;   
                      {
                       X=P3; //保存行扫描时有键按下时状态   
                       P3=0xf0; //列扫描   
                       Y=P3;    //保存列扫描时有键按下时状态   
                       Z=X|Y; //取出键值  
                       switch(Z) //判断键值(那一个键按下)
                                {
                                 case 0xee: {if(yx==1){r=0;fz=1;yx=0;}} break;    //0对键值赋值
                                 case 0xde: {if(yx==1){r=1;fz=1;yx=0;}} break;    //1
                                 case 0xbe: {if(yx==1){r=2;fz=1;yx=0;}} break;    //2
                                 case 0x7e: {if(yx==1){r=3;fz=1;yx=0;}} break;    //3
                                 case 0xed: {if(yx==1){r=4;fz=1;yx=0;}} break;    //4
                                 case 0xdd: {if(yx==1){r=5;fz=1;yx=0;}} break;    //5
                                 case 0xbd: {if(yx==1){r=6;fz=1;yx=0;}} break;    //6
                                 case 0x7d: {if(yx==1){r=7;fz=1;yx=0;}} break;    //7
                                 case 0xeb: {if(yx==1){r=8;fz=1;yx=0;}} break;    //8
                                 case 0xdb: {if(yx==1){r=9;fz=1;yx=0;}} break;    //9
                                 case 0xbb: {if(yx==1){qr=1;yx=0;}} break;    //A坐标点确认
                                 case 0x7b: {if((yx==1)&&(q==0)&&((a>0)||(b>0))&&xian==0){atzqd=1;btzqd=1;yx=0;}
                     if((yx==1)&&(q==0)&&xian==1){hy=1;atzqd=1;btzqd=1;yx=0;}
            if((yx==1)&&(q==0)&&xian==2){yx=0;}
            if((yx==1)&&(q==0)&&xian==3){yx=0;}} break; //B开始运行
                                 case 0xe7: {if(yx==1)xian=0;yx=0;} break;    //C  
                                 case 0xd7: {if(yx==1)xian=1;yx=0;} break;    //D  
                                 case 0xb7: {if(yx==1)xian=2;yx=0;} break;    //E  
                                 case 0x77: {if(yx==1)xian=3;yx=0;} break;    //F  
                                }
                      }
           }
else yx=1;
}
void kongzhi()
{
    P02=1; P03=1; P04=1; P05=1; P06=1; P07=1;
  if(P02==0){
             delay10ms();
    if(P02==0){bzrun(); P1=0Xff;}    //上移
    }
  if(P03==0){
             delay10ms();
    if(P03==0){bfrun(); P1=0Xff;}    //下移
    }
  if(P04==0){
             delay10ms();
    if(P04==0){afrun(); P1=0Xff;}    //左移
    }
  if(P05==0){
             delay10ms();
    if(P05==0){azrun(); P1=0Xff;}    //右移
    }
  if(P06==0){
             delay10ms();
    if(P06==0&&yw==1){tb=1;yw=0;}  //提笔
    }
  if(P07==0){
             delay10ms();
    if(P07==0&&yw==1){qb=1;yw=0;}    //落笔
    }
  else yw=1;
}

(下一页待续.....)

[ 本帖最后由 h15074037 于 2009-8-22 17:51 编辑 ]
此帖出自单片机论坛

最新回复

好帖! 只是图片看不到,建议楼不要使用图片链接。直接传上来  详情 回复 发表于 2013-9-4 22:47
点赞 关注
 

回复
举报

5

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
(接上一页)
void zhixian()   //步进电机直线运行函数
{
  if(atzqd==1)   //A步进电机
              {
              if(a>0)  //步骤未走完
            {
             if(azf==0){
             if(e>0){
               while(y                     {azrun();u++;y=e*u+f;}
                    } //斜率为正时,未过线之前铅笔位置x继续加1
       if(e==0)azrun();
             if(e<0){
               while(y>v||y==v)
                    {azrun();u++;y=e*u+f;}
                    } //斜率为负时,未过线之前铅笔位置x继续加1
            } //正转
             if(azf==1){
             if(e>0){
               while(y>v||y==v)
                    {afrun();u--;y=e*u+f;}
           } //斜率为正时,未过线之前铅笔位置x继续减1
       if(e==0)afrun();
             if(e<0){
               while(y               {afrun();u--;y=e*u+f;}
           } //斜率为负时,未过线之前铅笔位置x继续减1
        } //反转
       a--;
      }
     else {  //步骤已走完
           atzqd=0;
     P1=0xff;  //端口置1,防止电流过大
       }
     }
    if(btzqd==1)    //B步进电机
              {
              if(b>0)    //步骤未走完
            {
             if(bzf==0){
             if(e>0){
               while(x          {bzrun();v++;x=(v-f)/e;}
              } //斜率为正时,未过线之前铅笔位置y继续加1
       if(e==0)bzrun();
             if(e<0){
               while(x>u||x==u)
               {bzrun();v++;x=(v-f)/e;}
              } //斜率为负时,未过线之前铅笔位置y继续加1
        } //正转  
             if(bzf==1){
             if(e>0){
               while(x>u||x==u)
         {bfrun();v--;x=(v-f)/e;}
              } //斜率为正时,未过线之前铅笔位置y继续减1
       if(e==0)bfrun();
             if(e<0){
               while(x          {bfrun();v--;x=(v-f)/e;}
           } //斜率为负时,未过线之前铅笔位置y继续减1
        } //反转
       b--;
      }
     else {     //步骤已走完
           btzqd=0;
     P1=0xff;   //端口置1,防止电流过大
        }
     }
else if(hy==1){hy=2;qb=1;}  //画圆模式下 线走完后落笔画圆
}
void huayuan()   //画圆程序
{
    if(hy==1){zhixian();}
if(hy==2){
    if(u if(uo2){          //第二象限
                while(y                azrun(); P1=0xff;u++;y=sqrt(bj*bj-(u-o1)*(u-o1))+o2;
           }
                while(x          bzrun(); P1=0xff;v++;x=sqrt(bj*bj-(v-o2)*(v-o2))+o1;
           }
       }
if(u==o1&&v>o2){       //上端点
        {azrun(); P1=0xff;u++;}  
                }
if(u>o1&&v>o2){        //第一象限
       while(x          bfrun(); P1=0xff;v--;x=sqrt(bj*bj-(v-o2)*(v-o2))+o1;
           }
                while(y>v||y==v){
               azrun(); P1=0xff;u++;y=sqrt(bj*bj-(u-o1)*(u-o1))+o2;
           }
                }
if(u>o1&&v==o2){      //右端点
       {bfrun(); P1=0xff;v--;}
                }
if(u>o1&&v        while(y>v||y==v){
               afrun(); P1=0xff;u--;y=sqrt(bj*bj-(u-o1)*(u-o1))+o2;
           }
                while(x>u||x==u){
         bfrun(); P1=0xff;v--;x=sqrt(bj*bj-(v-o2)*(v-o2))+o1;
           }
                }
if(u==o1&&v        {afrun(); P1=0xff;u--;}
                }
if(u        if(u                 while(x>u||x==u){
         bzrun(); P1=0xff;v++;x=sqrt(bj*bj-(v-o2)*(v-o2))+o1;
           }
       while(y                afrun(); P1=0xff;u--;y=sqrt(bj*bj-(u-o1)*(u-o1))+o2;
           }
         }
       else hy=0;tb=1;  //圆画完后提笔结束
                }
     }
     
}
void main(void)
{
while(1)
       {
     kongzhi();
        Getch();
  if(fz==1) fuzhi();
  if(qr==1) queren();
  if(qb==1&&yl==0) qibi();
  if(tb==1&&yl==1) tibi();
        if(xian==0)zhixian();
  if(xian==1)huayuan();
       }
}

[ 本帖最后由 h15074037 于 2009-8-22 17:50 编辑 ]
此帖出自单片机论坛
 
 

回复

29

帖子

0

TA的资源

纯净的硅(中级)

板凳
 
哈哈,好强啊,佩服!:P
此帖出自单片机论坛
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

4
 

厉害啊

看看
此帖出自单片机论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

5
 
看不了图啊
此帖出自单片机论坛
 
 
 

回复

1万

帖子

25

TA的资源

裸片初长成(高级)

6
 
好帖!
只是图片看不到,建议楼不要使用图片链接。直接传上来
此帖出自单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表