在我们的项目中,经常使用到低电压小功率的步进电机,此类步进电机若采用驱动器控制不断成本高也过于复杂,我们可以直接使用场效应管或者达林顿管来实现对其的驱动。在本篇中,我们就来讨论一下基于ULN2003A达林顿管实现对步进电机的驱动。

1、功能概述

  我们先来了解一下基本的功能。ULN2003A达林顿管为7个输出通道,当导通时该通道连接到负端,所以非常适合于驱动4相5线步进电机。

1.1、ULN2003A达林顿管

  ULN2003A 器件是高电压大电流达林顿晶体管阵列。每 款器件均由7个NPN 达林顿对组成,这些达林顿对具有高压输出,带有用于开关感性负载的共阴极钳位二极管。 单个达林顿对的集电极电流额定值为500mA。将达林 顿对并联可以提供更高的电流。应用包括继电器驱动器、电锤驱动器、灯驱动器、显示驱动器(LED 和气体放电)、线路驱动器和逻辑缓冲器。其基本结构图如下:

1.2、步进电机基本原理

  在我们的测试中,我们使用4相5线步进电机。所谓4相5线步进电机就是该电机具有4组线圈5根连接线,实际上可能不只5根线,但公共端不管抽出多少根线,实际状态与1根无异。

  我们一般将这4组线圈记为A相、B相、C相和D相,当然,也可以用别的称呼,只要便于标记分别就好。4相5线步进电机一般采用单极性直流电源供电。只要对步进电机的各相绕组按合适的时序通电,就能使步进电机步进转动。一般电机都会提供控制表,具体如下所示:

  结合ULN2003A结构和4相5线步进电机的驱动要求,我们可以设计ULN2003A达林顿管驱动4相5线步进电机的驱动电路。

1.3、步进电机驱动模式

  步进电机的驱动虽然按照电机的驱动表就可以实现,但实际的驱动方式有多种,常见的如单波驱动方式、全步驱动方式、半步驱动方式以及微步驱动方式等。这里我们可以看一看前面三种比较简单的驱动方式。

  单波驱动方式又称之为单四拍工作方式。此种方式按固定次序依次驱动每一个线圈以达到使电机转动的目的。其波形如下:

  全步驱动方式又称之为双四拍工作方式。此种方式按固定次序依次驱动两组线圈以达到使电机转动的目的。其波形如下:

  半步驱动方式又称之为八拍工作方式。此种模式实际上是前两种模式的组合,以固定的次序依次激励一组或两组线圈以达到驱动电机的目的。其波形如下:

  上述波形即是在单波驱动方式、全步驱动方式以及半步驱动方式下使用示波器抓取的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以下都可以稳定运行。

欢迎关注:

步进电机驱动技术3:基于ULN2003的步进电机驱动相关推荐

  1. 基于matlab的步进电机转速控制仿真,基于matlab的步进电机转速控制仿真

    基于matlab的步进电机转速控制仿真 摘 要 一般电动机都是连续旋转,而步进电动却是一步一步转动的,故叫步进电动机.每输入一个冲信号,该电动机就转过一定的角度(有的步进电动机可以直接输出线位移,称为 ...

  2. 基于单片机的步进电机驱动电路设计

    基于单片机的步进电机驱动电路设计 步进电机在控制系统中具有广泛的应用.它可以把脉冲信号转换成角位移,并且可用作电磁制动轮.电磁差分器.或角位移发生器等. 有时从一些旧设备上拆下的步进电机(这种电机一般 ...

  3. 单片机控制两个步进电机画圆_基于单片机的步进电机转速控制设计详解(附程序)...

    步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件.在非超载的情况下,电机的转速.停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角.这 ...

  4. 新能源汽车800V电机驱动技术分析

    新能源汽车800V电机驱动技术分析 资料来自:驱动视界.网络.百度百科.搜狐 1.电驱系统发展趋势 2.800V电驱系统分析 3.面临的问题 1.电驱系统发展趋势 <节能与新能源汽车技术路线图2 ...

  5. 百度母婴技术团队—基于Reactjs实现webapp #1

    百度母婴技术团队-基于Reactjs实现webapp #1 Open my-fe opened this Issue 2 days ago · 16 comments Labels None yet ...

  6. linux升级ipv6协议栈,IPv6技术及基于Linux平台IPv6协议栈的实现

    IPv6技术及基于Linux平台IPv6协议栈的实现 简单介绍了 IPv6的基本原理和特征 ,重点探讨了 IPv6技术在 L inux环境中的应用 :对支持 IPv6协 (本文共5页) 阅读全文> ...

  7. 属性加密技术及基于属性的ABE算法的访问控制技术介绍

    属性加密技术 基于身份的加密体制简介 基于身份的加密体制可以看作一种特殊的公钥加密,它有如下特点:系统中用户的公钥可以由任意的字符串组成.这些字符串可以是用户在现实中的身份信息,如:身份证号码.用户姓 ...

  8. Spring AOP技术(基于AspectJ)的Annotation开发

    Spring AOP技术(基于AspectJ)的Annotation开发 @(Spring)[aop, spring, xml, Spring, annotation, aspectJ] Spring ...

  9. Spring AOP技术(基于AspectJ)的XML开发

    Spring AOP技术(基于AspectJ)的XML开发 @(Spring)[aop, spring, xml, Spring, annotation, aspectJ] Spring AOP技术基 ...

  10. 技术干货 | 基于MindSpore更好的理解Focal Loss

    [本期推荐专题]物联网从业人员必读:华为云专家为你详细解读LiteOS各模块开发及其实现原理. 摘要:Focal Loss的两个性质算是核心,其实就是用一个合适的函数去度量难分类和易分类样本对总的损失 ...

最新文章

  1. 正则表达式测试工具 Regex Tester 的使用方法
  2. 对AI行业未来发展的一些看法
  3. html5+调用safari,Safari浏览器不酷,HTML5无效元素; JavaScript是
  4. ASP.NET MVC Training Kit发布了
  5. maven工程xml文件路径问题
  6. html调用一个php文件路径_HTML中利用js调用php的内容
  7. mac/centos下添加永久alias
  8. Oracle客户端tnsnames.ora连接配置
  9. 手撸反向传播算法(附代码)
  10. opencv打开Lena图像,并且将Lena改成单通道的图片
  11. 深度解析输入偏置电流和输入失调电流的定义来源以及对电路的影响
  12. 计算机专业毕业了,还要不要参加培训班
  13. 3D打印了这个杜邦线理线神器,从此桌面再也不乱了
  14. 51单片机c语言数组怎么用,51单片机之C语言-4.2数组
  15. 这个Python脚本牛逼了,秒抢红包就算了,还能无视撤回消息
  16. VS2012(2013、2015) OpenCV “HEAP:Invalid Address specified to RtlValidateHeap( 000D0000, 019FEF18 )
  17. 如何在iPhone和iPad上隐藏IP地址,保护个人隐私信息
  18. RHEL7升级内核版本
  19. 我是漂移王-说明介绍
  20. Java –什么是-Xms和-Xmx参数?

热门文章

  1. 学习ectouch之文件结构
  2. W25Q64 的 QSPI 模式 问题
  3. 用excel做logistic回归分析_利用SPSS进行Logistic回归分析
  4. DotNetBar第三方控件详解
  5. 讲讲NVivo11的版本细节
  6. Webpower中国区发布《2015年中国酒店旅游行业邮件营销市场报告》
  7. Centos 7 离线安装dos2unix-7.4.0-3.el8.x86_64.rpm
  8. java nlpir_java实现NLPIR(ICTCLAS)分词
  9. 大数据时代,我竟然在用Excel和SPSS做数据分析,真香!
  10. Java多个PDF合成一个PDF的方法