步进电机驱动技术3:基于ULN2003的步进电机驱动

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

欢迎关注:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499327.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通讯接口应用笔记2:MAX3160实现多协议通讯

在一些应用需求中,我们需要对外部提供串行通讯端口,但这些端口所通讯的目标设备各有不同,接口协议也有RS232以及RS485和RS422多种。面对这种情况,我们当然可以同时设计多个串口以适应不同需要,但无疑对硬件资源是一种浪…

电机速度曲线规划1:梯形速度曲线设计与实现

电机驱动是很常见的应用,在很多系统中我们都会碰到需要改变电机的速度以实现相应的控制功能,这就涉及到电机速度曲线规划的问题。在这篇中我们就来简单讨论一下电机的梯形曲线规划的问题。 1、基本原理 梯形速度曲线控制算法是工业控制领域应用最为广泛…

文件系统应用笔记之一:FatFS在STM32F4上的移植

在实现如U盘文件读写,SD卡的文件读写等工作时,我们往往需要一个文件系统来支持我们的工作。特别在一些MCU应用中,文件系统的加入能明显改善系统交互的友好性。在这一篇中,我们就来讨论FatFS文件系统在STM32F4上的移植和应用。 1、…

通讯接口应用笔记3:使用W5500实现Modbus TCP服务器

前面我们设计实现了W5500的驱动程序,也讲解了驱动的使用方式。在最近一次的项目应用中,正好有一个使用W5500实现TCP通讯的需求,所以我们就使用该驱动程序轻松实现。这一篇中我们就来说一说基于我们W5500通讯驱动程序实现TCP通讯的过程。 1、…

电机速度曲线规划2:S形速度曲线设计与实现

电机驱动是很常见的应用,在很多系统中我们都会碰到需要改变电机的速度以实现相应的控制功能,这就涉及到电机速度曲线规划的问题。在这篇中我们就来简单讨论一下电机的S型曲线规划的问题。 1、基本原理 S型速度曲线控制算法是工业控制领域另一种常用的加…

USB应用开发笔记之一:STM32上实现USB主机读写U盘

在项目应用中,经常会有对外交换数据的需求。USB接口读写U盘无疑是一种颇为方便的选择。在这一篇中,我们就来讨论如何在STM32上实现USB主机读写U盘文件的方法。 1、应用概述 在我们的产品上有这样一个需求,希望通过大容量的U盘存取数据。我们…

Modbus协议栈综合实例设计

自我们开源了我们的Modbus协议栈之后,就一直有朋友来信说希望提供示例。这次我们整理了几个例子以供参考。 1、应用实例规划 在这次的实例中,我们使用的目标板拥有一个以太网接口、一个RS232串行接口和一个RS485串行接口,所以我们规划实现&a…

ThreadX应用开发笔记之二:移植ThreadX到STM32H7平台

前面我们将ThreadX成功移植到了STM32F4平台,但这只是我们的部分应用。我们希望将ThreadX的优势发挥到我们的更多应用中,所以在这一篇中我们就来实现将ThreadX移植到STM32H7平台中。 1、前期准备 在开始将ThreadX移植到STM32H7平台之前,我们需…

外设驱动库开发笔记31:S-Modlue远红外气体传感器驱动

在气体分析类产品中,我们经常会用到远红外气体传感器。我们就在碳氢类气体成分分析中使用了S-Modlue远红外气体传感器。接下来,我们将讨论S-Modlue远红外气体传感器驱动的设计与实现。 1、功能概述 S-MODULE EVO 使用非分散红外检测技术NDIR&#xff0c…

外设驱动库开发笔记32:HLPM025K3 PM2.5传感器驱动

现在人们对大气环境及室内环境都比较关注。PM2.5在生活中也是常见的词汇。在有些产品中就要求检测PM2.5的数值。检测PM2.5的手段多种多样,在要求不高时我们通常可以采用激光模块。在这一篇中,我们将讨论HLPM025K3 PM2.5传感器驱动的设计与实现。 1、功能…

外设驱动库开发笔记33:LCD1602液晶显示屏驱动

LCD1602是一种工业字符型液晶,能够同时显示16x02即32个字符。LCD1602液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,即可以显示出图形。在这一章我们就来讨论LCD1602液晶显示屏驱动的设计与实现。 1、功能概述 LCD1602液…

滤波器开发之四:基于算术平均的中值滤波器

在信号采集系统中,除了我们感兴趣的数据外,难免会有一些来自于环境的干扰信号。但我们总希望我们得到的数据是纯净而真实的,为了达到这个目标,我们不得不想办法去除这些干扰信号,于是滤波器就成为我们必不可少的帮手。…

LwIP应用开发笔记之十一:LwIP带操作系统UDP服务器

我们已经实现了在FreeRTOS系统上的LwIP的移植工作,但只是简单的在系统平台上跑了起来。我们还希望能做更多的事情,这一节我们就在FreeRTOS系统上实现基于LwIP的UDP服务器。 1、UDP协议简述 UDP协议全称是用户数据报协议,在网络中它与TCP协议…

滤波器开发之五:基于算术平均的限幅滤波器

通过AD采集数据时,我们总是希望采集到的数据是纯净而真实的,而实际上环境中存在太多的干扰信号,为了让我们得到的数据尽可能地接近实际值,我们需要降低这些干扰信号的影响。所以软件实现的数字滤波器应运而生,这一篇我…

外设驱动库开发笔记34:OLED显示屏驱动

现在OLED显示屏在嵌入式系统中应用的越来越多。对于一些显示信息不太复杂,以显示信息为主的需求,我们一般会选择OLED显示屏。在这一篇中,我们将讨论OLED显示屏驱动的设计与实现。 1、功能概述 从使用的情况来说,较为常用的是0.96…

外设驱动库开发笔记35:迪文触摸屏驱动

有些时候嵌入式系统也需要显示更为复杂的图形,需要更丰富的数据展示。为此,我们需要更大,色彩更丰富,带触屏的显示屏,当然性价比更高就最好了。在我们的项目中遇到此类需求,我们有时会选择DWIN触摸屏。在本…

快速实现一个室内空气质量检测仪

冬天我们大多会关闭门窗,而依靠暖通空调设备来维持室内温度。而在保证居室温度的同时,我们也希望保持居室内大气环境的健康度。鉴于此,我们设计了一个简单的室内空气质量检测器。 1、系统概述 我们依靠暖通空调设备来维持室内温度、湿度和通…

外设驱动库开发笔记36:NTC负温度系数热电阻测温驱动

在嵌入式产品中,温度检测非常常见。在成本比较敏感而精度要求较低时,NTC电阻是个不错的选择。在这一篇中,我们将讨论如何和设计并实现一个通用的NTC驱动,以便在后续的项目中更方便的复用。 1、功能概述 NTC是指随温度上升电阻呈指…

外设驱动库开发笔记37:S1336-5BQ光敏二极管作为光度计驱动

光敏二极管能够实现很多应用,用于光度检测即是其一。我们在一些产品中就曾使用S1336-5BQ光敏二极管进行光度值检测。所以在本篇中,我们将讨论如何设计并实现S1336-5BQ光敏二极管用于光度检测的驱动。 1、功能概述 根据相关的资料,光电二极管…

PID控制器改进笔记之六:改进PID控制器之参数设定

前面我们发布了一系列PID控制器相关的文章,包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能,也在实际使用中取得了良好效果,但还有很多的细节部分可以改进以提高性能和灵活性。这篇中我们来讨论改进PID控制…