实现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上的中断标志位
}
}
综上,中断比较快,速度慢的时候体现不出来,速度一旦快起来就很明显了
