前言:
stm32如何去控制无感无刷电机?
首先我们先要知道无刷电机的工作原理是什么,这样我们才能针对实际需求,对stm32 进行点对点的内部资源的调用,从而进行程序编写。
我相信能搜到这个Blog的同学都对无刷电机有一个大概的了解,但是具体的使用细节和原理,可能不太清楚。
在这里给大家讲解一下写程序时几个关键的点,在清楚了无刷电机控制的同时,也就明白了程序该如何写。
硬件使用的是KY_Motor的开发板。
链接:KY_Motor开发板

无刷电机控制的比较重要的地方就是换向,而无感无刷最重要的知识点就是零点检测。
1、电机换向和零点检测。
零点检测电路

//PA5 引脚中断,计算换相时刻 void EXTI9_5_IRQHandler(void) { Zero=GPIO_ReadInputData(GPIOA); Zero=Zero&0x0038; Zero=Zero>>3;//过零点信号, 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位,就能得出过零点信号 ,将也相应的换算成二进制数,就明白如何获取到过零点信号的值了。
在程序中我们分别对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位单片机上做一个航模无刷电调,今年会陆续把剩下的工作都做完,
感谢大家收看,关注我,定期更新无刷电机干货。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/177743.html原文链接:https://javaforall.net
