求助:51单片机同时控制两台步进电动机 点击:3672 | 回复:19



motronking

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 86回
  • 年度积分:0
  • 历史总积分:113
  • 注册:2005年4月06日
发表于:2005-11-09 22:08:00
楼主
我想用AT89S51单片机同时控制两台一样的步进电动机(要求两台步机的转速可以不同,一台正转一台反转):用C语言编程,其中步机1的四相分别连在P1.0-P1.3,步机2的四相分别连在P2.0-P2.3==>故有:步机1正转{0x03,0x09,0x0c,0x06};步机2反转{0x03,0x06,0x0c,0x09};然后用中断控制延时,大略的程序如下:
#include <reg51.h>
#define Num_run 192
#define m_T 100

unsigned char idata cw1[5]={0x03,0x09,0x0c,0x06,0x00};
unsigned char idata ccw1[5]={0x03,0x06,0x0c,0x09,0x00};

unsigned char idata cw2[5]={0x03,0x09,0x0c,0x06,0x00};
unsigned char idata ccw2[5]={0x03,0x06,0x0c,0x09,0x00};

unsigned char idata *p1,*p2;//分别用于再P1,P2口输出步机1,步机2的正转字

bit intt1=0;//两个中断的标志,等于1为中断
bit intt2=0;

void control(bit direct1,unsigned int num_run1,bit direct2,unsigned int num_run2)//同时控制两个步机的函数              
{
    unsigned int n1,n2;
    if(direct1==1) p1=cw1;
    else p1=ccw1;

    if(direct2==1) p2=cw2;
    else p2=ccw2;

    TMOD=0x11;//同时用T/C0及T/C1工作在模式1:16位

    TH0=(65536-m_T*500)/256;
    TL0=(65536-m_T*500)%256;
    TH1=(65536-m_T*250)/256;
    TL1=(65536-m_T*250)%256;

    ET0=1;
    ET1=1;
         TR0=1;
    TR1=1;;//启动T/C0及T/C1
         EA=1;
    ..............
}

void delay_time1(void)interrupt 1 using 1
{
    P1=*p1++;//P1口输出步机1正转字
    if(*p1==0) p1-=4;

    TH0=(65536-m_T*500)/256;
    TL0=(65536-m_T*500)%256;

    intt1=1;//中断标志
}

void delay_time2(void)interrupt 2 using 2
{
    P2=*p2++;//P2口输出步机2反转转字
    if(*p2==0) p2-=4;

    TH1=(65536-m_T*250)/256;
    TL1=(65536-m_T*250)%256;

    intt2=1;
}

void main()
{
    control(1,Num_run,0,Num_run);  
}
..............部分的循环语句怎弄?还是整个程序有问题?
请伸出你热情的手帮小弟一把,不胜感激!
开始我用于控制一台步机时用:
    for(n1=0;n1<num_run1;n1++)
    {
    while(intt1==0);
    intt1=0;
     }
倒时可以运行,但同时控制两台不知道怎弄



zsbs

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 145回
  • 年度积分:1
  • 历史总积分:234
  • 注册:2003年11月27日
发表于:2005-11-11 16:13:00
1楼
1."TH1=(65536-m_T*250)/256;    TL1=(65536-m_T*250)%256;"这样的语句放到定时器中断服务程序中很不合适,因为这两行语句要执行很长时间,可能在下一次中断时间前都完不成
2.在中断服务程序中没有对电机步数进行计算,当电机转完指定步数后,可能仍然不能停下
3. for(n1=0;n1<num_run1;n1++)
    {
    while(intt1==0);
    intt1=0;
     }
这段程序在控制步数上不是很好,尤其你的定时器中断服务程序要执行较长时间,可能有时中断很多次才能执行一次这段程序,而且这段程序只能累加中断次数,不能控制中断次数

motronking

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 86回
  • 年度积分:0
  • 历史总积分:113
  • 注册:2005年4月06日
发表于:2005-11-11 17:41:00
2楼
谢谢你!你说得很中肯!其实我发过一些帖子,几乎没有人回,不知道是不是我写的东西太多,很多人看了就怕 :>
我刚学单片机(以前学PLC),单片机C语言编程很多东西不懂。

这是我的毕业课题中的四个内容的其中之一:用AT89S51同时控制两台四相单四拍步机,能指点我一下程序应该怎写么?非常感谢!

motronking

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 86回
  • 年度积分:0
  • 历史总积分:113
  • 注册:2005年4月06日
发表于:2005-11-11 17:43:00
3楼
To:zsbs 谢谢你!你说得很中肯!我刚学单片机(以前学PLC),单片机C语言编程很多东西不懂。

这是我的毕业课题中的四个内容的其中之一:用AT89S51同时控制两台四相单四拍步机,能指点我一下程序应该怎写么?非常感谢!

motronking

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 86回
  • 年度积分:0
  • 历史总积分:113
  • 注册:2005年4月06日
发表于:2005-11-11 17:50:00
4楼
To:zsbs 
今天我改了一下程序,但不知道为什么两台步机一开始的转速(10HZ)一样转2圈,然后一台停下,另一台再高速(40HZ)转2圈,我分明已经用了两个if分开了,我怀疑是dlms()有问题,其实这个函数识别人说的,我不太明白,是不是时间一维然后。。。麻烦您分析一下,应该怎改?谢谢!
#include <reg51.h>
#define Num_run 96
#define m_T0 100//10HZ
#define m_T1 25//40HZ

unsigned char idata cw[5]={0x03,0x09,0x0c,0x06,0x00};
unsigned char idata ccw[5]={0x03,0x06,0x0c,0x09,0x00};
unsigned char idata *p0,*p1;

void dlms(unsigned int x);

void control(bit direct0,unsigned int num_run0,bit direct1,unsigned int num_run1)                
{
    unsigned int n0=0,n1=0;

    if(direct0) p0=cw;
    else p0=ccw;
    
    if(direct1) p1=cw;
    else p1=ccw;
        
    for(;n0<num_run0||n1<num_run1;)
    {        
         if(n0<num_run0)
          {
             P0=*p0++;
             dlms(m_T0);
             if(*p0==0) p0-=4;
             n0++;
             }
         if(n1<num_run1-num_run0)
        {
             P1=*p1++;
             dlms(m_T1);
             if(*p1==0) p1-=4;
             n1++;
         }
    }
}

void dlms(unsigned int x)//毫秒计时{
    unsigned int i;
    while(x--)
    for(i=0;i<125;i++){;}
}

void main(void)
{
    control(0,Num_run,1,2*Num_run);
    control(1,2*Num_run,0,Num_run);
}

zsbs

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 145回
  • 年度积分:1
  • 历史总积分:234
  • 注册:2003年11月27日
发表于:2005-11-12 08:42:00
5楼
for(;n0<num_run0||n1<num_run1;)
    {        
         if(n0<num_run0)
          {
             P0=*p0++;
             dlms(m_T0);
             if(*p0==0) p0-=4;
             n0++;
             }
         if(n1<num_run1-num_run0)
        {
             P1=*p1++;
             dlms(m_T1);
             if(*p1==0) p1-=4;
             n1++;
         }
    }
}
在这段程序中,开始时dlms(m_T1)和dlms(m_T0);这两个延时程序都要执行,这时两个电机的周期都是dlms(m_T1)+dlms(m_T1);当一台停下后,另一台才是dlms(m_T1);



zsbs

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 145回
  • 年度积分:1
  • 历史总积分:234
  • 注册:2003年11月27日
发表于:2005-11-12 08:44:00
6楼
 你开始写和程序,分别用个定时器中断来延时,其思路还是正确的,可后的程序,思路都是错的

motronking

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 86回
  • 年度积分:0
  • 历史总积分:113
  • 注册:2005年4月06日
发表于:2005-11-12 10:41:00
7楼
To好心热情的zsbs:
    那如果按我先前的想法:同时用两个定时器中断来延时,    
    TH0=(65536-m_T*500)/256;
    TL0=(65536-m_T*500)%256;
    和
    TH1=(65536-m_T*250)/256;
    TL1=(65536-m_T*250)%256;部分
应该怎么处理,你在你的说明1中."TH1=(65536-m_T*250)/256;    TL1=(65536-m_T*250)%256;"这样的语句放到定时器中断服务程序中很不合适,因为这两行语句要执行很长时间,可能在下一次中断时间前都完不成。这点怎么处理?步数的for语句应该改成什么放在?
能不能花你一点时间按我上面的程序的格式改改,列一个你修改后的程序。非常感谢!——我发现你的C语言挺厉害的:)

love_day

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 7回
  • 年度积分:0
  • 历史总积分:7
  • 注册:2005年11月12日
发表于:2005-11-12 11:41:00
8楼
我以前幫蘇拉公司做過加拈機,也就是一個正反轉電機控制機,還可以調整電機的轉速,可以直接用plc控制阿,把2台電機的3相錯開接,一個控制正轉,一個控制反轉,然後再外面的觸摸屏上加一個3 位轉換開關就可以了。

love_day

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 7回
  • 年度积分:0
  • 历史总积分:7
  • 注册:2005年11月12日
发表于:2005-11-12 11:41:00
9楼
我以前幫蘇拉公司做過加拈機,也就是一個正反轉電機控制機,還可以調整電機的轉速,可以直接用plc控制阿,把2台電機的3相錯開接,一個控制正轉,一個控制反轉,然後再外面的觸摸屏上加一個3 位轉換開關就可以了。

love_day

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 7回
  • 年度积分:0
  • 历史总积分:7
  • 注册:2005年11月12日
发表于:2005-11-12 11:42:00
10楼
我以前幫蘇拉公司做過加拈機,也就是一個正反轉電機控制機,還可以調整電機的轉速,可以直接用plc控制阿,把2台電機的3相錯開接,一個控制正轉,一個控制反轉,然後再外面的觸摸屏上加一個3 位轉換開關就可以了。

love_day

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 7回
  • 年度积分:0
  • 历史总积分:7
  • 注册:2005年11月12日
发表于:2005-11-12 11:43:00
11楼
我以前幫蘇拉公司做過加拈機,也就是一個正反轉電機控制機,還可以調整電機的轉速,可以直接用plc控制阿,把2台電機的3相錯開接,一個控制正轉,一個控制反轉,然後再外面的觸摸屏上加一個3 位轉換開關就可以了。

love_day

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 7回
  • 年度积分:0
  • 历史总积分:7
  • 注册:2005年11月12日
发表于:2005-11-12 11:44:00
12楼
我以前幫蘇拉公司做過加拈機,也就是一個正反轉電機控制機,還可以調整電機的轉速,可以直接用plc控制阿,把2台電機的3相錯開接,一個控制正轉,一個控制反轉,然後再外面的觸摸屏上加一個3 位轉換開關就可以了。

love_day

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 7回
  • 年度积分:0
  • 历史总积分:7
  • 注册:2005年11月12日
发表于:2005-11-12 11:45:00
13楼
我以前幫蘇拉公司做過加拈機,也就是一個正反轉電機控制機,還可以調整電機的轉速,可以直接用plc控制阿,把2台電機的3相錯開接,一個控制正轉,一個控制反轉,然後再外面的觸摸屏上加一個3 位轉換開關就可以了。

motronking

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 86回
  • 年度积分:0
  • 历史总积分:113
  • 注册:2005年4月06日
发表于:2005-11-13 09:48:00
14楼
我现在手上没有可以用C语言编程的PLC,因为步机的频率和转动步数是从C++传来的变量,也就是说我要的单片机控制两台步机的程序是一个模板,是从C++生成的程序。用PLC好像不大合适

love_day

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 7回
  • 年度积分:0
  • 历史总积分:7
  • 注册:2005年11月12日
发表于:2005-11-13 18:01:00
15楼
老莫,你是在學校做畢業設計把,對於電機控制,我覺得用PLC比較好,首先PLC都是POINT TO POINT 的,可能試驗 上可以實現的東西在工作中實現不了吧。對於程序這塊我也不是很了解,我現在主要是在做成品的測試以及調試工作。

zsbs

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 145回
  • 年度积分:1
  • 历史总积分:234
  • 注册:2003年11月27日
发表于:2005-11-13 20:49:00
16楼
#include <reg51.h>
#define Num_run 192
#define m_T 100

unsigned char idata cw1[5]={0x03,0x09,0x0c,0x06,0x00};
unsigned char idata ccw1[5]={0x03,0x06,0x0c,0x09,0x00};

unsigned char idata cw2[5]={0x03,0x09,0x0c,0x06,0x00};
unsigned char idata ccw2[5]={0x03,0x06,0x0c,0x09,0x00};

unsigned char idata *p1,*p2;//分别用于再P1,P2口输出步机1,步机2的正转字

bit intt1=0;//两个中断的标志,等于1为中断
bit intt2=0;

//定义两个全局变量,分别表示占步数

unsigned int iNumStep1;
unsigned int iNumStep2;

/////////////////////////////////

void control(bit direct1,unsigned int num_run1,bit direct2,unsigned int num_run2)//同时控制两个步机的函数              
{
    unsigned int n1,n2;
    if(direct1==1) p1=cw1;
    else p1=ccw1;

    if(direct2==1) p2=cw2;
    else p2=ccw2;

    TMOD=0x11;//同时用T/C0及T/C1工作在模式1:16位

    TH0=(65536-m_T*500)/256;
    TL0=(65536-m_T*500)%256;
    TH1=(65536-m_T*250)/256;
    TL1=(65536-m_T*250)%256;
//下面两行设置步数
    iNumStep1=num_run1;
    iNumStep1=num_run1;



    ET0=1;
    ET1=1;
         TR0=1;
    TR1=1;;//启动T/C0及T/C1
         EA=1;
    ..............
}

void delay_time1(void)interrupt 1 using 1
{
    if(iNumStep1>0)
   {
      iNumStep1--;

      P1=*p1++;//P1口输出步机1正转字
      if(*p1==0) p1-=4;

      TH0=(65536-m_T*500)/256;//这两行可以直接算出数值,写在这
      TL0=(65536-m_T*500)%256;//也可以把*和/分别用移位与相加计算,减少执行时间
    }
    else
    {    ET0=0;//如果步数已减到零,关中断
    TR0=0;//关定时器0
    }

   // intt1=1;//中断标志
}
//下在这个中断服务程序改法同上,在中断中当步数减到零后,定时器不在工作
void delay_time2(void)interrupt 2 using 2
{
    P2=*p2++;//P2口输出步机2反转转字
    if(*p2==0) p2-=4;

    TH1=(65536-m_T*250)/256;
    TL1=(65536-m_T*250)%256;

    intt2=1;
}

void main()
{
    control(1,Num_run,0,Num_run);  
}

motronking

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 86回
  • 年度积分:0
  • 历史总积分:113
  • 注册:2005年4月06日
发表于:2005-11-15 22:06:00
17楼
解决了,谢谢你!我上面的程序中主函数也有问题,我已经改了

王晟磊

  • 精华:12帖
  • 求助:0帖
  • 帖子:70帖 | 687回
  • 年度积分:0
  • 历史总积分:1173
  • 注册:2004年2月11日
发表于:2005-11-16 19:41:00
18楼
买个海维深的V80用吧,带两轴运动控制,只需要调两个功能块就行了。
0755-26995272

ldyziyou

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:1
  • 注册:2013年11月16日
发表于:2013-11-16 20:04:41
19楼

求助!!我想用单片机控制两个支流小电机顺序工作,就是一个先工作一会,另一个在工作,软硬件怎么做啊!


热门招聘
相关主题

官方公众号

智造工程师