永磁同步电机矢量控制代码说明
1、前言
永磁同步电机(PMSM)位置、速度、电流三闭环矢量控制(FOC)软件(以下简称“软件”)是为学习矢量控制算法而编写的,针对的是永磁同步电机,代码已经经过了项目验证,可以放心学习、使用。
首先说明,出此教程的目的,是为了让广大初学者可以挣脱淘宝海量教程的毒害,因为经常看到一些初学者买了一堆资料,学了大半年,结果连程序都看不懂,实践的时候最多也就是按照教程接好线,通电看电机转一转,浪费的大量的时间和金钱,很多细节问题不清楚,没有解决问题的能力。
所以,本人花了很多心思,以一套完整的、成熟的PMSM的FOC控制方案为例,从各个方面详细讲解了FOC的原理、实现方法等知识,几乎是逐条的分析了程序,又兼顾程序的系统层面,目的是让初学者看完我的资料,可以独立的完成FOC的编写、独立的解决一些问题,能达到这个目的,我就很满足了。知识是个触类旁通的东西,相信大家学完这个PMSM的FOC算法后,肯定会对电机控制有一个更深的认识。
2、软件功能设计
软件通过RS422总线与上位机实时通讯交互,在主循环中采用查询的方式接收上位机发送的系统工作模式、伺服指令,并将系统相关状态监测量实时反馈给上位机;为了保障系统安全,软件对输入指令进行了限幅,避免指令超限。
2.1功能
软件的具体功能及实现需求如下:
a)在控制电源上电后,完成各功能模块初始化;
b)通过串口与上位机通讯。通过查询方式接收上位机数据,并进行解析;
c)利用TI最新的SVPWM算法,产生占空比,驱动功率板;
d)通过DSP内部自带ADC采集母线电压信号、相电流信号;
e)完成位置闭环、速度闭环、电流闭环调节;
f)系统状态监测、故障诊断与处理(工业应用中故障诊断、系统检测是很复杂的,为了突出本教程重点,故程序仅保留过压、欠压、过流保护功能);
控制软件全部功能描述见表1和表2所示 。
序号 |
功能名称 |
说明 |
1 |
初始化功能 |
控制电源上电后对DSP相关硬件配置及变量进行初始化 |
2 |
SCI通信功能 |
与上位机通过RS422串口线进行实时通信 |
3 |
定时器功能 |
通过配置EPWM1获取125us周期定时,通过分频获取250us、1ms、10ms等周期定时 |
4 |
位置、速度、电流闭闭调节 |
完成电机位置闭环、速度闭环、电流的闭环调节 |
5 |
状态监测与故障诊断 |
对系统工作状态,故障状态实时监测 |
表2 软件性能描述
序号 |
性能名称 |
说明 |
1 |
串口数据发送周期 |
通过串口向上位机发送数据的周期为1ms。 |
2 |
脉宽调制信号 |
PWM波载波频率为8kHz,死区时间为2us |
3 |
MainPwmISR()中断程序执行时间 |
中断执行一次时间不能超过总中断时间的80%,即不超过100us。 |
2.2主要接口
与FOC控制软件相关的硬件接口,包括RS422串口,片内ADC,外设I/O,数字I/O等,连接关系见图1。
2.3安全性
a)所有中断服务程序严格禁止嵌套,软件中仅启动一个中断;
b)软件设计时要注意避免潜在的死循环。在软件模块设计过程中,不允许出现无法跳出的情况;
c)不使用的中断源要进行屏蔽,屏蔽措施包括设置中断屏蔽寄存器和编写空中断返回处理语句;
- 对采集到的信号应进行适当滤波处理,防止异常值影响软件性能。
2.4可移植性
软件的编译环境为Code Composer Studio 5.2.0,不具备可移植性。
3、软件结构设计
3.1 软件平台
软件运行的硬件平台资源:
- 处理器:TMS320F28335,晶振频率30MHz,工作主频150MHz;
- 存储器:TMS320F28335内部资源模块寄存器,片内18K×16位SARAM存储器,64K×16位Flash存储器;
- 中断源:PWM1中断,8kHz;
软件的构成如图2所示。
图2 软件结构图
3.2 各模块功能介绍
(1)系统初始化模块
名称:系统初始化模块
标识符:InitDevice(DSP28_PLLCR,DSP28_DIVSEL);
功能:配置看门狗电路,配置系统时钟,打开ePWM、SCI、SPI、ADC等用到的硬件资源的时钟信号,关闭不用的硬件的时钟信号。这个是标准的模块,用户不用自己编写,复制来按自己的需求配置即可。
(2)参数初始化模块
名称:参数初始化模块
标识符:ParaInit();
功能:软件第一次被调用时,初始化用于闭环的主要控制参数。调节PID的参数时,就是在这个函数里进行更改的。
(3)定时器模块
名称:定时器定时模块
标识符:void SchTimer(void)
功能:设置成125us-500ms多种计时器,作为流程分配的时间基准,注意定时器的时间基准是PWM的中断周期,而不是用的常规的定时器;
(4)与上位机数据交换和通讯模块
名称:串口通讯模块
标识符:void Communication()
功能:使用RS422串口与上位机进行数据交互,对接收到的数据包进行解析,同时对发送的数据包进行编码,以实现消息互通。
(5)指示灯模块
名称:指示灯模块
标识符:LED
功能:系统正常运行时,指示灯每500ms翻转一次。
(6)片内AD采集处理模块
名称:信号采集处理模块
标识符:DriverDspAdcInit()
功能:通过DSP内部自带ADC采集1路母线电压信号、2路相电流信号。
3.3 执行方案
DSP上电后,软件执行初始化模块的初始化功能。在使能中断后,软件在中断中执行数据采集、闭环控制、PWM信号输出。软件执行流程如图4所示。
3.4 接口设计
接口关系见表4。
表4控制软件接口描述
序号 |
接口 |
说明 |
引脚设置 |
|
1 |
外设GPIO0~GPIO5 |
电机6路PWM波输出(低电平有效) |
上拉,作为PWM功能引脚 |
|
2 |
数字GPIO7 |
通过控制SN74LVC8T245来决定是否关断6路PWM波 |
高电平切断输出 |
|
3 |
外设GPIO12(TZ1) |
W相电流采样芯片硬过流故障信号(低电平有效) |
上拉,作为TZ功能引脚,异步输入。 |
|
4 |
外设GPIO13(TZ2) |
U相电流采样芯片硬过流故障信号(低电平有效) IPM故障信号输入(低电平有效) |
||
5 |
外设GPIO16(TZ5) |
IR2136驱动芯片故障信号 |
||
6 |
数字GPIO25 |
LED灯控制信号(低电平灯亮) |
||
7 |
数字GPIO26 |
制动器信号 |
||
8 |
数字GPIO27 |
安全通车信号 |
||
9 |
外设GPIO30 |
ECANRXA |
CAN通信 |
|
外设GPIO31 |
ECANTXA |
|||
10 |
外设GPIO62 |
SCIRXDCM |
用于串口(SCI-C)通讯 |
上拉、异步输入、作为功能引脚 |
外设GPIO63 |
SCITXDCM |
上拉、作为功能引脚 |
||
11 |
外设GPIO51 |
EQEP1B |
EQEP |
|
外设GPIO52 |
EQEP1S |
|||
外设GPIO53 |
EQEP1I |
|||
12 |
外设GPIO54 |
SPISIMOA |
接AS2S1210的SPISIMOA引脚 |
上拉、异步输入、作为功能引脚 |
外设GPIO55 |
SPISOMIA |
接AS2S1210的SPISOMIA引脚 |
||
外设GPIO56 |
SPICLKA |
接AS2S1210的SPICLKA引脚 |
||
外设GPIO57 |
SPISTEA |
接AS2S1210的cs引脚 |
||
外设GPIO48 |
接AS2S1210的wr引脚 |
上拉、异步输入、作为IO |
||
外设GPIO51 |
接AS2S1210的A1引脚 |
模式配置 |
上拉、异步输入、作为IO、输出; 初始化清0. |
|
外设GPIO52 |
接AS2S1210的A0引脚 |
|||
外设GPIO53 |
接AS2S1210的RESET引脚 |
RESET |
||
外设GPIO58 |
接AS2S1210的Sample引脚 |
采样结果寄存器更新信号 |
上拉、异步输入、作为IO、输出 |
|
13 |
ADINA0 |
电流IA采样通道 |
片内ADC |
|
ADINA1 |
电流IB采样通道 |
|||
ADINA2 |
母线电压采样通道 |
CSCI详细设计
4.1主循环模块
4.1.1功能描述
主循环模块是程序运行时的主控流程,控制程序的流程走向。
4.1.2数据元素
无。
4.1.3流程逻辑
软件在控制电源上电复位后执行主程序,主程序完成初始化后,开中断(触发周期125us),然后进入主循环等待中断发生,同时在主循环中完成与上位机的实时通讯。
主程序流程图见图8,主要完成初始化(相关功能模块初始配置,控制变量、结构体的初始化),开主中断,然后进入主循环等待中断发生。主循环中完成与上位机的实时通讯交互(查询接收上位机输入的工作指令)。
主循环模块流程如图8所示。
4.1.4限制条件
无。
4.2 PWM初始化及TZ保护模块初始化
4.2.1功能描述
PWM初始化,配置PWM频率、死区,载波频率8kHz,死区时间为2us,对PWM1启动125us中断以及ePWM模块的错误联防保护功能。
4.2.2数据元素
无。
4.2.3流程逻辑
TBCLKSYNC位可以用来同步所有使能的ePWM模块的基准时钟,在配置ePWM模块的过程中,遵循以下步骤:
(1)使能各个ePWM模块的时钟;
(2)将TBCLKSYNC清零,从而停止所有ePWM模块的时钟;
(3)对ePWM模块进行配置;
(4)将TBCLKSYNC置位。
ePWM模块一共有7个子模块,分别为:时间基准子模块(TB)、比较功能子模块(CC)、动作限定子模块(AQ)、死区产生子模块(DB)、斩波控制子模块(PC)、故障捕获子模块(TZ)、事件触发子模块(ET)。各子模块的主要功能如下:
a.时间基准(TB)
设定基准时钟TBCLK与时钟SYSCLKOUT之间的关系;
设定PWM时间基准计数器TBCLK的频率和周期;
设定时间基准计数器的工作模式:增计数、减计数、增减计数;
设定与其他ePWM模块之间的相位关系;
通过软件或者硬件方式同步所有ePWM模块的时间基准计数器,并设定同步后计数器的方向(增计数或者减计数);
设定时间基准计数器在仿真器挂起时的工作方式;
指定ePWM的同步输出信号的信号源:同步输入信号、时间计数器归零、时间计数器等于比较器B(CMPB)、不产生同步信号。
b.比较功能(CC)
指定EPWMxA和EPWMxB的占空比;
指定EPWMxA和EPWMxB输出脉冲发生状态翻转的时间。
c.动作限定(AQ)
无反应;
EPWMxA和/或EPWMxB得输出切换到高电平;
EPWMxA和/或EPWMxB得输出切换到低电平;
EPWMxA和/或EPWMxB得输出进行状态翻转。
d.死区产生(DB)
控制上下两个互补脉冲之间的死区时间;
设定上升沿延时时间;
设定下降沿延时时间;
不做处理。
e.斩波控制(PC)
产生斩波频率;
设定脉冲序列中第一个脉冲的宽度;
设定第二个及其以后脉冲的脉冲宽度;
不做处理。
f.故障捕获(TZ)
配置ePWM模块响应一个、全部或者不响应外部故障触发信号;
设定当外部故障触发信号出现时,强制EPWMxA和/或EPWMxB为高电平、低电平、高阻态、不做反应;
设定ePWM对外部故障触发信号的响应频率:单次响应,周期性响应;
使能外部故障触发信号产生中断;
不做处理。
g.事件触发(ET)
使能ePWM模块的中断功能;
使能ePWM模块产生ADC启动信号;
设定触发事件触发中断或ADC启动信号的频率:每次都触发、2次才触发、3次才触发;
挂起、置位或清除事件标志位。
在配置ePWM模块时,按照图6所示流程进行。
图6 EPWM模块
图6中,虚线包围的模块,可以根据实际需求,选择使用或者让PWM直接通过该模块。事件触发子模块用来处理事件基准计数器、比较功能子模块产生的时间,从而向CPU发出中断请求或者产生ADC启动信号SOCA或SOCB。
4.2.4程序实现
4.2.6限制条件
无。
4.3 SCI初始化模块
4.3.1功能描述
串口初始化,设置波特率为921600pbs,8位数据位,1位停止位;无奇偶校验,全双工传送,设置FIFO深度为1。
4.3.2数据元素
无。
4.3.3流程逻辑
SCI内部串行时钟信号由低速外设时钟信号LSPCLK及波特率选择寄存器共同决定。BRR为16为波特率设定值,其高8位装入SCIHBAUD中,低8位装入SCILBAUD中,即可配制出不同的波特率。
若BBR=0, ;
若1≤BRR≤65535,,因此。
4.3.4限制条件
无。
4.4 片内AD采集处理模块
4.4.1功能描述
采样2路相电流及1路母线电压,采样值进行滤波数据处理。
片内AD信号采集处理功能如表5所示
表5 片内AD信号采集处理
功能名称 |
片内AD信号采集处理 |
|
输入 |
激励事件 |
125us定时 |
数据 |
母线电压、相电流 |
|
处理 |
片内AD模块实现母线电压、A和C两路相电流AD值采集,并进行解算。 |
|
输出 |
解算后的母线电压值、相电流值 |
|
说明 |
无 |
4.4.2数据元素
片内AD采集处理模块数据定义如表6所示。
序号 |
数据名称 |
数据标识 |
数据类型 |
|
输出数据 |
1 |
母线电压 |
ubus |
float |
2 |
A相电流 |
IPhase.Iu |
float |
|
3 |
C相电流 |
IPhase.Iw |
float |
4.4.3流程逻辑
ADC模块具有多个分频器,以产生任何需要的ADC操作时钟,图7为ADC的时钟链结构。
图7 ADC时钟链结构图
4.4.4限制条件
无。
中断处理模块
4.5.1功能描述
EPWM1产生的主中断,1次事件触发1次中断,因此中断触发周期为125us,该模块执行时间不能超过125us的80%即100us。该模块完成状态机机制下各子函数定时计数器时间分配任务(根据上位机指令,选择要执行的流程)。
中断服务程序流程图见图6所示,中断服务程序中主要完成:
(a)获取转子位置角度(每125us);
(b)获取电机三相电流(每125us);
(c)通过分频获取其他周期定时;
(d)每125us执行电流闭环控制;
(e)每1ms执行速度闭环控制(如果被选择);
(f)每2ms执行位置闭环控制(如果被选择);
其中电流闭环、速度电流双闭环、位置速度电流3闭环程序分别为6.1、6.2、6.3所示。
图6 中断服务程序流程图
图6.1 电流环子程序流程图
图6.2 速度环子程序流程图
图6.3 位置闭环子程序
其中3个环中使用的MotorDriv()流程如图6.4所示。
图6.4 子程序
定时计数器配置功能:使用EPWM1产生的主中断周期作为时间基准,使用TimerCtrl结构体定义的变量TimerCnt自加,得到125us到500ms不同的定时计数器各9种,当TimerCnt变量累加到所需定时计数器的预设值时,设置时间标识位变量置1,执行相应的功能函数,函数执行完成后该变量清零。
软件定时器功能见表7。
表7 定时器功能
功能名称 |
定时器功能 |
|
输入 |
激励事件 |
ePWM1产生中断(125us) |
数据 |
无 |
|
处理 |
125us周期定时到,标志位置1;定时计数器值累加,判断其他如250us、1ms、5ms、10ms、500ms等周期定时是否到。 |
|
输出 |
各定时器标志位 |
|
说明 |
标志位会在对应函数执行后清0 |
4.5.2数据元素
无。
4.5.3流程逻辑
现针对该模块中所调用的各子模块进行详细描述。
(0)转子位置角获取(电角度)
电机26对极,旋变2对极。旋变经过调理电路,给AD的是0-65535的数字量,代表了电机的绝对位置。
电机转子轴旋转一圈,旋变的AD采样值从0-65535变化2次。
即有:
因此:
又因为:
转子位置角获取(电角度)
此时计算出来的电角度范围超过了2pi,需要进行取模运算。
因为电机转1圈时,电角度的范围为:,此时,旋变的范围为65535*2,因此,可以对旋变读数进行取模,使得计算得到的电角度在0-2pi之间。
显然,取模的系数=。
因此,最终,电角度RotorPos.elec_theta = (RotorPos.RotorAngle%5042)*0.001246。
代码中电机5对极,旋变1对极的,因此计算出来为:
RotorPos.elec_theta =(RotorPos.RotorAngle%13107)*0.00048-2.6; //转换为电机电角度
注意-2.6的来源:
FOC使用的是电机的电角度(不是编码器的读数),而编码器安装时的0位很难和电机的机械零位对齐,如果知道了两者之间的偏差,就可以通过读取编码器读数,根据上述解算,求出电机的转子位置角度。
测量的方法为:首先令反Park变换使用的角度为0,给定Vq=0,Vd=0.1(此处指的标幺电压值,理解成10%占空比),运行程序,在调试模式下,读取RotorPos.elec_theta =(RotorPos.RotorAngle%13107)*0.00048的值,该值就是编码器零位和电机机械零位的偏差,我读到的就是2.6,因此在后面减去了2.6作为补偿值。
一般要多次正反测量,求出平均值,因为电机正反摩擦力会不一样。
(1)电机转速计算模块
本程序的第一版本对应的电机为5对极,旋变为1对极。计算的思路如下:
电机从0位开始旋转,旋变信号AD值在0~65535之间变化。当电机旋转一整圈,旋变值会回到初始值,发生0与65535之间跳变。
通过旋变信号AD值计算转子角度的函数,delta为旋变零位补偿后AD值两次采样之差,实际电机最大速为1200r/min,所以电机尚未旋转到一整圈时,每1ms计算一次电机转速,旋变AD值最大变化1310。只有在发生旋转够一整圈时,旋变AD值发生0与65535之间跳变。因此对于一次采样间隔,当旋变值变化量delta发生了很大变化时(远大于实际可以达到的差值),即认为发生了电机旋转到一整圈。
电机有正转和反转,基于对称考虑,选择了32767和-32768作为反转与正转情况下,电机旋转到达整圈,即发生旋变信号回归初始值的判断阈值。
计算电机转速如图7所示。
图7 电机转速计算流程图
本程序电机是26对极的,旋变是2对极的,解算思路一样的,不再重复。
(2)获取AD采样值及电流计算
获取相电流AD采样值及相电流计算的流程如图8所示。
图8 获取相电流AD采样值及相电流计算流程
(3)电流闭环控制
电流环在PMSM调速系统中如图中虚线所示。
图9 闭环控制结构框图
电流闭环控制功能如表8所示。
表8 电流闭环控制功能表
功能名称 |
电流环闭环调节 |
|
输入 |
激励事件 |
125us定时到 |
数据 |
电流环指令iq,电流反馈ia、ib、ic |
|
处理 |
1)速度环调节给出电流指令;通过旋转编码器解算出转子位置角;通过AD获取电机相电流; 2)电流指令与电流反馈做差得到电流偏差,电流偏差经过PI调节后输出电压; 3)d、q轴电压经过Ipark变换得到uα、uβ; 4)利用SVPWM算法计算出PWM波的占空比。 |
|
输出 |
PWM波的占空比 |
|
说明 |
电流环周期为125us。 |
电流环闭环控制流程如图10所示。
图10 电流环闭环控制流程
(4)速度闭环控制
该模块首先解算出电机速度反馈值,然后和速度指令作差,偏差经过速度PI调节器后,输出q轴的电流指令。
TimerCtrl.TF_1ms标志位置1后,即1ms定时到,电机驱动使能情况下,解算出电机转向以及速度反馈值,求出iq,然后将TimerCtrl.TF_1ms标志位请0。电机驱动失能情况下,解算出电机转向以及速度反馈值后,将电流环所有参数清0,PWM占空比固定为50%。
速度闭环控制功能如表9所示。
表9 速度闭环控制功能
功能名称 |
速度环闭环调节 |
|
输入 |
激励事件 |
1ms定时到 |
数据 |
电机速度指令,电机速度反馈 |
|
处理 |
解算出电机速度反馈; 速度指令与速度反馈做差得到速度偏差,速度偏差经过速度PI调节后,输出q轴电流指令。 |
|
输出 |
q轴电流指令 |
|
说明 |
周期1ms |
速度闭环主控流程如图11所示。
图11 速度闭环主控流程图
(5)位置闭环控制
由于程序对应的电机没有安装位移测量模块,所做的位置闭环受限制,在程序中计圈数实际意义不大,故实际上没用位置环。
如果用户使用位置环,只需要将绝对位置信号反馈给程序,即可完成位置闭环控制。
4.5.4限制条件
无
其他说明
#if FLASH
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
InitFlash(); // Call the flash wrapper init function
#endif
这几句是将FLASH中的程序COPY到RAM中运行,通常的目的是加快程序的运行速度,通常有两种情况需要这样去操作:
1、程序中对时基要求比较高的函数,如中断;
2、程序需要对FLASH进行操作,这时就要把程序先复制到RAM中运行然后才能对FLASH操作。
RamfuncsLoadStart、RamfuncsLoadEnd、RamfuncsRunStart这三个变量是在CMD文件中创建的,创建方式如下:
LOAD_START(RamfuncsLoadStart),
LOAD_END(RamfuncsLoadEnd),
RUN_START(RamfuncsRunStart),
分别表示了装载函数的首地址,装载函数的结束地址和装载函数的运行地址;
执行完MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);后,便将FLASH中相关的程序COPY到了RAM中,之后的程序运行时,只要调用FLASH中RamfuncsLoadStart地址开始的相关函数,系统都会自动地指向RAM中相应的函数入口地址运行。