设计分享 | STM32F103RCT6利用ULN2003驱动步进电机正反转

发布于:2022-11-09 ⋅ 阅读:(14) ⋅ 点赞:(0) ⋅ 评论:(0)

vx:嵌入式工程师成长日记

https://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484170&idx=1&sn=3fa68d0fbf30cf614e8779abf38c3e2b&chksm=cf430652f8348f44e4b95bb7b22ce7f9f5a86e13f421741aefd08cedb169708309c79566ab1f&token=1923877603&lang=zh_CN#rdicon-default.png?t=M85Bhttps://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484170&idx=1&sn=3fa68d0fbf30cf614e8779abf38c3e2b&chksm=cf430652f8348f44e4b95bb7b22ce7f9f5a86e13f421741aefd08cedb169708309c79566ab1f&token=1923877603&lang=zh_CN#rd

具体功能实现

接通电源后,电机开始正转,转够一圈后,电机开始反转,同时在OLED上会显示forward和reverse分别表示正反转

STM32F103RCT6原理图

器件

STM32F103RCT6,OLED屏,十根杜邦线 ,ULN2003步进电机拓展版,28BYJ-48步进电机

正反转展示图

正转展示图

此时,OLED屏上显示forward,电机正转

反转展示图

此时,OLED上显示reverse,电机反转

03

知识介绍

驱动电机的方法

①1相励磁法:

每一瞬间只有一个线圈相通,其它休息。

优点:简单,耗电低,精确性良好。

缺点:力矩小,振动大,每次励磁信号走的角度都是标称角度。 

 1相励磁法  A->B->C->D

②2相励磁法:

每一瞬间有两个线圈导通。

优点:力矩大,震动小。

缺点:每励磁信号走的角度都是标称角度。

2相励磁法  AB->BC->CD->DA

③1-2相励磁法:

1相和2相交替导通。

优点)精度较高,运转平滑,每送一个励磁信号转动1/2标称角度,称为半步驱动。(前两种称为4相4拍,这一种称为4相8拍)

1-2相励磁法  A-->AB-->B->BC->C-->CD->D-->DA

正转和反转代码(1-2相励磁法)

逆时针:

u8 phasecw[8] =

{0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};

//1000,1100,0100,0110,0010,0011,0001,1001

顺时针:

u8 phaseccw[8]=

{0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08};

// 顺时针

//1001,0001,0011,0010,0110,0100,1100,1000

上图是ULN2003步进电机驱动模块,可以看到上面的标号分别是A,B,C,D,因此代码我们可以按这个顺序来理解。

比如:AB是1100,BC是0110,CD是0011等

ULN2003电机驱动模块

上图为驱动模块原理图

ULN2003是高耐压、大电流复合晶体管阵列,由七个硅NPN 复合晶体管组成,每一对达林顿都串联一个2.7K 的基极电阻,在5V 的工作电压下它能与TTL 和CMOS 电路直接相连,可以直接处理原先需要标准逻辑缓冲器来处理的数据。

步进电机采用五线四相直流电速电机

其中:电压为5V,步进角度为5.625°,减速比为1/64,所以步距角为5.625/64=0.087°

意思就是,电机内部的转自转过5.626°,但是由于减速64倍所以外部的轴只转动0.087°。所需脉冲是360/0.087=4096个,由于采用四相八拍驱动,因此八个脉冲为一个周期,所以外部转动一周需要4096/8=512个周期。

04

主函数代码(C语言)KEIL5实现

main.c(主函数代码)

#include "stm32f10x.h"

#include "delay.h"

#include "step.h"

#include "OLED.h"

int main(void)

{

   Step_Motor_GPIO_Init();

   delay_init();

    OLED_Init();

    OLED_ShowString(1,1,"direction:");

   while(1){

     motorNcircle(1,true);//n为步进电机转动的圈数,position为正转或者反转

delay_ms(20);

motorNcircle(1,false);//n为步进电机转动的圈数,position为正转或者反转

}

}



//step.c(电机驱动函数)

#include "OLED.h"

#include "stdbool.h"

#include "sys.h"

#include "delay.h"

#include "step.h"

u8 phasecw[8] =

{0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};

// 逆时针

//1000,1100,0100,0110,0010,0011,0001,1001

u8 phaseccw[8]=

{0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08};

// 顺时针

//1001,0001,0011,0010,0110,0100,1100,1000

//引脚初始化

void Step_Motor_GPIO_Init(void)

{

   GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6|GPIO_Pin_5;

   GPIO_Init(GPIOB,&GPIO_InitStructure);  

}

//引脚映射

void SetMotor(unsigned char InputData)

{

   if(InputData&0x01)

   {

       GPIO_SetBits(GPIOB,GPIO_Pin_5);

   }

   else

   {

       GPIO_ResetBits(GPIOB,GPIO_Pin_5);

   }

   if(InputData&0x02)

   {

       GPIO_SetBits(GPIOB,GPIO_Pin_6);

   }

   else

   {

       GPIO_ResetBits(GPIOB,GPIO_Pin_6);

   }

   if(InputData&0x04)

   {

       GPIO_SetBits(GPIOB,GPIO_Pin_7);

   }

   else

   {

       GPIO_ResetBits(GPIOB,GPIO_Pin_7);

   }

   if(InputData&0x08)

   {

       GPIO_SetBits(GPIOB,GPIO_Pin_8);

   }

   else

   {

       GPIO_ResetBits(GPIOB,GPIO_Pin_8);

   }

}

//步距角5.625 360/5.625=64 减速比1/64

//故64*64个脉冲转一圈

//n圈数

//position 方向

void motorNcircle(int n,bool position)//n为步进电机转动的圈数,position为正转或者反转

{

   int i,j,k=0;

   for(j=0;j<n;j++)

   {

      for(i=0;i<64*5.625;i++)

       {

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

           {

               if(1 == position)

               {

OLED_ShowString(2,1,"forward");

                   SetMotor(phasecw[k]);

               }

               else

               {

OLED_ShowString(2,1,"reverse");

                   SetMotor(phaseccw[k]);

               }

               delay_ms(1);

           }

       }

   }

}

工程文件请在前面vx处领取~

问题解答

Q

为什么stm32需要接ULN2003才能驱动?

A

因为stm32的电流还达不到步进电机所需的最小电流,而ULN2003可以增大stm32的电流,提高驱动能力