天天看點

步進電機驅動技術3:基于ULN2003的步進電機驅動

  在我們的項目中,經常使用到低電壓小功率的步進電機,此類步進電機若采用驅動器控制不斷成本高也過于複雜,我們可以直接使用場效應管或者達林頓管來實作對其的驅動。在本篇中,我們就來讨論一下基于ULN2003A達林頓管實作對步進電機的驅動。

1、功能概述

  我們先來了解一下基本的功能。ULN2003A達林頓管為7個輸出通道,當導通時該通道連接配接到負端,是以非常适合于驅動4相5線步進電機。

1.1、ULN2003A達林頓管

  ULN2003A 器件是高電壓大電流達林頓半導體陣列。每 款器件均由7個NPN 達林頓對組成,這些達林頓對具有高壓輸出,帶有用于開關感性負載的共陰極鉗位二極管。 單個達林頓對的集電極電流額定值為500mA。将達林 頓對并聯可以提供更高的電流。應用包括繼電器驅動器、電錘驅動器、燈驅動器、顯示驅動器(LED 和氣體放電)、線路驅動器和邏輯緩沖器。其基本結構圖如下:

步進電機驅動技術3:基于ULN2003的步進電機驅動

1.2、步進電機基本原理

  在我們的測試中,我們使用4相5線步進電機。所謂4相5線步進電機就是該電機具有4組線圈5根連接配接線,實際上可能不隻5根線,但公共端不管抽出多少根線,實際狀态與1根無異。

  我們一般将這4組線圈記為A相、B相、C相和D相,當然,也可以用别的稱呼,隻要便于标記分别就好。4相5線步進電機一般采用單極性直流電源供電。隻要對步進電機的各相繞組按合适的時序通電,就能使步進電機步進轉動。一般電機都會提供控制表,具體如下所示:

步進電機驅動技術3:基于ULN2003的步進電機驅動

  結合ULN2003A結構和4相5線步進電機的驅動要求,我們可以設計ULN2003A達林頓管驅動4相5線步進電機的驅動電路。

步進電機驅動技術3:基于ULN2003的步進電機驅動

1.3、步進電機驅動模式

  步進電機的驅動雖然按照電機的驅動表就可以實作,但實際的驅動方式有多種,常見的如單波驅動方式、全步驅動方式、半步驅動方式以及微步驅動方式等。這裡我們可以看一看前面三種比較簡單的驅動方式。

  單波驅動方式又稱之為單四拍工作方式。此種方式按固定次序依次驅動每一個線圈以達到使電機轉動的目的。其波形如下:

步進電機驅動技術3:基于ULN2003的步進電機驅動

  全步驅動方式又稱之為雙四拍工作方式。此種方式按固定次序依次驅動兩組線圈以達到使電機轉動的目的。其波形如下:

步進電機驅動技術3:基于ULN2003的步進電機驅動

  半步驅動方式又稱之為八拍工作方式。此種模式實際上是前兩種模式的組合,以固定的次序依次激勵一組或兩組線圈以達到驅動電機的目的。其波形如下:

步進電機驅動技術3:基于ULN2003的步進電機驅動

  上述波形即是在單波驅動方式、全步驅動方式以及半步驅動方式下使用示波器抓取的A相和C相的波形圖,基本可以展示這幾種驅動工作方式波形特征。

2、驅動設計與實作

  我們已經了解了ULN2003A驅動4相5線步進電機的基本工作情況,接下來我們就需要據此來實作ULN2003A驅動4相5線步進電機驅動程式的設計與實作。

2.1、對象定義

  我們依然是基于對象來實作相關的操作。是以我們首先要定義對象,出于适用性考慮,我們要定義對象的類型并将具體的對象執行個體化,接下來我們就來抽象對象類型和執行個體化對象的操作。

2.1.1、對象的抽象

  對于一個對象最主要包括屬性與方法兩方面内容,是以我們先來考慮驅動一個步進電機對象具有哪些屬性和方法,并抽象出較為通用的步進電機的對象類型。

  首先,我們來考慮對象的屬性情況。對電機的操作包括啟停指令、方向指令、運作狀态、實際運轉方向、節拍數、周期等,這些資訊控制電機的運轉并表征其具體工作狀态,是以我們将其作為對象的屬性。驅動模式和運作模式用以配置電機的具體工作方式,是以我們也将其作為對象的屬性,以完成對象的配置。

  其次我們再來考慮對象的方法問題。對相位的具體操作與具體的硬體平台有關,根據對應的引腳定義相應的相位引腳。這依賴于具體的硬體和軟體操作平台,是以我們将其定義為對象的方法。為了控制操作時序,我們需要延時處理,而延時操作函數同樣依賴于具體的軟硬體平台,是以我們也将其定義為對象的方法,通過回調函數的方式來實作。

  根據上述對對象屬性和方法的分析,我們可以定義步進電機對象的類型如下:

/*定義步進電機對象類型*/
typedef struct StepperObject {
  uint8_t startStop;   //啟動停止指令
  uint8_t runStatus;   //運作狀态
  uint8_t directSet;   //方向設定
  uint8_t directRun;   //目前方向
  uint8_t beat;      //目前節拍
  uint8_t period;     //速度控制周期
  DriveModeType driveMode;  //驅動模式
  StepperModeType runMode;  //運作模式
  void (*PhaseAction)(uint8_t cmd);
  void (*Delayms)(uint32_t period);
}StepperObjectType;
           

2.1.2、對象初始化

  我們定義了對象類型,可以實作基于對象的操作,但定義的對象變量需要進行初始化才能讓不同的對象按照我們的配置的方式去運作。是以在開始對象的使用之前我們先對其進行初始化,這就需要我們設計一個對象的初始化函數。

  這個初始化函數,将構造一個具體的操作對象。對于步進電機來說,我們需要初始化其相關的參數,如:工作模式、運作模式以及相位操作函數等。具體的初始化函數如下:

/*步進電機對象初始化*/
void StepperInitialization(StepperObjectType *stepper,   //步進電機對象
​           DriveModeType driveMode,     //驅動模式
​           StepperModeType runMode,     //運作模式
​           uint8_t period,         //速度控制周期
​           StepperPhaseActionType action, //相位操作回調函數
​           StepperDelaymsType delayms  //延時操作回調函數
​           )
{
  if((stepper==NULL)||(action==NULL)||(delayms==NULL))
  {
​    return;
  }
  stepper->PhaseAction=action;
  stepper->Delayms=delayms;

  stepper->driveMode=driveMode;
  stepper->runMode=runMode;
  
  stepper->period=period>0?period:1;
}
           

2.2、對象操作

  接下來我們考慮對步進電機對象所要進行的操作問題。我們已經将相位的具體面向硬體平台的操作定義為對象的方法。我們需要實作對象在不同的模式下節拍操作的控制。具體實作如下:

//步進電機節拍操作
static void StepperAction(StepperObjectType *stepper)
{
  uint8_t Command[BEAT_NUM]={0x01,0x03,0x02,0x06,0x04,0x0C,0x08,0x09};
  RunBeatType beat=BEAT_NUM;
  
  if(stepper->beat>=BEAT_NUM)
  {
​    stepper->beat=0;
​    
​    if(stepper->driveMode==Full_Step)
​    {
​      stepper->beat=1;
​    }
  }
 
  beat=stepper->directRun>0?((RunBeatType)(7-stepper->beat)):((RunBeatType)stepper->beat);
  
  if(beat>=BEAT_NUM)
  {
​    return;
  }
  
  stepper->PhaseAction(Command[beat]);
  
  stepper->beat++;
  if((stepper->driveMode==Full_Step)||(stepper->driveMode==Single_Wave))
  {
​    stepper->beat++;
  }
  
  stepper->Delayms(stepper->period);
}
           

3、驅動的應用

  我們已經設計并實作了基于ULN2003A的步進電機驅動程式,接下來我們實作一個執行個體來驗證這一驅動程式設定是否符合要求。

3.1、聲明并初始化對象

  在開始一切操作之前,首先我們需要一個對象。前面的設計中,我們已經定義了一個StepperObjectType對象類型,是以我們使用它定義一個對象變量。

  StepperObjectType chamber;

  定義了chamber對象變量之後,還沒有辦法使用,因為我們需要對其進行初始化。前面我們已經設計了對象初始化函數,我們需要使用這一函數來初始化chamber對象變量。初始化函數需要如下參數:

  StepperObjectType *stepper, //步進電機對象

  DriveModeType driveMode, //驅動模式

  StepperModeType runMode, //運作模式

  uint8_t period, //速度控制周期

  StepperPhaseActionType action, //相位操作回調函數

  StepperDelaymsType delayms //延時操作回調函數

  第1個參數為我們需要初始化的步進電機對象。而驅動模式、運作模式為枚舉,根據實際使用要求輸入即可。而速度周期為初始速度設定,隻要不是0的整數就可以。主要需要考慮的是後面兩個函數指針。其原型定義如下:

  typedef void (*StepperPhaseActionType)(uint8_t cmd);

  typedef void (*StepperDelaymsType)(uint32_t period);

  根據函數指針的原型定義,以及我們項目中具體用到的硬體配置,我們可以實作相位操作函數為:

/*步進電機相位操作*/
static void PhaseOperation(uint8_t cmd)
{
  GPIO_PinState AP,BP,CP,DP;
  
  AP=(GPIO_PinState)(cmd&0x01);
  BP=(GPIO_PinState)((cmd>>1)&0x01);
  CP=(GPIO_PinState)((cmd>>2)&0x01);
  DP=(GPIO_PinState)((cmd>>3)&0x01);
  
  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, BP);
  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_11, DP);
  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_13, AP);
  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_14, CP);
}
           

  而延時函數我們直接使用HAL_Delay,是以我們就可以實作步進電機對象的初始化操作如下:

/*步進電機對象初始化*/
  StepperInitialization(&chamber,   //步進電機對象
​              Half_Step,     //驅動模式
​              Mode_Speed,     //運作模式
​              10,          //速度控制周期
​              PhaseOperation,  //相位操作回調函數
​              HAL_Delay    //延時操作回調函數
​                );
           

3.2、基于對象進行操作

  初始化之後,我們就可以使用該對象來實作我們想要的操作了。我們設計一個應用函數調用相關驅動實作操作。

  我們可以實作位置控制模式如下:

  StepperPositionControl(&chamber,5000,Direct_CW);

  我們可以實作速度控制模式如下:

  StepperSpeedControl(&chamber);

  當然具體的操作模式需要在初始化函數中配置。

4、結論

  在本篇中我們設計并實作了基于ULN2003A的步進電機驅動程式。我們設計的測試示例運作正常。事實上該驅動在我們的項目中已經實際使用,到目前為止運作還算穩定。

  我們開篇說是面向低電壓的小功率的步進電機,但實際上如果我們通過ULN2003A控制MOS管是可以實作高電壓大功率的步進電機的,但我們是直接使用ULN2003A達林頓管是以才限定為低電壓小功率的步進電機。

  使用驅動是需要注意,該驅動方式不支援很高的運作速度。速度高時會出現力矩過小而堵轉的情形。我們實驗中所采用的電機一般控制在250Hz以下都可以穩定運作。

歡迎關注:

如果閱讀這篇文章讓您略有所得,還請點選下方的【好文要頂】按鈕。

當然,如果您想及時了解我的部落格更新,不妨點選下方的【關注我】按鈕。

如果您希望更友善且及時的閱讀相關文章,也可以掃描上方二維碼關注我的微信公衆号【木南創智】

繼續閱讀