STM32F1开发指南笔记26----步进电机

步进电机应用场景:打印机、智能打印机、机器人…

1、步进电机

STM32F1开发指南笔记26----步进电机_第1张图片

2、直流电机

直流电机上电就开始工作,固定朝着一个方向转动,转动的频率与电流和负载有关,电流越大负载越小,则转动速度越快。应用于不需要精密控制的地方,例如电风扇等。

3、五线四相步进电机内部原理

STM32F1开发指南笔记26----步进电机_第2张图片
COM端是其他4端的公共端,只要给COM端一个高电平(类似共阳接口),其余端给一个低电平即可导通产生磁性吸引永磁铁。

4、四拍,转动一次角度为90度

STM32F1开发指南笔记26----步进电机_第3张图片

当A+导通,其余断开时,永磁铁转向A+。
当B+通电,A+断开,永磁铁转向B+。
A-,B-同理。
精度:每一次的转向角为90度。

5、八拍,转动一次角度为45度

STM32F1开发指南笔记26----步进电机_第4张图片

当A+导通,其余断开时,永磁铁转向A+。
当A+通电,B+也通电,其余断开时,永磁铁转向A+与B+之间。
精度:每一次的转向角为45度。

6、步进电机电路等效图

STM32F1开发指南笔记26----步进电机_第5张图片

STM32F1开发指南笔记26----步进电机_第6张图片

7、使用注意事项

STM32F1开发指南笔记26----步进电机_第7张图片

8、原理图

STM32F1开发指南笔记26----步进电机_第8张图片
步进电机通过P27端子连接在ULN2003上,因为单片机无法输出较大的电流来驱动步进电机,因此使用ULN2003驱动电路来输出大电流驱动电机。ULN2003在上一节讲过,有电平翻转的作用,因此要输出高电平(经ULN2003后输出低电平)才能使线圈导通产生磁性。

9、程序设计

main函数

#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();//当没有按键时步进电机断电
	}
}

step_motor.c函数

#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); 
}

步进电机可以按拍数或者角度做精确控制,但是要注意驱动电路的稳定,如果驱动电路不稳定,则会出现步进电机丢步的现象,长时间会产生较大误差。

你可能感兴趣的:(STM32,单片机,stm32,嵌入式,程序设计,人工智能)