4058|2

5

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

如何控制悬挂运动走直线? [复制链接]

以下是悬挂运动控制系统的程序,如何让步进电机走直线(水平线,垂直线,斜线)?
#include "reg52.h"
#include "math.h"
sbit P1_0=P1^0;//A步进电机端口
sbit P1_1=P1^1;//A步进电机端口         
sbit P1_2=P1^2;//A步进电机端口  
sbit P1_3=P1^3;//A步进电机端口
sbit P1_4=P1^4;//B步进电机端口
sbit P1_5=P1^5;//B步进电机端口
sbit P1_6=P1^6;//B步进电机端口
sbit P1_7=P1^7;//B步进电机端口
bit  atzqd=0;   //A电机停止启动    默认停止
bit  btzqd=0;   //B电机停止启动    默认停止
bit fz=0;   //是否给x,y赋值    默认否
bit qr=0;  //赋值后是否确认   默认否
unsigned char m,n,k,g,u=1,v=1;
float a=0;  //计算得到的A电机步数   
float b=0;  //计算得到的B步进电机的步数
float L1,L2,L3,L4;   //定义线的长度
bit azf=0;  //A运转方向  
bit bzf=0;  //B运转方向
bit yx=1; //按键重复允许   默认否
float r;  //给x,y赋值的中间变量
unsigned char p=0,q=0;  //赋值和确认中间标志
float x1=0,x2=0;  //x坐标
float y1=0,y2=0;  //y坐标
int s=20;//定义转动速度,数值越大电机转速越慢反之则快      
code unsigned char arunz[4]={0xef,0xdf,0xbf,0x7f};  //A电机正转  
code unsigned char arunf[4]={0x7f,0xbf,0xdf,0xef};  //A电机反转
code unsigned char brunf[4]={0xfe,0xfd,0xfb,0xf7};  //B电机正转  
code unsigned char brunz[4]={0xf7,0xfb,0xfd,0xfe};  //B电机反转   
//unsigned char code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
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 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;   //两位数
  L1=sqrt((x1+3)*(x1+3)+(43-y1)*(43-y1));  //求L1长度
  L2=sqrt((43-x1)*(43-x1)+(43-y1)*(43-y1));    //求L2长度
  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;  //两位数
  L3=sqrt((x2+3)*(x2+3)+(43-y2)*(43-y2));   //求L3长度
  L4=sqrt((43-x2)*(43-x2)+(43-y2)*(43-y2));    //求L4长度
  if(L3>L1) {azf=1;a=12*(L3-L1);}       //
  if(L3   if(L4>L2) {bzf=1;b=12*(L4-L2);}     //
  if(L4   p++;
  }
  fz=0; //运行完毕后跳出
}
void queren()  //确认函数  每输入一个坐标点的x或y值就确认一下
{
  p=0;
  q++;
  if(q==4) q=0;   
  qr=0;   //运行完毕后跳出
}
void Getch()  //矩阵键盘程序
{
unsigned char X,Y,Z;
P2=0xff;
P2=0x0f; //先对P2置数 行扫描   
if(P2!=0x0f) //判断是否有键按下   
           {delay10ms(); //延时,软件去干扰   
           if(P2!=0x0f) //确认按键按下X = P2;   
                      {
                       X=P2; //保存行扫描时有键按下时状态   
                       P2=0xf0; //列扫描   
                       Y=P2;    //保存列扫描时有键按下时状态   
                       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)){atzqd=1;btzqd=1;yx=0;}} ; break;    //B
                                 case 0xe7: {azf=0;azrun();P1=0Xff;}; break;    //C
                                 case 0xd7: {azf=1;afrun();P1=0Xff;}; break;    //D
                                 case 0xb7: {bzf=0;bfrun();P1=0Xff;}; break;    //E
                                 case 0x77: {bzf=1;bzrun();P1=0Xff;}; break;    //F
                                }
                      }
           }
else yx=1;
}
void yunxing()   //步进电机运行函数
{
  unsigned char i,j;
  if(atzqd==1)   //A步进电机
              {
              if(a>0)  //步骤未走完
     for(i=u;i>0;i--){
                if(azf==0) azrun(); //正转
       if(azf==1) afrun(); //反转
       a--;
      }
     else {  //步骤已走完
           atzqd=0;
     P1=0xff;  //端口置1,防止电流过大
       }
     }
    if(btzqd==1)    //B步进电机
              {
              if(b>0)    //步骤未走完
     for(j=v;j>0;j--){
                if(bzf==0) bzrun();  //正转
                         if(bzf==1) bfrun();  //反转
       b--;
      }
     else {     //步骤已走完
           btzqd=0;
     P1=0xff;   //端口置1,防止电流过大
        }
     }
   if(a>b){u=a/b;v=1;}   
   if(a }
void main(void)
{
while(1)
       {
        Getch();
  if(fz==1) fuzhi();
  if(qr==1) queren();
        yunxing();
       }
}
此帖出自单片机论坛

最新回复

园、椭圆、抛物线、双曲线、渐开线  详情 回复 发表于 2009-6-7 22:07
点赞 关注
 

回复
举报

1634

帖子

0

TA的资源

裸片初长成(高级)

沙发
 
园、椭圆、抛物线、双曲线、渐开线
此帖出自单片机论坛

赞赏

1

查看全部赞赏

 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
程序怎样写?用什么算法?
void jisuan()
{
  x1=sqrt(((a/12+L1)*(a/12+L1)-(b/12+L2)*(b/12+L2)+46*46)/92-3);
  y1=43-sqrt((L1+a/12)*(L1+a/12)-(x1+3)*(x1+3));
  L1=sqrt((x1+3)*(x1+3)+(43-y1)*(43-y1));  //求L1长度
  L2=sqrt((43-x1)*(43-x1)+(43-y1)*(43-y1));    //求L2长度
  L3=sqrt((x2+3)*(x2+3)+(43-y2)*(43-y2));  //求L3长度
  L4=sqrt((43-x2)*(43-x2)+(43-y2)*(43-y2));    //求L4长度
  if(L3>L1) {azf=1;a=12*(L3-L1);}       //
  if(L3   if(L4>L2) {bzf=1;b=12*(L4-L2);}     //
  if(L4 }

将这一个子程序加在:

void yunxing()   //步进电机运行函数
{
  if(atzqd==1)   //A步进电机
              {
              if(a>0)  //步骤未走完
               {
                if(azf==0) azrun(); //正转
       if(azf==1) afrun(); //反转
       P1=0xff;  //端口置1,防止电流过大
       a--;
       jisuan();
      }
     else {  //步骤已走完
           atzqd=0;
     P1=0xff;  //端口置1,防止电流过大
       }
     }
    if(btzqd==1)    //B步进电机
              {
              if(b>0)    //步骤未走完
               {
                if(bzf==0) bzrun();  //正转
                         if(bzf==1) bfrun();  //反转
       P1=0xff;  //端口置1,防止电流过大
       b--;
       jisuan();
      }
     else {     //步骤已走完
           btzqd=0;
     P1=0xff;   //端口置1,防止电流过大
        }
     }
}

每走一步计算一次行吗?
此帖出自单片机论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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