实现STM32与直流无刷电机的正反转

原理

通俗来讲就是通过电生磁,通电导线绕在磁体上,相邻磁体缠绕方式不同,就会产生不同的极。通过同性相斥,异性相吸的原理,使得电机能转动。直流无刷电机原理这方面有很多文章讲解,如果对这方面了解不够清楚,可以在很多文章中找到。

程序编写

实现电机转动,必须知道相位,常见的三相电机为三相六状态。 相位如下: 我用两种方法实现, 第一种,放在while循环里面,注意两点就行,一个是相位信号(上图所示),另一个是顺序;代码如下

//霍尔传感器
#define HALL_U PBin(13)
#define HALL_V PBin(14)
#define HALL_W PBin(15)

//电机驱动IR2104
#define U_IN PAout(3)
#define U_SD PAout(5)
#define V_IN PAout(2)
#define V_SD PAout(4)
#define W_IN PAout(1)
#define W_SD PCout(14)
//PWM
#define PWM PAout(7)


void panduan(void)
{
          
   
	if(turn_flag==0)  //正转
	{
          
   
	if(HALL_U==1&&HALL_V==0&&HALL_W==0)
	{
          
   
		U_SD=1;TIM_SetCompare4(TIM2,PWM_TIME);

		V_SD=0;V_IN=0;

		W_SD=1;TIM_SetCompare2(TIM2,0);
	}
	if(HALL_U==1&&HALL_V==1&&HALL_W==0)
	{
          
   
		U_SD=0;U_IN=0;

		V_SD=1;TIM_SetCompare3(TIM2,PWM_TIME);

		W_SD=1;TIM_SetCompare2(TIM2,0);		
	}
	if(HALL_U==0&&HALL_V==1&&HALL_W==0)
	{
          
   
		U_SD=1;TIM_SetCompare4(TIM2,0);
		
		V_SD=1;TIM_SetCompare3(TIM2,PWM_TIME);
		
		W_SD=0;W_IN=0;
	}
	if(HALL_U==0&&HALL_V==1&&HALL_W==1)
	{
          
   
		U_SD=1;TIM_SetCompare4(TIM2,0);
		
		V_SD=0;V_IN=0;
		
		W_SD=1;TIM_SetCompare2(TIM2,PWM_TIME);
	}
	if(HALL_U==0&&HALL_V==0&&HALL_W==1)
	{
          
   
		U_SD=0;U_IN=0;
	
		V_SD=1;TIM_SetCompare3(TIM2,0);
	
		W_SD=1;TIM_SetCompare2(TIM2,PWM_TIME);
	}
			
	if(HALL_U==1&&HALL_V==0&&HALL_W==1)
	{
          
   
		U_SD=1;TIM_SetCompare4(TIM2,PWM_TIME);
		
		V_SD=1;TIM_SetCompare3(TIM2,0);
		
		W_SD=0;W_IN=0;
	}
}
	else                                       //反转
	{
          
   
		if(HALL_U==1&&HALL_V==0&&HALL_W==0)
	{
          
   
		U_SD=1;TIM_SetCompare4(TIM2,0);
		
		V_SD=0;V_IN=0;
		
		W_SD=1;TIM_SetCompare2(TIM2,PWM_TIME);
	}
	if(HALL_U==1&&HALL_V==1&&HALL_W==0)
	{
          
   
		U_SD=0;U_IN=0;
	
		V_SD=1;TIM_SetCompare3(TIM2,0);
	
		W_SD=1;TIM_SetCompare2(TIM2,PWM_TIME);	
	}
	if(HALL_U==0&&HALL_V==1&&HALL_W==0)
	{
          
   
		U_SD=1;TIM_SetCompare4(TIM2,PWM_TIME);
		
		V_SD=1;TIM_SetCompare3(TIM2,0);
		
		W_SD=0;W_IN=0;
	}
	if(HALL_U==0&&HALL_V==1&&HALL_W==1)
	{
          
   
		U_SD=1;TIM_SetCompare4(TIM2,PWM_TIME);

		V_SD=0;V_IN=0;

		W_SD=1;TIM_SetCompare2(TIM2,0);
	}
	if(HALL_U==0&&HALL_V==0&&HALL_W==1)
	{
          
   
		U_SD=0;U_IN=0;

		V_SD=1;TIM_SetCompare3(TIM2,PWM_TIME);

		W_SD=1;TIM_SetCompare2(TIM2,0);	
	}
			
	if(HALL_U==1&&HALL_V==0&&HALL_W==1)
	{
          
   
		U_SD=1;TIM_SetCompare4(TIM2,0);
		
		V_SD=1;TIM_SetCompare3(TIM2,PWM_TIME);
		
		W_SD=0;W_IN=0;
	}
	}
}
int main(void)
{
          
   
	LED_Init();
	MOTOR_Init();
	//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
//	EXTIX_Init();
	TIM3_Int_Init(10-1,72-1);  //72000000/72/10
PWM=1;
	while(1)
	{
          
   
		panduan();
	}
}

第二种是把上面代码放到外部中断里面,代码如下

//外部中断15-5服务程序
void EXTI15_10_IRQHandler(void)
{
          
   
	//delay_ms(10);//消抖
	if(EXTI_GetFlagStatus(EXTI_Line13))
	{
          
   
		panduan();
		EXTI_ClearITPendingBit(EXTI_Line13);  //清除LINE13上的中断标志位  
	}
	if(EXTI_GetFlagStatus(EXTI_Line14))
	{
          
   
		panduan();
		EXTI_ClearITPendingBit(EXTI_Line14);  //清除LINE14上的中断标志位  
	}
	if(EXTI_GetFlagStatus(EXTI_Line15))
	{
          
   
		panduan();
		EXTI_ClearITPendingBit(EXTI_Line15);  //清除LINE15上的中断标志位  
	} 
}

综上,中断比较快,速度慢的时候体现不出来,速度一旦快起来就很明显了

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