昆仑山

注册

 

发新话题 回复该主题

伺服驱动软件一FOC让电机转起来 [复制链接]

1#

一,开发简介

本文为PMSM电机驱动软件开发的简易代码,目的是为了详细记录电机驱动软件+硬件的整体实现过程,(后面一节讲介绍电流环与速度环控制算法实现),为后面的PCB硬件设计提供一些参考,下面将记录一步步搭建出电机矢量控制的过程,包括调试过程和C源代码。

原理与代码相关:

1、矢量控原理框图

2、SVPWM算法

3、CLARK变换

4、PARK变换

硬件相关:

1、MCU为STM32FIGTX

2、PWM互补波形设置

3、双电阻电流采样

4、编码器AB输入

5、串口通信输出结果

6、DMA数据传输

二、电机矢量控制整体框架

整个电机控制软件三个主要环路:FOC环路,安全环路,电机控制环路,虚线方框部分为可选择组件,实现部分为主要组件,可以看到整个控制围绕了电机控制系统的方方面面。本文主要记录FOC环路。

FOC框图介绍

电流闭环控制FOC框图

以电流闭环控制为例,也就是让电机始终保持一个恒定力矩(力矩与电流成正比T=kt*iq)。

从上图可以看到最左边的Iq_Ref和Id_Ref两个变量经过PID控制器进行反馈调节,其中涉及到几个变换模块,包括:Clarke变换、Park变换以及反Park变换,最后是SVPWM模块作用到三相逆变器进而控制电机旋转。我们先来大致的概括下FOC的整个控制框图,后面会对整体框架进行拆分讲解。

①对电机三相电流进行采样得到:ia、ib、ic;

②将ia、ib、ic经过clarke变换得到iα、iβ;

③将iα、iβ经过park变换得到iq、id;

④计算iq、id和其设定值iq_Ref、id_Ref的误差;

⑤将上述误差输入到两个PID(只用到PI)控制器,得到输出的控制电压Vq、Vd;

⑥将Vq、Vd进行反park变换得到Vα、Vβ;

⑦将Vα、Vβ输入SVPWM模块进行调制,合成电压空间矢量,输出该时刻三个半桥的开关状态进而控制电机旋转;

⑧循环上述步骤。

上面是整体FOC电流环控制的整体过程,由于电流环闭环控制容易超速失控,本次只记录最核心的开环部分⑥⑦⑧的实现,有了开环控制,电机就能转起来了。

FOC坐标系定义

坐标系的定义请注意,ST的FOC库,采用的Iβ轴(即虚轴)滞后Iα90度的表示方法。与其他地方说的Iβ提前Iα90度是一样的效果。只是表示方法不同而已,选择了这种表示方法,后面的park变换也和提前90度的不同。

SVPWM算法理解

SVPWM的主要思想是以三相对称正弦波电压供电时三相对称电机定子理想磁链圆为参考标准,以三相逆变器不同开关模式作适当的切换,从而形成PWM波,以所形成的实际磁链矢量来追踪其准确磁链圆。传统的SPWM仅电源的角度出发生成一个可调频调压的正弦波电源,而SVPWM将逆变系统和异步电机看作一个整体来考虑,模型比较简单,也便于微处理器的实时控制。

普通的三相全桥是由六个开关器件构成的三个半桥。这六个开关器件组合起来(同一个桥臂的上下半桥的信号相反)共有8种安全的开关状态.其中、(这里是表示三个半桥的开关状态)这两种开关状态在电机驱动中都不会产生有效的电流。因此称其为零矢量。另外6种开关状态分别是六个非零矢量。它们将度的电压空间分为60度一个扇区,共六个扇区,利用这六个基本非零矢量和两个零量,可以合成度内的任何矢量。

当要合成某一矢量时先将这一矢量分解到离它最近的两个基本矢量,而后用这两个基本矢量去表示,而每个基本矢量的作用大小就利用作用时间长短去代表。用电压矢量按照不同的时间比例去合成所需要的电压矢量。从而保证生成电压波形近似于正弦波。

在变频电机驱动时,矢量方向是连续变化的,因此我们需要不断的计算矢量作用时间。为了计算机处理的方便,在合成时一般是定时器计算(如每0.1ms计算一次)。这样我们只要算出在0.1ms内两个基本矢量作用的时间就可以了。由于计算出的两个时间的总和可能并不是0.1ms(比这小),而那剩下的时间就按情况插入合适零矢量。由于在这样处理时,合成的驱动波形和PWM很类似。因此我们还叫它PWM,又因这种PWM是基于电压空间矢量去合成的,所以就叫它SVPWM了。

SVPWM的主要特点有:

1.在每个扇区虽有多次开关切换,但每次开关切换只涉及一个器件,所以开关损耗小。

2.利用电压空间矢量直接生成三相PWM波,计算简单。

3.逆变器输出线电压基波最大值为直流侧电压,比一般的SPWM逆变器输出电压高15%

软件平台

整体软件框图

对于整体程序流程上,电机库控制过程都发生在中断中,区别于普通顺序控制流程,也无任务调度;这样做可以将电机控制做到实时控制

FOC主要执行高频任务逻辑如下:

高频任务执行于ADC采样转换完成中断,ADC采样开始由TIM1硬件触发,转换完成后进入中断,在这个中断中执行FOC坐标变换以及SVPWM的执行,最终控制TIM1的PWM占空比输出。

具体实施过程如下:

一、使用STM32CubeMX新建工程-配置外设

1、这个根据你开发板使用的CPU具体的型号来选择,选STM32FIGTx型号

2、进入工程后打开RCC选项,选择Crystal/CeramicResonator,即使用外部晶振作为HSE的时钟源

3、开发板的外部晶振为25MHz,我们填入25;通道选择LSE;PLLM选择为/25;倍频系数N选择为x;系统时钟选择PLLCLK;系统时钟设定为Mz;APB1分频系数选择为/4即PCLK1位42MHz;APB2分频系数选择为/2即PCLK2位84MHz。

4、配置工程属性

接着选择ProjectManager选项,配置工程的名称,路径,使用的IDE工具,堆栈大小。注意不要使用中文路径和工程名称。

5.生成代码配置

点击左侧CodeGenerator.选中仅复制需要的库,否则生成的工程会很大.选择将外设配置为单独的.c和.h文件

6、开启SWD调试功能

二、PWM互补模块

高级定时器主要用于产生6路互补的PWM来驱动MOS管,加入死区防止电源导通,本文未使用刹车引脚。高级定时器1通道1、2、3用于产生PWM,通道4用于触发ADC电流采样,根据扇区的位置,灵活设置PWM占空比,进而选择合理的触发点,避免在噪声点采样。引脚配置与PWM极性请根据自己的硬件合理配置,如IR是高电平有效,而IR则是低端低有效,高端高有效。

相关变量取值:

CKTIM=//定时器时钟频率

PWM_PRSC=0//预分频器

PWM_FREQ=16//PWM频率

PWM_PERIOD=CKTIM/(2*PWM_FREQ*(PWM_PRSC+1))=

DEADTIME_NS=1//死区时间ns

DEADTIME=CKTIM/1/2*DEADTIME_NS/1=84

PWM测试:

生成工程后,应首先对PWM模块进行测试,如果有示波器,先测试PWM是否正常(安全起见一路路测试),死区时间是否正确,测试完成后进入下一项。从图中可以到死区时间位1ms,配置正确。

/*USERCODEBEGIN2*/

//PWM初始化

HAL_TIM_PWM_Start(htim1,TIM_CHANNEL_1);

HAL_TIMEx_PWMN_Start(htim1,TIM_CHANNEL_1);

__HAL_TIM_SET_COMPARE(htim1,TIM_CHANNEL_1,);//为最大占空比

/*USERCODEEND2*/

三、编码器配置

本次使用的是ABZ1线的编码器,通过配置定时器Time3的编码器模式,并设置为4倍频,可以准确的测量出当前电角度,具体配置见下图。Counter=4*1-1;

编码器测试

生成工程后,在主函数中加入初始化代码启动编码器,通过串口打印出电角度,观察信息是否正确,一圈范围为:-—+。

//使能ABZ编码器

HAL_TIM_Encoder_Start_IT(htim3,TIM_CHANNEL_ALL);//所有通道

HAL_TIM_Base_Start_IT(htim3);

四、USART1串口设置

可以通过端口连续打印数据方便查看数据的连续变化。具体配置如下。

串口测试:

1、首先在图示位置加入头文件#include“stdio.h”

/*USERCODEBEGINIncludes*/

#include"stdio.h"

/*USERCODEENDIncludes*/

2、然后在main.c文件中加入下面的这个函数,注意串口号根据自己的实际使用的串口进行更改

intfputc(intch,FILE*f)

{

//uint8_ttemp[1]={ch};

/*发送一个字节数据到串口USARTx*/

HAL_UART_Transmit(huart1,(uint8_t*)ch,1,0xFFFF);

returnch;

}

3、然后就可以使用printf()函数了

printf("\r\n这是一个通过串口通信指令控制RGB彩灯实验\n");

4、纸飞机调试助手还不错,大家可以下载使用。

五、DMA采用数据传输

DMA读取ADC常规通的数据,比如温度传感器,总线电压等参数。具体配置如下。

DMA测试

可以通过串口打印读取到的数据。

//初始化DMA

HAL_ADC_Start_DMA(hadc1,(uint32_t*)adc_buffer,50);

六、ADC采样

按图示配置好ADC外设(只用了ADC1),利用ADC中断计算FOC的参数。

ADC中断测试

由于本文不做闭环控制,可以对电流采用不做处理,仅仅利用中断函数进行开环控制。在ADC中断中设置一个GPIO口反转,看下ADC中断与触发频率是否正确,测试图如下。

//开启ADC中断,注入通道

HAL_ADCEx_InjectedStart_IT(hadc1);

七、让电机动起来

01:27

开环让电机动起来主要步骤:

1、找到电机零位,电机三相的位置与编码器要对应,通过给Ud=2;让电机停在一个位置后,让编码器清零。

2、开环控制,给Uq=2;电机就能正常正转起来,给Uq=-2;电机就能正常反转起来,Uq越大速度愉快。可以通过串口查看角度变化。

需要C源代码的可以私信我。。。

分享 转发
TOP
发新话题 回复该主题