步进电机应用场景:打印机、智能打印机、机器人…
直流电机上电就开始工作,固定朝着一个方向转动,转动的频率与电流和负载有关,电流越大负载越小,则转动速度越快。应用于不需要精密控制的地方,例如电风扇等。
COM端是其他4端的公共端,只要给COM端一个高电平(类似共阳接口),其余端给一个低电平即可导通产生磁性吸引永磁铁。
当A+导通,其余断开时,永磁铁转向A+。
当B+通电,A+断开,永磁铁转向B+。
A-,B-同理。
精度:每一次的转向角为90度。
当A+导通,其余断开时,永磁铁转向A+。
当A+通电,B+也通电,其余断开时,永磁铁转向A+与B+之间。
精度:每一次的转向角为45度。
步进电机通过P27端子连接在ULN2003上,因为单片机无法输出较大的电流来驱动步进电机,因此使用ULN2003驱动电路来输出大电流驱动电机。ULN2003在上一节讲过,有电平翻转的作用,因此要输出高电平(经ULN2003后输出低电平)才能使线圈导通产生磁性。
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "touch_key.h"
#include "relay.h"
#include "step_motor.h"
int main (void)
{
RCC_Configuration(); //系统时钟初始化
TOUCH_KEY_Init();//触摸按键初始化
STEP_MOTOR_Init();//步进电机初始化
while(1)
{
if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_A))STEP_MOTOR_LOOP(0,1,3); // 按圈数右转
else if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_B))STEP_MOTOR_LOOP(1,1,3); //按圈数左转
else if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_C))STEP_MOTOR_NUM(0,100,3); //按步数右转
else if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_D))STEP_MOTOR_NUM(1,100,3); //按步数左转
else STEP_MOTOR_OFF();//当没有按键时步进电机断电
}
}
#include "step_motor.h"
u8 STEP;
//接口初始化
void STEP_MOTOR_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE, ENABLE); //APB2外设GPIO时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//启动AFIO重映射功能时钟
GPIO_InitStructure.GPIO_Pin = STEP_MOTOR_A | STEP_MOTOR_B | STEP_MOTOR_C | STEP_MOTOR_D; //选择端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)
GPIO_Init(STEP_MOTOR_PORT, &GPIO_InitStructure);
//必须将禁用JTAG功能才能做GPIO使用
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);// 改变指定管脚的映射,完全禁用JTAG+SW-DP
STEP_MOTOR_OFF(); //初始状态是断电状态
}
//电机断电
void STEP_MOTOR_OFF (void)
{
GPIO_ResetBits(STEP_MOTOR_PORT,STEP_MOTOR_A | STEP_MOTOR_B | STEP_MOTOR_C | STEP_MOTOR_D);//各接口置0
}
//电机单步8拍。测试得4076拍为旋转一周360度,即一拍旋转360/4076度。
void STEP_MOTOR_8A (u8 a,u16 speed)
{
switch (a)
{
case 0:
GPIO_ResetBits(STEP_MOTOR_PORT,STEP_MOTOR_B | STEP_MOTOR_C | STEP_MOTOR_D);//0
GPIO_SetBits(STEP_MOTOR_PORT,STEP_MOTOR_A);//1
break;
case 1:
GPIO_ResetBits(STEP_MOTOR_PORT,STEP_MOTOR_C | STEP_MOTOR_D);//0
GPIO_SetBits(STEP_MOTOR_PORT,STEP_MOTOR_A | STEP_MOTOR_B);//1
break;
case 2:
GPIO_ResetBits(STEP_MOTOR_PORT,STEP_MOTOR_A | STEP_MOTOR_C | STEP_MOTOR_D);//0
GPIO_SetBits(STEP_MOTOR_PORT,STEP_MOTOR_B);//1
break;
case 3:
GPIO_ResetBits(STEP_MOTOR_PORT,STEP_MOTOR_A | STEP_MOTOR_D);//0
GPIO_SetBits(STEP_MOTOR_PORT,STEP_MOTOR_B | STEP_MOTOR_C);//1
break;
case 4:
GPIO_ResetBits(STEP_MOTOR_PORT,STEP_MOTOR_A | STEP_MOTOR_B | STEP_MOTOR_D);//0
GPIO_SetBits(STEP_MOTOR_PORT,STEP_MOTOR_C);//1
break;
case 5:
GPIO_ResetBits(STEP_MOTOR_PORT,STEP_MOTOR_A | STEP_MOTOR_B);//0
GPIO_SetBits(STEP_MOTOR_PORT,STEP_MOTOR_C | STEP_MOTOR_D);//1
break;
case 6:
GPIO_ResetBits(STEP_MOTOR_PORT,STEP_MOTOR_A | STEP_MOTOR_B | STEP_MOTOR_C);//0
GPIO_SetBits(STEP_MOTOR_PORT,STEP_MOTOR_D);//1
break;
case 7:
GPIO_ResetBits(STEP_MOTOR_PORT,STEP_MOTOR_B | STEP_MOTOR_C);//0
GPIO_SetBits(STEP_MOTOR_PORT,STEP_MOTOR_A | STEP_MOTOR_D);//1
break;
default:
break;
}
delay_ms(speed); //延时
STEP_MOTOR_OFF(); //进入断电状态,防电机过热
}
//电机按步数运行。RL:方向,num:拍数,speed:速度
void STEP_MOTOR_NUM (u8 RL,u16 num,u8 speed)
{
u16 i;
for(i=0;i<num;i++){
if(RL==1){ //当RL=1右转,RL=0左转
STEP++;
if(STEP>7)STEP=0;
}else{
if(STEP==0)STEP=8;
STEP--;
}
STEP_MOTOR_8A(STEP,speed);
}
}
//电机按圈数运行。一圈是4076拍,一拍旋转360/4076度
void STEP_MOTOR_LOOP (u8 RL,u8 LOOP,u8 speed)
{
STEP_MOTOR_NUM(RL,LOOP*4076,speed);
}
步进电机可以按拍数或者角度做精确控制,但是要注意驱动电路的稳定,如果驱动电路不稳定,则会出现步进电机丢步的现象,长时间会产生较大误差。