前言:
stm32如何去控制无感无刷电机?
首先我们先要知道无刷电机的工作原理是什么,这样我们才能针对实际需求,对stm32 进行点对点的内部资源的调用,从而进行程序编写。
我相信能搜到这个Blog的同学都对无刷电机有一个大概的了解,但是具体的使用细节和原理,可能不太清楚。
在这里给大家讲解一下写程序时几个关键的点,在清楚了无刷电机控制的同时,也就明白了程序该如何写。
硬件使用的是KY_Motor的开发板。
链接:KY_Motor开发板
无刷电机控制的比较重要的地方就是换向,而无感无刷最重要的知识点就是零点检测。
1、电机换向和零点检测。
无感无刷电机控制的主要内容就是检测悬浮相的感生电动势的过零点,当模拟比较器发 生中断时说明过零事件产生,然后准备换相。 由于stm32f103系列没有自带的比较器,因此外围电路采用了LM358作为比较器,零点检测除了使用比较器也可以使用中断的方式实现,感兴趣的小伙伴可以尝试改一下。零点检测电路
//PA5 引脚中断,计算换相时刻
void EXTI9_5_IRQHandler(void)
{
Zero=GPIO_ReadInputData(GPIOA);
Zero=Zero&0x0038;
Zero=Zero>>3;//过零点信号,513264
if(!Direction)Zero=7-Zero;
Zero_SW();
counter1++;
if(EXTI_GetITStatus(EXTI_Line5)!= RESET)
{
EXTI_ClearITPendingBit(EXTI_Line5);
}
}
在这里通过检测U、V、W三相哪一路导通,进而通过比较器来判断哪一路导通。
在这里解释一下zero = zero & 0x0038 是什么意思,在硬件上我们采用了 PA3、PA4、PA5三个引脚作为零点检测引脚,0x0038的二进制为 xx 0011 1000,就是说 PA3、PA4、PA5与 111相与,进而得出哪一路导通的值。
再将zero的值右移3位,就能得出过零点信号 513264,将513264也相应的换算成二进制数,就明白如何获取到过零点信号的值了。
在程序中我们分别对PA3、PA4、PA5三个引脚进行了中断处理,程序都一样,只是中短线不一样,大家自行改一下程序。
我们在取得过零点信号后需要对取到的信号用于电机换相,也就是下面这个经典的六臂全桥驱动电路。
取其中两路导通,实现方法我们通过如下方法进行实现。
//过零点换相函数
void Zero_SW(void)
{
switch(Zero)
{
case 5:
TIM1->CCR2=0; //AB
TIM1->CCR1 = My_PWM;
TIM1->CCR3=0;
GPIO_ResetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_15);
GPIO_SetBits(GPIOB, GPIO_Pin_14);
break;
case 1:
TIM1->CCR2=0; //AC
TIM1->CCR1 = My_PWM;
TIM1->CCR3=0;
GPIO_ResetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_14);
GPIO_SetBits(GPIOB, GPIO_Pin_15);
break;
case 3:
TIM1->CCR1=0; //BC
TIM1->CCR2 = My_PWM;
TIM1->CCR3=0;
GPIO_ResetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_14);
GPIO_SetBits(GPIOB, GPIO_Pin_15);
break;
case 2:
TIM1->CCR1=0; //BA
TIM1->CCR2 = My_PWM;
TIM1->CCR3=0;
GPIO_ResetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15);
GPIO_SetBits(GPIOB, GPIO_Pin_13);
break;
case 6:
TIM1->CCR2=0;//CA
TIM1->CCR3 = My_PWM;
TIM1->CCR1=0;
GPIO_ResetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15);
GPIO_SetBits(GPIOB, GPIO_Pin_13);
break;
case 4:
TIM1->CCR2=0; //CB
TIM1->CCR3 = My_PWM;
TIM1->CCR1=0;
GPIO_ResetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_15);
GPIO_SetBits(GPIOB, GPIO_Pin_14);
break;
default:
break;
}
}
这段程序很好理解,就不做过多解释。
========================================================================
到这,无感无刷电机驱动的比较重要的两部分程序就讲解完了。我们接下来看一下启动函数。
//启动函数
void START_UP(void)
{
switch(phase)
{
case 1:
TIM1->CCR2=0; //AB
TIM1->CCR1 = My_PWM;
TIM1->CCR3=0;
GPIO_ResetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_15);
GPIO_SetBits(GPIOB, GPIO_Pin_14);
break;
case 2:
TIM1->CCR2=0; //AC
TIM1->CCR1 = My_PWM;
TIM1->CCR3=0;
GPIO_ResetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_14);
GPIO_SetBits(GPIOB, GPIO_Pin_15);
break;
case 3:
TIM1->CCR1=0; //BC
TIM1->CCR2 = My_PWM;
TIM1->CCR3=0;
GPIO_ResetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_14);
GPIO_SetBits(GPIOB, GPIO_Pin_15);
break;
case 4:
TIM1->CCR1=0; //BA
TIM1->CCR2 = My_PWM;
TIM1->CCR3=0;
GPIO_ResetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15);
GPIO_SetBits(GPIOB, GPIO_Pin_13);
break;
case 5:
TIM1->CCR2=0;//CA
TIM1->CCR3 = My_PWM;
TIM1->CCR1=0;
GPIO_ResetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15);
GPIO_SetBits(GPIOB, GPIO_Pin_13);
break;
case 6:
TIM1->CCR2=0; //CB
TIM1->CCR3 = My_PWM;
TIM1->CCR1=0;
GPIO_ResetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_15);
GPIO_SetBits(GPIOB, GPIO_Pin_14);
break;
default:
break;
}
}
细心的同学会发现,启动函数和零点换相函数一样。
因为电机在启动的时候程序无法判断哪一个点在零点,因此需要先让电机导通,当导通后,便会产生反向电动势,也就可以采集到零点信号,因此知道哪一路导通。
在程序中加的用户接口程序就不在这罗列了,这个程序通过按键控制电机启动,分别对应加速和减速按键,对电机速度进行控制。下面视频测试了航模无刷电机12v、1400KV。程序花了点事件优化,无感无刷的电机启动的很流畅。
stm32无刷电机驱动器_按键调速
网上有些例程代码只能适配一种电机,换一个新电机便不能流畅的转动了,因此我把手头的电机都试了一遍,目前我手里的这些电机都可以流畅的启动,以前总玩航模,手头的电机也大都是航模用的电机。
启动算法优化优化的比较理想,可以移植到国产的32位单片机上做一个航模无刷电调,今年会陆续把剩下的工作都做完,
感谢大家收看,关注我,定期更新无刷电机干货。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)