前言
有幸被选中参与评估板的测试和学习,也是初次接触直流无刷电机的编程,有很多知识点需要补充和学习,比如BLDC的工作原理和控制方式。
参加过几次论坛,国内厂商推出了很多集成电机驱动电路的MCU,APM32F035是极海科技针对电机驱动市场,推出的高性能、高性价比电机专用APM32F035系列 MCU,该系列型号基于Arm® Cortex®-M0+内核,主频可达72MHz,内置 Vector Computer(MDU+CORDIC)多种专用数学运算加速器,集成高速 ADC、运放、比较器、及 CAN 控制器等外设资源,搭配电机控制通用开发平台,有效提升电机控制性能,降低产品运行成本。
极海官网链接:电机控制专用APM32F035 (geehy.com) ,可在里面下载规格书、用户手册、SDK和相关开发文档。
APM32F035主要外设参数
电机算法软件平台
同时极海还提供了一系列电机算法平台,方便大家在产品中快速开发导入。
一、开发环境准备和搭建
1.1 准备无刷电机和对应的供电电源在某宝选了款带霍尔的无刷电机,型号B3040M-042,驱动电压12V,驱动空载电流0.28A,空载运行转速5600转,无其他电机参数,这点对后续电机调参很不利。电机图片如下:
然后就是电机电源的购买,考虑后续可能会用24V的电机,所以选了个3~24V电压可调的电源,图片如下:
1.2 了解开发板硬件配置
主要功能:
- 电气参数:12~72VDC 宽电压输入,最大功率 100W
- 支持电机类型:BLDC,PMSM
- 支持编码器类型:霍尔,光电,磁编码器
- 通讯接口:SCI,SPI,I2C,CAN
- 电流采样方式:单 / 双电阻采样,三相反电动势采样
开发板的硬件构成
- 12V Buck电路:采用的是TI的LM5164,将VM电机电压降压至12V,同时给3相栅极驱动芯片供电。
- 5V Buck电路:采用的是UTECH(德信)的EUP3458VIR1,同时给串口驱动芯片供电。
- 3.3V LDO电路:采用的是MaxLinear(迈凌)的SPX3819M5-L-3-3/TR,主要给主控APMF035供电。
- MCU:用的是极海科技APM32F035,Arm® Cortex®-M0+内核,主频可达72MHz,集成运放,定时器等,外设很丰富。
- USB-UART TLL转换电路:采用的是CH340G.
- LED灯:供电指示灯1个,状态指示灯1个(用于电机故障指示)。
- 轻触按键:MCU硬复位按键,前进/后退切换按键,锁车按键。
- 可调电阻:通过ADC采样控制电机转速。
- 电机驱动电路:栅极驱动器用的是峰岹的FD6288,并且开发板设计了三相功率MOS半桥电路,功率MOS用的HUASHUO(华朔)的HSU0048。
1.3 软件开发环境配置
基本准备
1)开发环境可用Eclipse、IAR和Keil MDK,因为笔者习惯了Keil,所以用的Keil平台。
2)极海F035开发包支持安装,需要安装Geehy.APM32F035_DFP.1.0.0.pack,下载链接:https://www.geehy.com/uploads/tool/Geehy.APM32F035_DFP.1.0.0.pack
3)需要准备一个调试工具,APM32F035支持JLINK和STLINK,这个可以根据需要自行配置。
4) 电机驱动例程:可在官网下载或者找对应的极海FAE提供。
开发界面
笔者用的无感BLDC例程,因为是菜鸟,只想先让电机转起来。
相关代码
- /*!
- * @file main.c
- *
- * @brief Main program body
- *
- * @version V1.0.0
- *
- * @date 2022-09-30
- *
- * @attention
- *
- * Copyright (C) 2022 Geehy Semiconductor
- *
- * You may not use this file except in compliance with the
- * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
- *
- * The program is only for reference, which is distributed in the hope
- * that it will be usefull and instructional for customers to develop
- * their software. Unless required by applicable law or agreed to in
- * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
- * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
- * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
- * and limitations under the License.
- */
- /* Includes */
- #include "main.h"
- #include "dev_include.h"
- #include <stdio.h>
- #include <string.h>
- #include "m0cp.h"
- #include "hardware.h"
- #include "systick.h"
- #include "user_function.h"
- #include "StateMachine.h"
- #include "BLDC_SensorLess.h"
- TIMFlagType TIMFlag;
- Motor_TypeDef Motor_1st;
- int16_t M1FaultID, M1FaultID_Record;
- stc_motor_ramp_cal_t Motor_stcRampCal;
- uint8_t bNewDIRKey;
- uint8_t bOldDIRKey;
- uint8_t bBrakeKey = 0;
- uint8_t bSwitchFlag = 0;
- /*******************************************************************************
- * Function Name : Interrupt_Init
- * Description : Interrupt priority initialization
- *
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void Interrupt_Init(void)
- {
- /* Configure one bit for preemption priority */
- SCB->AIRCR = (u32)0x05FA0500;
- /* Enable the ADC Interrupt */
- NVIC_EnableIRQ(ADC_COMP_IRQn);
- NVIC_SetPriority(ADC_COMP_IRQn,0);
- NVIC_EnableIRQ(TMR1_BRK_UP_TRG_COM_IRQn);
- NVIC_SetPriority(TMR1_BRK_UP_TRG_COM_IRQn,1);
- NVIC_EnableIRQ(SysTick_IRQn);
- NVIC_SetPriority(SysTick_IRQn,2);
- // ADC->STS &= ~(u32)(0x070C); //ADC_FLAG_EOC
- TMR1->STS &= (u16)0xFFFE;
- TMR1->STS &= (u16)0xFF7F;
- }
- /*!
- * @brief Main program
- *
- * @param None
- *
- * @retval None
- *
- */
- int main(void)
- {
- __disable_irq();
- Systick_Init(SystemCoreClock / 1000);
- /* Initialize motor control parameters */
- Init_Parameter(&Motor_1st);
- Board_Init();
- //Initial direction determination
- bNewDIRKey = GPIO_ReadInputBit(GPIOC,GPIO_PIN_13);
- bOldDIRKey = bNewDIRKey;
- Motor_1st.BLDC.u8Direction = bNewDIRKey;
- /* Initialize interrupts */
- Interrupt_Init();
- __enable_irq(); //Enable all interrupts
- /*Ö÷Ñ»· */
- while (1)
- {
- //Get key value status in real time
- bNewDIRKey = GPIO_ReadInputBit(GPIOC,GPIO_PIN_13); //PC13 Direction·½Ïò°´¼ü
- bBrakeKey = GPIO_ReadInputBit(GPIOC,GPIO_PIN_14); //PC14 LOCKËø³µ°´¼ü
- if(bBrakeKey == 0)
- {
- eM1_RunSubState = RunState_Brake;
- variable_reset(&Motor_1st);
- }
- if(bOldDIRKey != bNewDIRKey)
- {
- bSwitchFlag = 1;
- }
- bOldDIRKey = bNewDIRKey;
-
- //ÂýËÙ»·Ö´Ðж¯×÷ÈçÏ£º
- if(Motor_1st.USER.bSlowLoopFlag)
- {
- if(bSwitchFlag == 1)
- {
- //¼Ç¼µ±Ç°µÄÐýÅ¥¹éÒ»»¯ºóµÄÊý¾Ý£¬Í¬Ê±½øÐнµËÙ
- Motor_1st.USER.RP.Out --;
- //ËٶȽµËÙµ½0ºó¿ªÆô»»Ïà
- if(0 == Motor_1st.USER.RP.Out)
- {
- Motor_1st.BLDC.u8Direction = bNewDIRKey;
- bSwitchFlag = 0;
- }
- }else
- {
- //Ìí¼ÓÂýËÙ»·µÄËٶȿØÖÆÒÔ¼°ramp´¦Àíº¯ÊýµÈ
- CalcNormalization((Motor_1st.USER.s16VspCmd>>3),&Motor_1st.USER.RP);
- }
- /* Slow Loop Statemachine */
- s_STATE[eM1_MainState]();
- Motor_1st.USER.bSlowLoopFlag = 0;
- }
- }
- }
- /******************* Copyright (C) 2022 Geehy Semiconductor ****/
二、测试例程及电机参数修改
因为笔者对无刷电机所知不多,只是简单根据电机参数修改了parameter.h中的配置,具体代码如下:
- #ifndef __PARAMETER_H_
- #define __PARAMETER_H_
- typedef signed short Q15_t;
- typedef signed long Q31_t;
- #if !defined(Q15)
- #define Q15(x) ((Q15_t)((x) < 0.999969482421875 ? ((x) >= -1 ? (x)*0x8000 : 0x8000) : 0x7FFF))
- #endif //Q15
- #if !defined(Q31)
- #define Q31(x) ((Q31_t)((x) < 1 ? ((x) >= -1 ? (x)*0x80000000 : 0x80000000) : 0x7FFFFFFF))
- #endif //Q31
- //#define SingleShunt
- /*System setting*/
- #define SYS_REFV 3.3f // unit:v MCU VCC must be 5.0V or 3.3V
- #define ADC_REFV SYS_REFV
- #define SYSCLK_HSE_72MHz 72000000 // unit:Hz
- #define SYSCLK_HSE_MHz 72 // unit:MHz
- #define PWMFREQ 8000 // unit:Hz
- #define DEAD_TIME 1.0f // unit:us determined by Hardware parameter
- #define SLOWLOOP_FREQ 1000 // unit:Hz
- #define PWMFREQ_KHZ 8 // unit:KHz
- #define POLEPAIRS 2 //unit
- #define SPEEDX 60*PWMFREQ/POLEPAIRS
- #define SPEEDX_UNIPHASE SPEEDX / 6
- // Voltage Sampling
- #define UDC_MAX (69.0f) // unit:V Max DC Voltage of Hardware
- #define U_MAX (UDC_MAX/4.0f) // (UDC_MAX/1.732f) // unit:V Max Voltage
- #define DCBUS_OVER (15.0f) // unit:V if DC Bus voltage over this, it will stop motor
- #define DCBUS_UNDER (8.0f) // unit:V if DC Bus voltage under this, it will stop motor
- #define DCBUS_SWITCH (11.5f) // unit:V
- #define R_SHUNT (0.02f) // unit:ohm
- #define CURRENT_OPA_GAIN (5.00f) // unit:ohm
- #define I_MAX (ADC_REFV/2/CURRENT_OPA_GAIN/R_SHUNT) // 16.5A unit:A Max current of Hardware
- #define IBUS_OVER (13.5f) // unit:A
- #define IBUS_OVER_CMD Q15((IBUS_OVER * R_SHUNT *CURRENT_OPA_GAIN + ADC_REFV/2)/ADC_REFV)
- // run state
- #define RAMP_UP 1000.0f // RPM/s ramp of speed command increase
- #define RAMP_DOWN 1000.0f // RPM/s ramp of speed command decrease
- // freewheel state
- #define FREEWHEEL_TIME 5.0f // unit:s freewheel time
- #define FAULTRELEASE_TIME 5.0f // unit:s fault release time
- #define SPEED_MAX (5000.0f) // unit:rpm max speed of motor
- //BLDC parameter
- // Align state
- #define ALIGN_PWMVALUE 460
- #define ALIGN_TIME (0.1f*SLOWLOOP_FREQ) // unit:s align time :0.1s
- #define STARTUP_TIME (1.0f*SLOWLOOP_FREQ) //unit:s 1.0s
- #define STARTUP_PWMVALUE1 460 // 6.6% duty
- #define STARTUP_PWMVALUE2 600 // 10% duty 600
- #define OPENLOOP_TIME 18 // 18*1ms
- #define FORCED_COMMUTATION_TIME 18 // 18*125us //18*62.5us
- #define ECW 1 // forward
- #define ECCW 0 // reverse
- #define MIN_DUTY 100 // Minimum PWM output
- #define MAX_DUTY 9000 // Maximum PWM output
- #define FREEWHEELING_TIME 10000 // Motor free-wheel reference time
- #define THIRTYDEGREE_TIME 10000 // 30 degree Electrical cycle
- #define PERIODNUMBER_MAX 100 // Electrical Period Cnt
- #define CARRIER_FREQUENCY 8 // unit: Hz
- #define STARTUPSPEED_RPM 300 // unit: rpm
- #define VSP_MAX (3.3f) // unit: V
- #define START_VSP Q15(0.5f/VSP_MAX)>>2
- #define STOP_VSP Q15(0.3f/VSP_MAX)>>2
- /* SPEED LOOP PI PARAMETER */
- #define M1_SPEED_KP_Q15 (0) // Q15 format KP of speed loop
- #define M1_SPEED_KP_Q10 (2048) // Q10 format KP of speed loop
- #define M1_SPEED_KI_Q15 (0) // Q15 format KI of speed loop
- #define M1_SPEED_KI_Q10 (300) // Q10 format KI of speed loop
- #endif
三、调试样品展示
1、将电机三相线和霍尔线按照说明接上,当然使用无感控制时,霍尔相关线可先不接。
2、接上电机电源
3、整体图片如下
4、测试结果
功能都是跑通了,可实现调试,正反转控制和锁车操作,包括电压过压保护也是OK的。
本来想录个视频的,结果调试过程不知道哪里搞错了,把主电源3.3V弄短路了,最后排除是主控芯片短路,对地主控只有2R,得找极海申请样品更换了。
----1月24日更新----
感谢极海的高总,重新寄了样品给我,换上去后正常了,那就出个视频吧
四、总结
电机控制是个很重要的学科,涉及到电子、嵌入式和机械,想要精通任重而道远,只能继续保持学习,和实际项目应用结合,才能慢慢掌握电机。
既然跑通了,电机规格书也不全,索性把电机拆开看看它的五脏六腑吧。
电机外围是线圈,也就是定子,中间的永磁铁作为转子。
电机相位检测PCBA,有U、V、W三个焊点,用于焊接电机三相绕组;另外还有H1、H2和H3三个数字霍尔,用于电机转子的位置。
最后说下极海电机开发板的优缺点吧。
优点:
1)电路板简单明了,布局很清晰,有很多的测试点并标有丝印,可以很大地提高调试效率。
2)主控是基于M0内核,对很多从事消费电子开发的人来说,可以比较快捷的上手。
3)有提供各种电机控制的例程,工程师可以基于例程快速完成评估和导入。
缺点:
1)开发板使用说明不详细,比如例程对应的电机和电源参数都没提供。
2)例程中注释比较少,初学者无法将各个参数和电机一一匹配。
3)后续希望可以提供PC端的图形开发界面,降低开发成本,提高开发效率。
总之,这是个不错的开发板,特别是MCU集成了运放,工程师的降本压力又少一点了。
初次接触,具体的产品参数和性能大家可以直接咨询极海FAE哈,感谢大家!