加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

双极性步进电机驱动

(2009-08-29 09:49:55)
标签:

it

分类: 专业

 

H桥式驱动电路原理图
来源:机器人世界 日期:2009-03-17

一、H桥式电机驱动电路
图4.12中所示为一个典型的直流电机控制电路。电路得名于“H桥式驱动电路”是因为它的形状酷似字母H。4个三极管组成H的4条垂直腿,而电机就是H中的横杠(注意:图4.12及随后的两个图都只是示意图,而不是完整的电路图,其中三极管的驱动电路没有画出来)。
如图所示,H桥式电机驱动电路包括4个三极管和一个电机。要使电机运转,必须导通对角线上的一对三极管。根据不同三极管对的导通情况,电流可能会从左至右或从右至左流过电机,从而控制电机的转向。

http://www.intool.cn/uploads/userup/0903/1GI6421913.jpg  
图4.12 H桥式电机驱动电路

要使电机运转,必须使对角线上的一对三极管导通。例如,如图4.13所示,当Q1管和Q4管导通时,电流就从电源正极经Q1从左至右穿过电机,然后再经Q4回到电源负极。按图中电流箭头所示,该流向的电流将驱动电机顺时针转动。
当三极管Q1和Q4导通时,电流将从左至右流过电机,从而驱动电机按特定方向转动(电机周围的箭头指示为顺时针方向)。

 http://www.intool.cn/uploads/userup/0903/1GIFA600.jpg
图4.13 H桥电路驱动电机顺时针转动

图4.14所示为另一对三极管Q2和Q3导通的情况,电流将从右至左流过电机。
当三极管Q2和Q3导通时,电流将从右至左流过电机,从而驱动电机沿另一方向转动(电机周围的箭头表示为逆时针方向)。

 http://www.intool.cn/uploads/userup/0903/1GIG92491.jpg
图4.14 H桥电路驱动电机逆时针转动

二、使能控制和方向逻辑
驱动电机时,保证H桥上两个同侧的三极管不会同时导通非常重要。如果三极管Q1和Q2同时导通,那么电流就会从正极穿过两个三极管直接回到负极。此时,电路中除了三极管外没有其他任何负载,因此电路上的电流就可能达到最大值(该电流仅受电源性能限制),甚至烧坏三极管。
基于上述原因,在实际驱动电路中通常要用硬件电路方便地控制三极管的开关。
图4.155所示就是基于这种考虑的改进电路,它在基本H桥电路的基础上增加了4个与门和2个非门。4个与门同一个“使能”导通信号相接,这样,用这一个信号就能控制整个电路的开关。而2个非门通过提供一种方向输人,可以保证任何时候在H桥的同侧腿上都只有一个三极管能导通。(与本节前面的示意图一样,图4.15所示也不是一个完整的电路图,特别是图中与门和三极管直接连接是不能正常工作的。)

 http://www.intool.cn/uploads/userup/0903/1GII4L01.jpg
图4.15 具有使能控制和方向逻辑的H桥电路

采用以上方法,电机的运转就只需要用三个信号控制:两个方向信号和一个使能信号。如果DIR-L信号为0,DIR-R信号为1,并且使能信号是1,那么三极管Q1和Q4导通,电流从左至右流经电机(如图4.16所示);如果DIR-L信号变为1,而DIR-R信号变为0,那么Q2和Q3将导通,电流则反向流过电机。

 http://www.intool.cn/uploads/userup/0903/1GI92KR4.jpg
图4.16 使能信号与方向信号的使用

实际使用的时候,用分立件制作H桥式是很麻烦的,好在现在市面上有很多封装好的H桥集成电路,接上电源、电机和控制信号就可以使用了,在额定的电压和电流内使用非常方便可靠。比如常用的L293D、L298N、TA7257P、SN754410等。

双极性步进电机驱动

 

http://img.blog.163.com/photo/7PHWpDV-xVCe0q_9A-SfBQ==/325385073078625916.jpg

     双极性步进电机的驱动电路,使用八颗晶体管来驱动两组相位。双极性驱动电路可以同时驱动四线式或六线式步进电机,虽然四线式电机只能使用双极性驱动电路,它却能大幅降低量产型应用的成本。双极性步进电机驱动电路的晶体管数目是单极性驱动电路的两倍,其中四颗下端晶体管通常是由微控制器直接驱动,上端晶体管则需要成本较高的上端驱动电路。双极性驱动电路的晶体管只需承受电机电压,所以它不像单极性驱动电路一样需要箝位电路。

 

L297各脚功能。

脚号                            脚名                   功能
                               SYNC                 多路同步
                               GND                  
                               HOME
                                                     A相左桥驱动
                               /INH1                  禁止信号1:L有效、两相整步时为H
                                                     A相右桥驱动
                                                     B相左桥驱动
                              /INH2                  禁止信号2:L有效、两相整步时为H
                                                    B相右桥驱动
10                             ENABLE             使能输控制入:L时,INH1、INH2、A、B、C、D均被强制为L,电路停止工作
11                             CONTROL           斩波控制选择:L单极性工作方式;L或H双极性工作方式
12                             Vcc                    电源正
13                             SENS2               绕组电流检测入2
14                             SENS1               绕组电流检测入1
15                             Vref                    绕组电流调节
16                             OSC                   外接LC网络
17                             CW/CCW           H正转、L反转
18                              /CLOCK            步进脉冲
19                             HALF/FULL        H半步、L整步
20                              /RESET            异步复位:0101

 

看原理图:BSD是外界线圈对地的二极管,RE是采样电阻,而VREF则是通3.04*RE,这由电流真值表的计算公式可以看出。 

 

下面给出我的一个驱动程序:是对步进脚进行4细分,双线圈导通驱动。


#include <pic.h>

//代表输出电流值
//分别代表
// 17.39% 26.08% 34.78% 43.48% 52.17% 60.87% 69.56% 73.91% 78.26% 82.61% 86.95% 91.30% 95.65% 100%
//对应端口
// IB4 IB3 IB2 IB1 IA4 IA3 IA2 IA1
// RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
const unsigned char TableA[] = {0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x0F,0x0F,0x0f,0x0f,0x0f,0x0f};// 电流输出值对应
const unsigned char TableB[] = {0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0xA0,0xB0,0xC0,0xD0,0xE0,0xF0,0xF0,0xF0,0xf0,0xf0,0xf0,0xf0};
// 正转反转时许设定
// 1.单相通电
// 正转时序
// A/ B A B/
// 反转时序
// B/ A B A/
// 2.两相通电
// 正转时序
// A/B AB AB/ A/B/
// 反转时序
// A/B/ AB/ AB A/B
// 3.半步方式
// 正转时序
// A/ A/B B AB A AB/ B/ A/B/
// 反转时序
// A/B/ B/ AB/ A AB B A/B A/
// 步进电机对应
// 从带蓝边开始 依次 A B A/ B/
// 操作时序
// PHASE    ENABLE   OUTAorB    OUTA/orB/
// H                      L
// L                      H
// -              OFF        OFF
const unsigned char PositiveTable[]={0x08,0x06,0x09,0x02};  // 正转时序
const unsigned char ReverseTable[]={0x02,0x09,0x06,0x08};   // 反响时序

const unsigned char PositiveTable1[]={0x04,0x05,0x01,0x00};  // 正转时序
const unsigned char ReverseTable1[]={0x00,0x01,0x05,0x04};   // 反响时序

const unsigned char PositiveTable2[] ={0x08,0x04,0x06,0x05,0x09,0x01,0x02,0x00};   // 8拍正转时序           
const unsigned char ReverseTable2[]={0x00,0x02,0x01,0x09,0x05,0x06,0x04,0x08};
#define Timer1_Int  0xFF80   // 定时器1初始化值

const unsigned char PositiveTable3[]={0x08,0x06,0x09,0x02};  // 正转时序

#define PHASEA      RC0      // 输出管脚使能
#define ENABLEA     RC1
#define PHASEB      RC2
#define ENABLEB     RC3

unsigned char Point_CurrentA;    // A相电流输出指针
unsigned char Point_CurrentB;    // B相电流输出指针 

unsigned char Point_Running;     // 转动指针

unsigned char Delay_Counter;     // 延时计数器
unsigned int  Timer_Add;

unsigned char Add_Pluse;

volatile bit  A_Add;
volatile bit  A_Plus;
volatile bit  B_Add;
volatile bit  B_Plus; 
 
volatile bit Positive_Reverse_Flage; // 正反标志
volatile bit Positive_ReverseA;
volatile bit Positive_ReverseB;

//#define A_Add        // A相电流加操作
//#define A_Pluse 2       // A相电流减操作
//#define B_Add        // B相电流加操作
//#define B_Pluse 4       // B相电流减操作 


void Pic_Int();

void delay(unsigned int asd)
{
  unsigned int i;
  for(i=0;i<asd;i++)
  {}
 
//*****************************************
//中断函数
//*****************************************
void interrupt SDI()
{
  if(TMR1IF)     // 定时器中断
  {
    TMR1IF = 0; 
    if(Timer_Add<0xFF60)
    {
      //Timer_Add++;
    }
    TMR1H = (unsigned char)(Timer_Add>>4);     // 定时器计时初始化
    TMR1L = (unsigned char)(Timer_Add&0x00ff);
   
    Delay_Counter++;
    if(Delay_Counter>=1);
    {
      Delay_Counter = 0;

      PORTC = PositiveTable[Point_Running];    // 正转时序
      PORTB = (unsigned char)((TableA[Point_CurrentA])|(TableB[Point_CurrentB]));
      if(A_Add)
      {
        Point_CurrentA+=4;
      }

      if(A_Plus)
      {
        Point_CurrentA-=4;
      }

      if(B_Plus)
      {
        Point_CurrentB-=4;  
      }
      if(B_Add)
      {
        Point_CurrentB+=4;
      }
      //Point_Running++;
      if(A_Add)  
      {
        if(Point_CurrentA == 16)
        {
           A_Add = 0;
           A_Plus = 1;
          if(Positive_ReverseA)
          {Point_Running++;}
          Positive_ReverseA = 0;
        
        
      if(A_Plus)
      {
        if(Point_CurrentA == 0)
        {
          A_Add = 1;
          A_Plus = 0;
          if(Positive_ReverseA)
          {Point_Running++;}
          Positive_ReverseA = 0;
        }
      }
      if(B_Add)
      {
        if(Point_CurrentB==16)
        {
           B_Add = 0;
           B_Plus = 1;
          if(Positive_ReverseB)
          {Point_Running++;}
          Positive_ReverseB = 0;
        }
      }
      if(B_Plus)
      {
         if(Point_CurrentB==0)
         {
           B_Add = 1;
           B_Plus = 0;   
          if(Positive_ReverseB)
          {Point_Running++;}
           Positive_ReverseB = 0;        
         }
      }
      if(Positive_Reverse_Flage==0) // 正转
      {
        if(Positive_ReverseA==0)
         {
           Positive_ReverseB = 1;
         }
        if(Positive_ReverseB==0)
         {
           Positive_ReverseA = 1;
         }
      }
     
 
        if(Point_Running>4)
        {
          Point_Running = 0;
        }
        
  }
}
//*****************************************
//主函数
//*****************************************
void main()
{
  Pic_Int();   // 初始化
  //PHASEB = 1;
  //ENABLEB = 0;
  while(1)
  {

  }
}

//*****************************************
//初始化函数
//*****************************************
void Pic_Int()
{
  ADCON1 = 0x07;  // 关闭AD转换器
  INTCON= 0x00;   // 关闭中断
  TRISB = 0x00;   // RB口设置为输出
  PORTB = 0xff;   // 全部电流输出
 
  TRISC = 0xF0;   // 低四位设置为输出引脚
  ENABLEB = 1;
  ENABLEA = 1;

  T1CON = 0x00;   // 定时器1初始化
  TMR1IE = 1;
  Timer_Add = Timer1_Int;

  TMR1H = (unsigned char)(Timer_Add>>4);     // 定时器计时初始化
  TMR1L = (unsigned char)(Timer_Add&0x00ff); 
  GIE = 1;                                  // 中断开始
  PEIE = 1;
  TMR1ON= 1;                                // 定时器运行
  Point_CurrentA = 0;                       // 指针初始化
  Point_CurrentB = 0;
  Point_Running = 0; 
  Delay_Counter = 0;

  Positive_Reverse_Flage = 0;               // 正转标志
  Point_CurrentA = 16;                      // 正转电流A相处于最大
  Point_CurrentB = 0;                       // 正转电流B相处于最小

  Positive_ReverseA = 1;
  Positive_ReverseB = 0;
  A_Plus = 1;                               // 起始B进行加操作
  A_Add = 0;
  B_Add = 1;                                // B加操作
  B_Plus = 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有