您的位置:首页 > 其它

STM32+ULN2003驱动步进电机

2014-05-12 00:06 543 查看
选用的步进电机的型号为28BYJ-48(或MP28GA,5V,转速比1/64),驱动电路选用uln2003芯片的驱动板,其控制时序图如下:

四相八拍:A->AB->B ->BC ->C ->CD ->D ->DA

其A、B、C、D指的是uln2003芯片驱动板的1N1、1N2、1N3、1N4,波形在上表示有输入信号。

此外至少需要4根杜邦线,还需提供一个5V的直流电源,接线方式如下:

PE0接IN1

    PE1接IN2 

    PE2接IN3

    PE3接IN4 

    5V电源(一个是地,一个是正)。

/***************************************************************************//**

 * @file : stm32_pio.h

 * @brief : STM32F1xx CoX PIO Peripheral Interface

 * @version : V1.0

 * @date : 28 Feb. 2011

 * @author : CooCox

*******************************************************************************/

#ifndef __STM_PIO_H

#define __STM_PIO_H

#include "cox_pio.h"

/***************************************************************************//**

 * Define STM32F1xx CoX PIO Peripheral Interface

*******************************************************************************/

extern COX_PIO_PI pi_pio;

#endif

/***************************************************************************//**

 * @file : stm32_pio.c

 * @brief : STM32F1xx CoX PIO Peripheral Interface

 * @version : V1.0

 * @date : 28 Feb. 2011

 * @author : CooCox

 ******************************************************************************/

#include "stm32_pio.h"

#include "stm32f10x.h"

/***************************************************************************//**

 * @brief Get pointer to GPIO peripheral due to GPIO
port

 * @param[in] portNum : Port
Number value, should be in range from 0 to 6.

 * @return Pointer to GPIO peripheral

*******************************************************************************/

static GPIO_TypeDef* STM32_GetGPIO(uint8_t port)

{

    GPIO_TypeDef *pGPIO = COX_NULL;

    switch(port)

    {

        case 0: pGPIO = GPIOA; break;

        case 1: pGPIO = GPIOB; break;

        case 2: pGPIO = GPIOC; break;

        case 3: pGPIO = GPIOD; break;

        case 4: pGPIO = GPIOE; break;

        case 5: pGPIO = GPIOF; break;

        case 6: pGPIO = GPIOG; break;

        default: break;

    }

    return pGPIO;

}

/***************************************************************************//**

 * @brief Initializes the PIO peripheral

 * @param[in] pio : The
specified peripheral

 * @return Result, may be :

 * -COX_ERROR : Error occurred, parameter is not supported

 * -COX_SUCCESS : Previous argument of the specified option

*******************************************************************************/

static COX_Status STM32_PIO_Init (COX_PIO_Dev pio)

{

    GPIO_TypeDef* pGPIO = COX_NULL;

    uint8_t port, pin;

    port = (pio >> 8) & 0xFF;

    pin = (pio >> 0) & 0xFF;

    pGPIO = STM32_GetGPIO(port);

    if(port >6 || port<0 || pin<0 || pin > 15)

        return COX_ERROR;

    /* Enable GPIO and AFIO clocks */

    switch(port)

    {

        case 0: RCC->APB2ENR |= (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN); break;

        case 1: RCC->APB2ENR |= (RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN); break;

        case 2: RCC->APB2ENR |= (RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN); break;

        case 3: RCC->APB2ENR |= (RCC_APB2ENR_IOPDEN | RCC_APB2ENR_AFIOEN); break;

        case 4: RCC->APB2ENR |= (RCC_APB2ENR_IOPEEN | RCC_APB2ENR_AFIOEN); break;

        default: break;

    }

  return COX_SUCCESS;

}

/***************************************************************************//**

 * @brief Set direction (Input or Output)

 * @param[in] pio : The
specified PIO peripheral

 * @param[in] dir : Direction, should
be

 * -0: Input

 * -1: Output

 * @return Result, may be :

 * -COX_ERROR : Error occurred, parameter is not supported

 * -COX_SUCCESS : Previous argument of the specified option

*******************************************************************************/

static COX_Status STM32_PIO_SetDir(COX_PIO_Dev pio, uint8_t dir)

{

    GPIO_TypeDef* pGPIO = COX_NULL;

    uint8_t port, pin;

    port = (pio >> 8) & 0xFF;

    pin = (pio >> 0) & 0xFF;

    pGPIO = STM32_GetGPIO(port);

    /* Direction is input:GPIO_Mode_IN_FLOATING */

    if(dir == 0){

        if(pin>7)

        {

            /* Configure the eight high port pins */

            pin = pin-8;

            /* MODE[1:0]=00 */

            pGPIO -> CRH &= ~(0x3 << (pin*4));

            /* CNF[1:0] =01 */

            pGPIO -> CRH &= ~(0x8 << (pin*4));

            pGPIO -> CRH |= (0x4 <<(pin*4));

        }

        else

        {

            /* Configure the eight low port pins */

            pGPIO -> CRL &= ~(0x3 << (pin*4));

            pGPIO -> CRL &= ~(0x8 << (pin*4));

            pGPIO -> CRL |= (0x4 << (pin*4));

        }

    }

    /* Direction is output:GPIO_Mode_Out_PP */

    else {

        if(pin>7)

        {

            pin = pin-8;

            /* MODE[1:0]=11 */

            pGPIO -> CRH |= (0x3 <<(pin*4));

            /* CNF[1:0] =00 */

             pGPIO -> CRH &= ~(0xc <<(pin*4));

        }

        else

        {

            pGPIO -> CRL |= (0x3 << (pin*4));

            pGPIO -> CRL &= ~(0xc<<(pin*4));

        }

    }

    return COX_SUCCESS;

}

/******************************<span
s

uln2003 驱动 继电器及步进电机

由于单片机的驱动能力较弱,使用继电器、步进电机等外设时,一般需要外接5v 12v电源驱动,使用uln2003即可使用小电压控制大电压的通断。
 
uln2003
 
uln2003的内部是一组达林顿管,你可以理解为放大倍数很高的三极管,你用到的控制极就是其基极,所以,它有0.7V电压就可以工作了。但一般在使用时,还是要保证提供2V以上,不然可能不会很可靠。
 
    原理图                                                     应用电路


 


 
单片机的I/O口直接和ULN2003连,ULN2003有16个脚共7路驱动.
ULN2003的8脚接5V电源地,9脚接+5V或12V电源,因为ULN2003里面有续流二极管从9脚引出.
 
假如你用P1.0驱动一个电机,那么P1.0接ULN2003的1脚,ULN2003的16脚接电机线圈的一端,电机线圈的另一端接+5V电源.P1.0为高电平,电机就转,P1.0为低电平,电机就停.ULN2003驱动电流500MA.
 
这个器件用起来很简单,它是一个不能输出高电平的反相器,就是说你输入高电平的时候,输出低电平,你输入低电平的时候它就成高阻态(就是电阻很大,可以看成短路,这时如果你加上拉电阻的话输出就会拉成高电平)。
 
一般他的用法就当成电子开关用,就是你输入高电平的时候它相应的端口会输出低电平,而且这个低电平能吸收的电流达500mA。所以一般就是电机或者其他用电器的一段接ULN2003 的输出口(像接了一个开关然后再接到低)。还有一段接高电平或者电源。使用的时候就把相应的端口置高电平就会打开开关,让电机形成对地的回路,从而让电机运行;如果相应的端口为低电平,输出为高阻态,就像断开了对地的开关,从而不形成回路让电机关闭。
 
继电器
 


(继电器型号: hjr-4120-*v   *为线圈控制电压)
 

一般继电器的外壳有标注,如果没有,自己用万用表测一下也很简单:
 
1、找出线圈引脚。
    用万用表测各引脚间的电阻,阻值在数百至1K欧姆左右的两个脚是线圈引脚。注意有些继电器的线圈分正负极,反接虽然不至于损坏,但不动作。
 
2、找出常开、常闭点。
    用万用表测除线圈之外的四个引脚,导通的两个引脚是常闭关 系,给线圈加上5V(继电器线圈有效电压)直流电,使继电器动作,它们应断开;如果没有断开,则内部是短接关系。
    给线圈加上5V(继电器线圈有效电压)直流电,使继电器动作,此时再用万用表测,如果有原来不通的两个引脚导通了,则它们是常开关系。
 
    既与常开点有关系,又与常闭点有关系的引脚,就是公共端。

 
步进电机
 
相关特性:

1、 步进电机必须加驱动才可以运转, 驱动信号必须为脉冲信号,没有脉冲的时候,
步进电机静止, 如果加入适当的脉冲信号, 就会以一定的角度(称为步角)转动。转
动的速度和脉冲的频率成正比。
2、28BYJ48 5V 驱动的4 相5 线的步进电机,而且是减速步进电机,减速比为1:64,步进角为5.625/64 度。
如果需要转动1 圈,那么需要360/5.625*64=4096 个脉冲信号。
3、 步进电机具有瞬间启动和急速停止的优越特性。
4、 改变脉冲的顺序, 可以方便的改变转动的方向。
 
因此,目前打印机,绘图仪,机器人,等等设备都以步进电机为动力核心。
 

每一个脉冲信号对应步进电机的某一相或两相绕组的通电状态改变一次,也就对应转子转过一定的角度(一个步距角)。当通电状态的改变完成一个循环时,转子转过一个齿距。四相步进电机可以在不同的通电方式下运行,常见的通电方式有单(单相绕组通电)四拍(A-B-C-D-A。。。),双(双相绕组通电)四拍(AB-BC-CD-DA-AB-。。。),八拍(A-AB-B-BC-C-CD-D-DA-A。。。)。
 

采用四拍方式驱动:



将单片机IO(如P1)接到uln2003输入端,将步进电机的信号线对应接到uln2003的输出口,根据上表可以单片机IO口的8个驱动脉冲信号为:

uchar code Step_1[8]={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09}; //逆时钟旋转相序表
uchar code Step_2[8]={0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08}; //正时钟旋转相序表
 
uln2003驱动继电器  步进电机原理图:
 




28byj48步进电机工作时序图和stm32+uln2003驱动代码  

2013-04-30 11:30:41|  分类: 单片机 |  标签:stm32  28byj48  步进电机  |举报|字号 订阅



 void init_stepmotor_GPIO(void)
{
//打开时钟
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

//GPIO设置
      GPIO_InitTypeDef GPIO_InitStructure;   
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;   
      GPIO_Init(GPIOA,&GPIO_InitStructure);  
}

void motor_cw(uint32_t circle,uint32_t delay)//circle循环数 delay控制转速
{
  uint32_t i,j;
  j=2000;
  for(i=0;i<=circle;i++)
  {
   GPIO_Write(GPIOA, 8);
   motor_delay(j);
   GPIO_Write(GPIOA, 12);
   motor_delay(j);
   GPIO_Write(GPIOA, 4);
   motor_delay(j);
   GPIO_Write(GPIOA, 6);
   motor_delay(j);
   GPIO_Write(GPIOA, 2);
   motor_delay(j);
   GPIO_Write(GPIOA, 3);
   motor_delay(j);
   GPIO_Write(GPIOA, 1);
   motor_delay(j);
   GPIO_Write(GPIOA, 9);
   motor_delay(j);
   motor_delay(delay);//这个控制转速
  }
}

void motor_ccw(uint32_t circle,uint32_t delay)
{
  uint32_t i,j;
  j=2000;
  for(i=0;i<=circle;i++)
  {
   GPIO_Write(GPIOA, 9);
   motor_delay(j);
   GPIO_Write(GPIOA, 1);
   motor_delay(j);
   GPIO_Write(GPIOA, 3);
   motor_delay(j);
   GPIO_Write(GPIOA, 2);
   motor_delay(j);
   GPIO_Write(GPIOA, 6);
   motor_delay(j);
   GPIO_Write(GPIOA, 4);
   motor_delay(j);
   GPIO_Write(GPIOA, 12);
   motor_delay(j);
   GPIO_Write(GPIOA, 8);
   motor_delay(j);
   motor_delay(delay);//这个控制转速
  }
}

void motor_delay(uint32_t delay)
{
  uint32_t i;
  for(i=1;i<delay;i++)
    {
    asm("nop");
    } 
}


28BYJ48型步进电机的控制方法  

2011-03-13 23:02:00|  分类: 单片机技术|举报|字号 订阅

  前不久弄到一只28BYJ48型步进电机,没有资料,从网上查找,搜到一些资料,但按照网上介绍的程序实验,都没有成功。后来根据资料的原理部分,试着自己编写了一段程序,经过多次实验调试,终于成功了。

  哈哈,收获不小!!!

  步进电机是一种将电脉冲转化为角位移的执行设备。通俗一点讲:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(即步进角)。我们可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时我们可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。

  28BYJ48型步进电机是四相八拍电机,电压为DC5V~DC12V。当对步进电机按一定顺序施加一系列连续不断的控制脉冲时,它可以连续不断地转动。每一个脉冲信号使得步进电机的某一相或两相绕组的通电状态改变一次,也就对应转子转过一定的角度。当通电状态的改变完成一个循环时,转子转过一个齿距。四相步进电机可以在不同的通电方式下运行,常见的通电方式有单(单相绕组通电)四拍(A-B-C-D-A……),双(双相绕组通电)四拍(AB-BC-CD-DA-AB……),四相八拍(A-AB-B-BC-C-CD-D-DA-A……)。本例是使用四相八拍驱动方式实现的。

  下面是我写的C语言控制程序实现28BYJ48型步进电机正转五圈然后倒转五圈的效果:

//********************************************************************************

//*  标题:  步进电机正反转演示程序                                               *

//*  文件:  步进电机正反转演示.C                                                 *

//*  日期:  2011-3-13                                                            *

//*  环境:  使用自制单片机最小系统板测试通过                                     *

//********************************************************************************

//*  描述:  28BYJ-48步进电机正反转控制                                           *

//*  电机使用端口:P1.0、P1.1、P1.2、P1.3                                        *

//*  单双八拍工作方式:A-AB-B-BC-C-CD-D-DA                                       *

//********************************************************************************

#include <reg51.h>

#include <intrins.h>

//**********************正向旋转相序表*****************************

unsigned char code FFW[8]={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};

//**********************反向旋转相序表***************************** 

unsigned char code REV[8]={0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08};

//***********************延时子程序******************************** 

void delay(unsigned int t)

{                          

   unsigned int k;

   while(t--)

   {

     for(k=0; k<125; k++)

     {}

   }

}

 

//**********************步进电机正转****************************** 

void  motor_ffw(unsigned int n)

 {

   unsigned char i;

   unsigned int  j;

   for (j=0; j<8*64*n; j++)

    {

      for (i=0; i<8; i++)

        {

          P1 = FFW[i];

         delay(1);

         }

    }

 }

 

//*********************步进电机反转******************************** 

void  motor_rev(unsigned int n)

{

    unsigned char i;

  unsigned int  j;

  for (j=0; j<8*64*n; j++)

      {

        for (i=0; i<8; i++)

        {

          P1 = REV[i];

          delay(1);

        }

      }

 }

 

//*************************主程序*********************************

main()

 {  

   while(1)                    

    { 

       motor_ffw(5);          //电机正转5圈

       delay(1000);

       motor_rev(5);          //电机反转5圈

       delay(1000);

    }

 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uln2003 步进电机