基于STM32单片机的28BYJ-48步进电机驱动

基于STM32单片机的28BYJ-48步进电机驱动

一、ULN2003

这是ULN2003购买驱动板的电路图,IN1、IN2、IN3、IN4为输入端,分别和输出端的OUT1、OUT2、OUT3、OUT4一一对应。

二、单片机 所使用的单片机是STM32F103ZERCT6系列,使用单片机的PB12、PB13、PB14、PB15分别连接ULN2003输入引脚的IN1、IN2、IN3、IN4脚。 三、28BYJ-48步进电机 步进电机28BYJ48型四相八拍电机,电压为DC5V—DC12V。当对步进电机施加一系列连续不断的控制脉冲时,它可以连续不断地转动。每一个脉冲信 号对应步进电机的某一相或两相绕组的通电状态改变一次,也就对应转子转过一定的角度(一个步距角)。当通电状态的改变完成一个循环时,转子转过一个齿距。 四相步进电机有两种运行方式:①四相四拍、②四相八拍。 1、拍数:完成一个磁场周期性变化所需脉冲数或导电状态用n表示,或指电机转过一个齿距角所需脉冲数,以四相电机为例,有四相四拍运行方式即AB-BC-CD-DA-AB,四相八拍运行方式即 A-AB-B-BC-C-CD-D-DA-A。 2、步距角:对应一个脉冲信号,电机转子转过的角位移用θ表示。θ=360度/(转子齿数J运行拍数),以常规二、四相,转子齿为50齿电机为例。 四拍运行时步距角为θ=360度/(504)=1.8度(俗称整步) 八拍运行时步距角为θ=360度/(508)=0.9度(俗称半步) 3、拍数:完成一个磁场周期性变化所需脉冲数或导电状态用N表示,或者指电机转过一个齿距脚所需脉冲数。 四相四拍运行方式:AB-BC-CD-DA-AB 四相八拍运行方式A-AB-B-BC-C-CD-D-DA-A 例如:四相八拍方式下,每接收到一个脉冲信号,转过0.9度,如果每秒钟接收400个脉冲,转速为4000.9=360度/s。 驱动方式 导线颜色 1 2 3 4 5 6 7 8 5红 + + + + + + + + 4橙色 - - 3黄色 - - - 2粉色 - - - 1蓝色 - - -

u8 TIM3_count= 0;
void TIM3_IRQHandler(void)
{
          
   
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
	{
          
   
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
		if(TIM3_count>3)
		{
          
   
			TIM3_count=0;
		}
		if(TIM3_count==0)
		{
          
   
			GPIO_SetBits(GPIOB, GPIO_Pin_12);
   			GPIO_SetBits(GPIOB, GPIO_Pin_13);
   			GPIO_ResetBits(GPIOB, GPIO_Pin_14);
   			GPIO_ResetBits(GPIOB, GPIO_Pin_15);
		}
		else if(TIM3_count==1)
		{
          
   
			GPIO_ResetBits(GPIOB, GPIO_Pin_12);
   			GPIO_SetBits(GPIOB, GPIO_Pin_13);
   			GPIO_SetBits(GPIOB, GPIO_Pin_14);
   			GPIO_ResetBits(GPIOB, GPIO_Pin_15);
		}
		else if(TIM3_count==2)
		{
          
   
			GPIO_ResetBits(GPIOB, GPIO_Pin_12);
   			GPIO_ResetBits(GPIOB, GPIO_Pin_13);
   			GPIO_SetBits(GPIOB, GPIO_Pin_14);
   			GPIO_SetBits(GPIOB, GPIO_Pin_15);
		}
		else if(TIM3_count==3)
		{
          
   
			GPIO_SetBits(GPIOB, GPIO_Pin_12);
   			GPIO_ResetBits(GPIOB, GPIO_Pin_13);
   			GPIO_ResetBits(GPIOB, GPIO_Pin_14);
   			GPIO_SetBits(GPIOB, GPIO_Pin_15);
		}
		TIM3_count++;
	}
}

void TIM_Init(void)		
{
          
   
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 , ENABLE);
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1 ; 
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up ;
	TIM_TimeBaseInitStruct.TIM_Period = 200;  
	TIM_TimeBaseInitStruct.TIM_Prescaler = 719;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct ) ; 
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;    
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; 
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure);
	TIM_ITConfig(TIM3, TIM_IT_Update,ENABLE); 
	TIM_Cmd(TIM3, ENABLE);    
}

int main(void)
{
          
   
	TIM_Init();
	while(1);
}

注意:定时器的周期不能再减了,否则电机不转

经验分享 程序员 微信小程序 职场和发展