1. 程式人生 > 其它 >STM32通過ULN2003對步進電機進行控制

STM32通過ULN2003對步進電機進行控制

1 前言

本實驗是基於STM32103晶片和ULN2003進行對步進電機的控制。

2 ULN2003的基本介紹

2.1 ULN2003的概述

ULN2003是高耐壓、大電流複合電晶體陣列,由七個矽NPN 複合電晶體組成。一般採用DIP—16SOP—16 塑料封裝。

ULN2003的主要特點:

  • ULN2003 的每一對達林頓都串聯一個2.7K 的基極電阻,在5V 的工作電壓下它能與TTL 和CMOS 電路直接相連,可以直接處理原先需要標準邏輯緩衝器來處理的資料。
  • ULN2003 工作電壓高,工作電流大,灌電流可達500mA,並且能夠在關態時承受50V 的電壓,輸出還可以在高負載電流並行執行。

2.2 ULN2003的作用

ULN2003是大電流驅動陣列,多用於微控制器、智慧儀表、PLC、數字量輸出卡等控制電路中,可直接驅動繼電器等負載

輸入5VTTL電平,輸出可達500mA/50V。

簡單地說,ULN2003其實就是用來放大電流的,增加驅動能力。比如說微控制器輸出引腳一般輸出就幾mA,是無法驅動電機、繼電器或者電磁閥的,像要讓直流電機轉需要500mA,而用ULN2003放大後,可以通過微控制器的輸出引腳直接控制這些裝置。而我們文章的目的是使用ULN2003晶片來增大微控制器的輸出電流使得微控制器的輸出電流可以驅動步進電機。

2.3 ULN2003的引腳圖和功能

  • 引腳1:CPU脈衝輸入端,埠對應一個訊號輸出端;
  • 引腳2:CPU脈衝輸入端;
  • 引腳3:CPU脈衝輸入端;
    引腳4:CPU脈衝輸入端;
  • 引腳5:CPU脈衝輸入端;
    引腳6:CPU脈衝輸入端;
  • 引腳7:CPU脈衝輸入端;
  • 引腳8:接地;
    引腳9:該腳是內部7個續流二極體負極的公共端,各二極體的正極分別接各達林頓管的集電極。用於感性負載時,該腳接負載電源正極,實現續流作用。如果該腳接地,實際上就是達林頓管的集電極對地接通;
  • 引腳10:脈衝訊號輸出端,對應7腳訊號輸入端;
  • 引腳11:脈衝訊號輸出端,對應6腳訊號輸入端;
  • 引腳12:脈衝訊號輸出端,對應5腳訊號輸入端;
  • 引腳13:脈衝訊號輸出端,對應4腳訊號輸入端;
  • 引腳14:脈衝訊號輸出端,對應3腳訊號輸入端;
  • 引腳15:脈衝訊號輸出端,對應2腳訊號輸入端;
  • 引腳16:脈衝訊號輸出端,對應1腳訊號輸入端。

2.4 ULN2003工作原理驅動應用電路

ULN2003是高耐壓、大電流複合電晶體陣列,由七個矽NPN 複合電晶體組成,每一對達林頓都串聯一個2.7K 的基極電阻,在5V 的工作電壓下它能與TTL 和CMOS 電路直接相連,可以直接處理原先需要標準邏輯緩衝器來處理的資料。

LN2003也是一個7路反向器電路,即當輸入端為高電平時,ULN2003輸出端為低電平;當輸入端為低電平時,ULN2003輸出端為高電平。

ULN2003是一個非閘電路,包含7個單元,單獨每個單元驅動電流最大可達500mA,9腳可以懸空。比如1腳輸入,16腳輸出,你的負載接在VCC與16腳之間,不用9腳。

根據上面的原理,ULN2003的驅動應用電路的基本示例圖,各個引腳的功能都標註在上面:

這裡需要注意的是:儘管按照官方文獻要求,控制電壓輸入需要在5V,其實只需要超過2.5V的電平訊號基本都能夠算作是高電平。也就是說,3.3V的微控制器的IO口的高電平輸出就能夠直接來進行ULN2003的控制輸入了。

再介紹一個實際例程的ULN2003的驅動應用電路:

3 28BYJ48型步進電機

3.1 步進電機簡介

28BYJ48型步進電機是四相八拍電機,電壓為DC5V~DC12V。當對步進電機按一定順序施加一系列連續不斷的控制脈衝時,它可以連續不斷地轉動。每一個脈衝訊號使得步進電機的某一相或兩相繞組的通電狀態改變一次,也就對應轉子轉過一定的角度。當通電狀態的改變完成一個迴圈時,轉子轉過一個齒距。四相步進電機可以在不同的通電方式下執行。

  • 單(單相繞組通電)四拍(A-B-C-D-A……)
  • 雙(雙相繞組通電)四拍(AB-BC-CD-DA-AB……)
  • 四相八拍(A-AB-B-BC-C-CD-D-DA-A……)。

所以說,要想啟動步進電機只需要依次給各個相輸入高電平訊號就可以了。注意,當給某一相輸入訊號的時候,其他相要重新置0。也就是說,同一時刻只能保持有一個相。

3.2 步進電機引數

4 STM32控制程式

步進電機是一種將電脈衝轉化為角位移的執行裝置。通俗一點講:當步進驅動器接收到一個脈衝訊號,它就驅動步進電機按設定的方向轉動一個固定的角度(即步進角)。我們可以通過控制脈衝個數來控制角位移量,從而達到準確定位的目的;同時我們可以通過控制脈衝頻率來控制電機轉動的速度和加速度,從而達到調速的目的。

4.1 硬體配置

  • 微控制器:STM32103C8T6
  • 步進電機:28BYJ-48
  • 驅動電路:ULN2003晶片的驅動板
  • 引腳連線:IN1 ----- PB6
    IN2 ----- PB7
    IN3 ----- PB8
    IN4 ----- PB9
    OUT1:步進電機4、OUT2:步進電機3、OUT3:步進電機2、OUT4:步進電機1、步進電機5:
    VCC電源正極(5V)、GND:共地、COM:VCC電源正極(5V)。
  • 5V直流電源:STM32F103ZET6開發板上的5V電壓引腳(下圖中的VCC)。

4.2 控制程式碼

motor.h

/***************************************************************************************
$ @ Copyright    : 
$ @ Author       : Krone
$ @ Data         : Do not edit
$ @ LastEditor   : 
$ @ LastData     : 
$ @ Describe     : 
*****************************************************************************************/
#ifndef MOTOR_H__
#define MOTOR_H__
#include <stdio.h>
#include <string.h>

#define  MOTOR_CLK               (RCC_APB2Periph_GPIOB)
#define  MOTOR_PORT              (GPIOB)
#define  MOTOR_IN1_PIN           (GPIO_Pin_6)
#define  MOTOR_IN2_PIN           (GPIO_Pin_7)
#define  MOTOR_IN3_PIN           (GPIO_Pin_8)
#define  MOTOR_IN4_PIN           (GPIO_Pin_9)

void Moto_Init(void);
void Motor_Forward_Ration(void);  //反轉
void Motor_Reverse_Rotation(void);  //正轉
void MotorStop(void); //停止
void Motor_Ctrl_Direction_Angle(int direction, int angle);//控制電機正轉還是反轉某個角度

#endif

motor.c

/***************************************************************************************
$ @ Copyright    : 
$ @ Author       : Krone
$ @ Data         : Do not edit
$ @ LastEditor   : 
$ @ LastData     : 
$ @ Describe     : 
*****************************************************************************************/
#include "motor.h"
#include "delay.h"

uint16_t phasecw[4] ={0x0200,0x0100,0x0080,0x0040}; /*   D-C-B-A  反轉 */
uint16_t phaseccw[4]={0x0040,0x0080,0x0100,0x0200}; /*	 A-B-C-D   正轉 */
/*---------------------------------電機模組與微控制器連線引腳---------------------------------------------------*/
/* IN4: PB9  d */
/* IN3: PB8  c */
/* IN2: PB7  b */ 
/* IN1: PB6  a */

void Moto_Init(void)
{
	 GPIO_InitTypeDef GPIO_InitStructure;
	 RCC_APB2PeriphClockCmd(MOTOR_CLK,ENABLE);

	 GPIO_InitStructure.GPIO_Pin = MOTOR_IN1_PIN | MOTOR_IN2_PIN | MOTOR_IN3_PIN | MOTOR_IN4_PIN ;//引腳按著INT1順序接就行了
	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	 GPIO_Init(GPIOB,&GPIO_InitStructure);
	 GPIO_ResetBits(MOTOR_PORT, MOTOR_IN1_PIN | MOTOR_IN2_PIN |MOTOR_IN3_PIN |MOTOR_IN4_PIN );
}
// 正轉
void Motor_Forward_Ration(void)  
{  
    int i;  
    for(i=0;i<4;i++)  
    {  
        GPIO_Write(MOTOR_PORT, phaseccw[i]);  
        delay_ms(1);  
    }  
}
// 反轉
void Motor_Reverse_Rotation(void)  
{  
	uint8_t i;  
    for(i=0;i<4;i++)  
    {  
        GPIO_Write(MOTOR_PORT, phasecw[i]);  
        delay_ms(1);  
    }  
}
//停止
void MotorStop(void) 
{  
    GPIO_Write(MOTOR_PORT, 0x0000);  
}

//控制電機正轉還是反轉某個角度
//direction方向,1為正轉,0為反轉
//angle角度,可為0-360具有實際意義
void Motor_Ctrl_Direction_Angle(int direction, int angle)
{
	uint16_t i;

	if(direction == 1)
	{								
		for(i = 0; i < 64*angle/45; i++) 
		{
			/* 正轉 */
			Motor_Forward_Ration();
		}
		MotorStop();//停止
  	}
	else
	{
		for(i = 0; i < 64*angle/45; i++) 
		{
			/* 反轉 */
			Motor_Reverse_Rotation(); 
		}
		 MotorStop();//停止
	}
}