最近做了步进电机的试验,从网上查找了一下ULN2003的资料,并根据步进电机的工作原理,自己设计了一段代码,起初电机没有转起来,增加电机驱动脉冲的频率后,电机转起来了。
28BYJ_48型步进电机是四相八拍电机,电压为DC5V~DC12V。关于步进电机的详细资料,可以在网上查找,也可以看博客:“http://blog.csdn.net/super_demo/article/details/25570067”里面的介绍,本文主要使用四相八拍(A-AB-B-BC-C-CD-D-DA一个循环)驱动电机运行,关于四相八拍的驱动顺序,可以参考ULN2003驱动板上说明。
步进电机驱动电路选用uln2003芯片的驱动板,其控制时序为:
四相八拍:A->AB->B ->BC ->C ->CD ->D ->DA
其A、B、C、D指的是uln2003芯片驱动板的1N1、1N2、1N3、1N4。
接线方式如下:
PA1接IN1
PA2接IN2
PA3接IN3
PA4接IN4
5V电源(一个是地,一个是正)是从单片机上供给ULN2003模块。
具体的程序实现方式如下:
/************************************************************************************************
** 函数名称:TIM2_IRQHandler
** 输入参数:无
** 输出参数:无 单双八拍工作方式:A-AB-B-BC-C-CD-D-DA
** 功能描述:用于电机驱动控制,每1ms进一次中断,2ms一个周期。步进电机正转一圈之后反转一圈;
************************************************************************************************/
unsigned char un8ModeCont = 0;
unsigned int un16Count = 0;
unsigned char G_un8Mode_** = 1; //等于1正转 等于5反转 0停止驱动
void TIM2_IRQHandler(void) //TIM2中断
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
un8ModeCont++;
if(G_un8Mode_** == 1)
{
if(un8ModeCont == 1)//脉冲A
{
MOTOR1_ON;
}
else if(un8ModeCont == 2)
{
MOTOR1_OFF;
}
else if(un8ModeCont == 3)//脉冲AB
{
MOTOR1_ON;MOTOR2_ON;
}
else if(un8ModeCont == 4)
{
MOTOR1_OFF;MOTOR2_OFF;
}
else if(un8ModeCont == 5)//脉冲B
{
MOTOR2_ON;
}
else if(un8ModeCont == 6)
{
MOTOR2_OFF;
}
else if(un8ModeCont == 7)//脉冲BC
{
MOTOR2_ON;MOTOR3_ON;
}
else if(un8ModeCont == 8)
{
MOTOR2_OFF;MOTOR3_OFF;
}
else if(un8ModeCont == 9)//脉冲C
{
MOTOR3_ON;
}
else if(un8ModeCont == 10)
{
MOTOR3_OFF;
}
else if(un8ModeCont == 11)//脉冲CD
{
MOTOR3_ON;MOTOR4_ON;
}
else if(un8ModeCont == 12)
{
MOTOR3_OFF;MOTOR4_OFF;
}
else if(un8ModeCont == 13)//脉冲D
{
MOTOR4_ON;
}
else if(un8ModeCont == 14)
{
MOTOR4_OFF;
}
else if(un8ModeCont == 15)//脉冲DA
{
MOTOR4_ON;MOTOR1_ON;
}
else if(un8ModeCont >= 16)
{
un16Count++;
un8ModeCont = 0;
MOTOR4_OFF;MOTOR1_OFF;
}
if(un16Count >= 512)
{
G_un8Mode_** = 5;
un16Count = 0;
//TIM_Cmd(TIM2, DISABLE);
}
}
else
{
if(un8ModeCont == 1)//脉冲DA
{
MOTOR4_ON;MOTOR1_ON;
}
else if(un8ModeCont == 2)
{
MOTOR4_OFF;MOTOR1_OFF;
}
else if(un8ModeCont == 3)//脉冲D
{
MOTOR4_ON;
}
else if(un8ModeCont == 4)
{
MOTOR4_OFF;
}
else if(un8ModeCont == 5)//脉冲CD
{
MOTOR3_ON;MOTOR4_ON;
}
else if(un8ModeCont == 6)
{
MOTOR3_OFF;MOTOR4_OFF;
}
else if(un8ModeCont == 7)//脉冲C
{
MOTOR3_ON;
}
else if(un8ModeCont == 8)
{
MOTOR3_OFF;
}
else if(un8ModeCont == 9)//脉冲BC
{
MOTOR2_ON;MOTOR3_ON;
}
else if(un8ModeCont == 10)
{
MOTOR2_OFF;MOTOR3_OFF;
}
else if(un8ModeCont == 11)//脉冲B
{
MOTOR2_ON;
}
else if(un8ModeCont == 12)
{
MOTOR2_OFF;
}
else if(un8ModeCont == 13)//脉冲AB
{
MOTOR1_ON;MOTOR2_ON;
}
else if(un8ModeCont == 14)
{
MOTOR1_OFF;MOTOR2_OFF;
}
else if(un8ModeCont == 15)//脉冲A
{
MOTOR1_ON;
}
else if(un8ModeCont >= 16)
{
un16Count++;
un8ModeCont = 0;
MOTOR1_OFF;
}
if(un16Count >= 512)
{
G_un8Mode_** = 1; //停止驱动
un16Count = 0;
// TIM_Cmd(TIM2, DISABLE);
}
}
}
}
#define MOTOR1_ON GPIO_ResetBits(GPIOA, GPIO_Pin_1)//步进电机A
#define MOTOR1_OFF GPIO_SetBits(GPIOA, GPIO_Pin_1) //步进电机A
#define MOTOR2_ON GPIO_ResetBits(GPIOA, GPIO_Pin_2)//步进电机B
#define MOTOR2_OFF GPIO_SetBits(GPIOA, GPIO_Pin_2) //步进电机B
#define MOTOR3_ON GPIO_ResetBits(GPIOA, GPIO_Pin_3)//步进电机C
#define MOTOR3_OFF GPIO_SetBits(GPIOA, GPIO_Pin_3) //步进电机C
#define MOTOR4_ON GPIO_ResetBits(GPIOA, GPIO_Pin_4)//步进电机D
#define MOTOR4_OFF GPIO_SetBits(GPIOA, GPIO_Pin_4) //步进电机D
int main(void)
{
/* System Clocks Configuration */
delay_init(72); //延时初始化函数
RCC_Configuration();
ALL_GPIO_Config();
// USART_Configuration1();
MOTOR1_OFF;
MOTOR2_OFF;
MOTOR3_OFF;
MOTOR4_OFF;
TIM_InitConfigFunc();
NVIC_Configuration();
while(1)
{
;
}
}
单片机+ULN2003和电机连接示意图:
图1.系统连接图
图2.ULN2003接线示意图
图3.单片机连线示意图