【零基础玩转BLDC系列】无刷直流电机无位置传感器三段式启动法详细介绍及代码分享
无刷直流电动机基本转动原理等内容请参考《基于霍尔传感器的无刷直流电机控制原理》、《基于反电动势过零检测法的无刷直流电机控制原理》与《以GD32F30x为例定时器相关功能详解》,BLDC基本原理及基础知识本篇不再赘述。
直流无刷电机由于定子绕组的反电动势与电机的转速成正比,所以电机在静止时反电动势为零或低速时反电动势很小,此时无法根据反电动势信号确定转子磁极的位置。因此,反电动势法需要采用特殊启动技术,从静止开始加速,直至转速足够大。通过反电势能检测到过零时,再切换至直流无刷电机运行状态。这个过程称为“三段式”启动,主要包括转子预定位、加速和运行状态切换三个阶段。这样既可以使电机转向可控,又可以保证电机达到一定转速后再进行切换,保证了启动的可靠性。
下面对“三段式”启动技术进行详细的分析。
1、电机转子预定位
若要保证直流无刷电机能够正常启动,首先要确定转子在静止时的位置。
在小型轻载条件下,对于具有梯形反电势波形的直流无刷电机来说,一般采用磁制动转子定位方式。系统启动时,任意给定一组触发脉冲,在气隙中形成一个幅值恒定、方向不变的磁通。只要保证其幅值足够大,那么这一磁通就能在一定时间内将电机转子强行定位在这个方向上。
在应用中,可以在任意一组绕组上通电一定时间,其中预定位的PWM占空比和预定位时间的长短设定值可由具体电机特性和负载决定,在实际应用中调试而得。通常为了保险起见,会定位两次相邻的位置,防止转子刚好处于临界位置。
在预定位成功后,转子在启动前可达到预定的位置,为电机启动做好准备。
void motor_lacation_cfg_1()
{//W+ U-/* channel0 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_DISABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_ENABLE);/* channel1 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0);timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_DISABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_DISABLE);/* channel2 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_ENABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_DISABLE);
}
void motor_lacation_cfg_2()
{//U+ V-/* channel0 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_ENABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_DISABLE);// /* channel1 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_DISABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_ENABLE);/* channel2 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0);timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_DISABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_DISABLE);
}
void motor_lacation_cfg_3()
{//W+ V-/* channel0 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0);timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_DISABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_DISABLE);/* channel1 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_DISABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_ENABLE);/* channel2 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_ENABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_DISABLE);
}
void motor_lacation_cfg_4()
{//V+ W-/* channel0 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0);timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_DISABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_DISABLE);/* channel1 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_ENABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_DISABLE); /* channel2 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_DISABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_ENABLE);
}
void motor_lacation_cfg_5()
{//V+ U-/* channel0 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_DISABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_ENABLE);/* channel1 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_ENABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_DISABLE);/* channel2 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0);timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_DISABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_DISABLE);
}
void motor_lacation_cfg_6()
{// U+ W-/* channel0 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_ENABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_DISABLE);/* channel1 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_DISABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_DISABLE);/* channel2 configuration */timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0); timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_DISABLE);timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_ENABLE);
}
void motor_step_stop()
{ timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0, 0); timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1, 0);timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2, 0);
}
void motor_locate()
{timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0, 1500); timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1, 1500);timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2, 1500); if(CCW==0){motor_lacation_cfg_4();timer_enable(TIMER0);delay_1ms(60);motor_lacation_cfg_6();timer_enable(TIMER0);delay_1ms(60);}else{//逆时针motor_lacation_cfg_3();timer_enable(TIMER0);delay_1ms(60);motor_lacation_cfg_2();timer_enable(TIMER0);delay_1ms(60);}motor_step_stop();timer_disable(TIMER0);
}
2、电机的外同步加速
确定了电机转子的初始位置后,由于此时定子绕组中的反电动势仍为零,所以须人为改变电机的外施电压和换相信号,使电机由静止逐步加速运动。这一过程称为外同步加速。对于不同的外施电压调整方法和换相信号调整方法,外同步加速可划分为三类:
①换相信号频率不变,逐步增大外施电压使电机加速,称为恒频升压法。
②保持外施电压不变,逐渐增高换相信号的频率,使电机逐步加速,称为恒压升频法。
③在逐步增大外施电压的同时,增高换相的频率,称为升频升压法。
各个方法都有其优点和缺点。如升频升压法是人为地给电机施加一个由低频到高频不断加速的他控同步切换信号,而且电压也在不断地增加。通过调整电机换相频率,即可调整电机启动的速度。调整方法比较简单。但是这个过程较难实现。切换信号的频率的选择要根据电机的极对数和其他参数来确定。太低,电机无法加速;太高,电机转速达不到,会有噪声甚至无法启动,算法比较困难。
无论哪种方法,该过程都是在未检测到反电动势信号时进行。因此对于控制系统来说此段电机控制是盲区。参数在调试好的时候,可以快速切换至正常运行状态;而参数不理想时,电流可能不稳甚至电机会抖动。因此,在应用中,应根据电机及负载特性设定合理的升速曲线,并在尽可能短的时间内完成切换。
void openloop_step_change(uint32_t pwm_duty,uint32_t counter)
{timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0, pwm_duty);timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1, pwm_duty);timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2, pwm_duty);if(CCW==0){//顺时针motor_lacation_cfg_2();delay_1us(counter);motor_lacation_cfg_3();delay_1us(counter);motor_lacation_cfg_1();delay_1us(counter);motor_lacation_cfg_5();delay_1us(counter);motor_lacation_cfg_4();delay_1us(counter);motor_lacation_cfg_6();delay_1us(counter);}else{//逆时针motor_lacation_cfg_6();delay_1us(counter);motor_lacation_cfg_4();delay_1us(counter);motor_lacation_cfg_5();delay_1us(counter);motor_lacation_cfg_1();delay_1us(counter);motor_lacation_cfg_3();delay_1us(counter);motor_lacation_cfg_2();delay_1us(counter);}}
void motor_openloop()
{int i=0;timer_enable(TIMER0);for(i=0;i<192;i++){openloop_step_change(1600,60000-300*i);}for(i=0;i<800;i++){openloop_step_change(1600,2700);}}
3、电机运行状态的转换
当电机通过外同步加速到一定的转速,反电势信号可以准确检测时,即可由外同步向自同步切换。可以通过试验观察反电势信号能够被准确检测的转速。在进行切换有两种方法:一种是测速模块可以测出电机的转速,当达到这一转速时即可进行切换;另一种,通过试验检测出达到预定切换转速的时间,通过软件定时器设置切换时间。
这一步是关键也是比较难实现的一步。有时软件或者硬件设计的不合理都可能导致启动失败。通常是采用估算的方式来选择切换速度。
void motor_sensorless_start()
{timer_channel_control_shadow_config(TIMER0,ENABLE); //开始从外同步切入自同步模式,即使用过零点检测法检测位置timer_enable(TIMER2);while(speed_count>1300){} //自同步模式切入后会有短暂的升速阶段,通过判断速度等待并确认自同步成功切入CloseLoop_Start=1; //闭环标志位置位,后续进行闭环控制
}
int main(void)
{systick_config();bldc_gpio_config(); // all gpioPID_init( &Speed_Ctrl, PID_Speed, I_ref_Max, 0.0f);PID_init( &I_Ctrl, PID_I, PWM_Duty_Max, 0.0f);NVIC_CFG();dma_config();adc_config();TimerIn_config();TimerOut_config();motor_locate(); //定位motor_openloop(); //外同步motor_sensorless_start(); //自同步-闭环while (1){}
}
通过上面的分析可知,无位置传感器直流无刷电机控制系统的难点就是加速及切换阶段。当电机顺利启动后,就可以对电机进行调速操作。其中,无位置传感器直流无刷电机和有位置传感器直流无刷电机调速原理一致。但,由于无感三段式启动过程,转子位置检测无效。因此,对电机进行的速度PID闭环控制,须在电机启动顺利完成后进行。
【零基础玩转BLDC系列】无刷直流电机无位置传感器三段式启动法详细介绍及代码分享相关推荐
- 【零基础玩转BLDC系列】无刷直流电机闭环控制与软件架构
无刷直流电动机基本转动原理等内容请参考<基于霍尔传感器的无刷直流电机控制原理>.<基于反电动势过零检测法的无刷直流电机控制原理>.<以GD32F30x为例定时器相关功能详 ...
- 【零基础玩转BLDC系列】基于反电动势过零检测法的无刷直流电机控制原理
无刷直流电动机基本转动原理请参考<基于HALL传感器的无刷直流电机控制原理>,基本原理及基础知识本篇不再赘述. 位置传感器的存在限制了无刷直流电机在某些特定场合中的应用,如:使电机系统的体 ...
- 零基础玩转C语言系列第一章——初始C语言(上)
目录 一.如何学好C语言? 1.鼓励你,为你叫好. 2.挤时间学习 3.学好编程,不仅仅是学好C语言 二.初始C语言 本章目标 本章重点 1.什么是C语言? 2.第一个C语言程序 3.数据类型 4.变 ...
- STC单片机驱动BLDC无刷直流电机(无HALL)官方示例
STC单片机驱动BLDC无刷直流电机(无HALL)官方示例 示例代码在STC8系列文档第20章里面:http://www.stcmcudata.com/STC8F-DATASHEET/STC8H.pd ...
- 劢领AT| 五分钟,零基础玩转阿里云物联网套件
劢领AT| 五分钟,零基础玩转阿里云物联网套件 阿里云准备工作 新建产品 添加设备 WIFI模块及设备连接 AT指令方式 配置网络 一步到位,直接连接阿里云 发布与订阅消息 订阅主题 说明 阿里云准备 ...
- Arduino基础篇(九)-- 无刷直流电机转速和方向控制
本文选择Arduino MEGA 2560开发板做调试,通过调整PWM的占空比,控制BLDC3525,内置有感有霍尔驱动,实现对无刷直流电机的转速控制,通过调整数字口输出高低电平,从而实现电机方向控制 ...
- 零基础 ABAP 学习教程系列文章的目录
零基础 ABAP 学习教程系列文章的目录 ABAP 标准培训教程 BC400 学习笔记之一:ABAP 服务器的架构和一个典型的 ABAP 程序结构介绍 ABAP 标准培训教程 BC400 学习笔记之二 ...
- 深圳c语言程序设计,深圳零基础玩转C语言编程
零基础玩转C语言编程 教学特色:注重学员的实操动手能力,案例解析且提供一对一服务 使用教材:国家教材 学习内容:掌握Microsft Visual 2010集成开发工具.掌握C语言编程,重点掌握数组. ...
- 零基础带你学习MySQL—备份恢复数据库(三)
零基础带你学习MySQL-备份恢复数据库(三) 一.备份数据库 二.恢复数据库 先删除数据库zs_db03 恢复数据库zs_db03 课堂练习 方法一:傻瓜式办法 直接Ctrlcv 方法二:命令行方法 ...
最新文章
- 书评 | 你为什么成不了资深产品经理?
- system函数和fork-exec机制
- VMware中虚拟机与主机不能ping通解决办法
- 微信小程序服务器域名修改生效时间,微信小程序修改request合法域名不生效及解决方法...
- 存储过程系列之存储过程返回值总结
- 系统学习深度学习(三十一)--Nature DQN(NIPS 2015)
- 数组 -- 13.2 Maximum Subarray --图解
- Rust: 如何在Windows下Atom中配置Rust环境?
- gmm聚类python_聚类算法GMM和KMeans?
- pscad调用matlab的模块,PSCAD模块库功能教程(包含与matlab接口).pdf
- 绑定流详解——网络测试仪实操
- 3dmax简单制作方法
- oracle字体库 生僻字,繁难字库生僻字大全-找字网_免费字体下载、字体在线商用授权、ttf字体分享、专业字体网站!...
- 四年级上册数学计算机笔记,读书笔记:最新人教版四年级上册数学总复习讲义...
- IBX TableVew
- java 小技巧_Java中有哪些好用的小技巧?
- Linux服务篇--LAMP架构
- 复旦计算机教师,复旦教师:我有无人能及的相声天赋
- 【靶机练习】Vulnhub靶场Earth-练习记录
- Logistic Regression Model
热门文章
- 使用mongoDB中的问题
- TSINGSEE青犀视频安防监控视频平台EasyCVR新增密码复杂度提示
- 【状态估计】无迹卡尔曼滤波(UKF)应用于FitzHugh-Nagumo神经元动力学研究(Matlab代码实现)
- 如何建立一个网站,可用互联网访问?(原创详细教程)
- lab值意义_色差仪上的字母Lab值代表什么意思
- 一种新型的语音控制器-surfboard-可简单的帮助你实施家居自能语音控制
- Python的数据分析中超参数调优方法:网格搜索
- QR分解以及最小二乘求解
- afn原理 ios_iOS AFN实现原理
- 一颗树,两棵树,三棵树_TREE_TO_Tree