可编程逻辑
电流回路控制长期以来一直在过程控制系统和自动化制造设施中发挥重要作用。为了满足对更高性能伺服系统的需求,制造商需要在基于高速 FPGA 和昂贵信号链的复杂设计中实现更快的电流环路控制解决方案。
但是,本文将使用德州仪器(TI) 的实际解决方案展示,微控制器硬件和软件功能的最新进展使得在不牺牲性能的情况下降低实施成本成为可能。
控制回路操作
在许多控制系统中,设计人员依靠比例积分 (PI) 控制回路来管理电流或其他性能特征。原则上,这些控制器很简单。他们使用期望性能和测量性能之间的误差,根据两个错误处理路径的输出生成校正信号(图 1)。比例 (P) 路径将增益应用于误差;积分 (I) 路径对误差进行积分并放大结果。
图 1:比例积分 (PI) 控制回路生成校正信号,该信号将积分测量信号误差输出与将简单比例增益应用于误差信号的路径相结合。(图片来源:德州仪器)
与更简单的控制应用不同,伺服电机的设计依赖于三个相互依赖的性能特征:位置、速度和电流。为了改变电机转子的位置,它的速度需要改变。反过来,为了改变其速度,通过脉宽调制 (PWM) 施加到电机绕组的电流需要改变。伺服电机控制开发人员在级联控制结构中反映了这种循环相互依赖关系,如图 2 所示。
图 2:级联伺服控制系统使用嵌套反馈回路来快速响应性能偏差,而不是等待影响传播到整个控制结构。(图片来源:NCTU)
这种嵌套方法通过在潜在错误传播之前纠正它们来固有地帮助稳定性。例如,在负载变化显着影响速度和位置之前,最里面的电流回路可以独立地修改扭矩以响应负载变化。
同时,这种嵌套方法意味着外部循环的性能只能与其底层的内部循环一样好。在伺服系统中,如果内环缺乏支持外环性能预期的带宽,那么提高位置和速度性能的努力将不可避免地落空。最终,内部电流环路的性能有效地定义了整个伺服系统的性能极限。
电流回路控制很好理解,概念上也很简单。电流控制器修改驱动逆变器的 PWM 输出,逆变器反过来为电机绕组(或电源设计中的变压器)供电。使用快速模数转换器 (ADC) 测量电机电流,控制器可以确定修改 PWM 输出以实现所需电机性能所需的校正信号。
然而,在这个概念上简单的过程的核心,数字控制系统中使用的磁场定向控制 (FOC) 算法可能会带来巨大的计算负担。FOC 算法操纵电流的矢量表示,使用 Park 和 Clarke 变换来达到最佳解决方案(图 3)。
图 3:为了根据测量的电机性能调整 PWM 输出,电机控制回路使用复杂的向量空间表示,包括提出了重要处理要求的 Park 和 Clarke 变换。(图片来源:德州仪器)
在软件库中实现的高性能 MCU 可以足够快地生成电流环路,以满足传统伺服系统的要求。在这些系统中,PI 控制器通常将电流环路带宽限制在 PWM 载波频率的 10% 左右,该载波频率通常在 10 kHz 左右运行。
更高的带宽会导致复杂性和电源管理问题
为了提高内部环路带宽,设计人员已将 PWM 载波频率提升至 30 kHz 及以上。然而,在这些更高的频率下,传统的电流环路设计开始滞后,无法足够快地完成控制算法。因此,希望提高内部环路带宽的开发人员已转向基于 FPGA 的专用子系统,这些子系统旨在在更高的载波频率上执行控制算法的计算(图 4)。
图 4:在提高 PWM 载波频率提高内环性能的同时,工程师需要使用高速 FPGA 和 ADC 构建更复杂的电流环控制设计。(图片来源:德州仪器)
尽管使用这些专用子系统提高了性能,但它也显着提高了电流环路实现的成本和复杂性。设计人员需要添加组件,包括通常不集成到 FPGA 本身中的高速、高分辨率 ADC 和模拟比较器。在电机和 MCU 与 FPGA 的接口处,工程师需要确保最大吞吐量,最大限度地减少可能在这个关键处理循环中阻碍性能的任何延迟。除了处理额外的硬件要求外,这些系统的设计人员还需要在开发过程中解决 FPGA 代码编程和调试的额外要求,然后最终将生产代码存储在主机 MCU 中。
虽然使用 FPGA 会增加自己的一组额外的硬件和软件要求,但使用更高的 PWM 频率会从根本上影响设计。在更高频率下运行可能意味着额外的逆变器开关损耗和对更高功率驱动器的需求。这反过来又转化为对更大、更高输出电源的要求。增加的功率水平导致需要更强大的热管理。
除了增加设计复杂性、尺寸和成本之外,与基于 FPGA 的电流回路设计相关的额外要求可能会影响项目进度和最终交付。相比之下,德州仪器 (TI) 的专用 MCU 和软件消除了基于 FPGA 的电流环路控制的复杂性。
优化的基于 MCU 的解决方案简化了高性能环路设计
通过利用德州仪器TMS320F28379S单核和TMS320F28379D双核 C2000 Delfino MCU 的特殊功能,TI 快速电流环路 (FCL) 软件库使伺服设计人员能够在不增加 PWM 载波的情况下实现内部控制环路的高带宽性能频率。使用这种方法,开发人员可以使用熟悉的基于 MCU 的设计和软件开发方法构建高度响应的伺服应用程序。
TI 的方法可在 500 纳秒 (ns) 内完成 FOC 处理并执行 PWM 更新,从而允许子周期 PWM 更新,而不是等待整个控制环路周期通过。这种方法让开发人员可以在 10 KHz PWM 载波频率下实现超过 3 kHz 的控制环路带宽,将控制环路带宽增加三倍,而无需像基于 FPGA 的方法所要求的那样将 PWM 载波频率增加三倍。
这种更简单的设计方法提高性能的关键在于专门的 C2000 MCU 结构与 FCL 软件相结合,以提供与传统的基于 FPGA 的控制回路相当的功能和性能(图 5)。这些专用 MCU 基于 TI 的 32 位 C28x 浮点 CPU,将完整的模拟和数字外设与专用功能块集成在一起。
图 5:TI TMS320F28379S 和 TMS320F28379D C2000 Delfino MCU 中的集成外设和专用模块提供与以前使用 FPGA 构建的控制回路元件相当的功能和性能,以实现快速电流回路性能。(图片来源:德州仪器)
TI 设计的这些外设和模块不仅具有片上特性的集合,而且集成度特别高,适合高速控制环路操作。例如,为了捕获控制环路计算中使用的数据,MCU 集成了一个灵活的模拟信号链,其中包括一个比较器子系统 (CMPSS) 和四个高速 ADC。每个 CMPSS 都包括一个专用模拟信号路径(图 6),其输出连接到集成交叉开关,连接到 GPIO 多路复用器、ADC 和 PWM 子系统。同样,工程师可以使用交叉开关将 ADC 的输出引导至 PWM 和其他模块。
图 6:TI 通过构建紧密集成的功能(例如在其基于 MCU 的控制环路解决方案的输入端使用的比较器子系统)实现类似 FPGA 的控制环路性能。(图片来源:德州仪器)
片上 Sigma-Delta 滤波器模块 (SDFM) 包括四个独立的比较器和四个独立的滤波器,它们支持图 5 所示控制回路中使用的 sinc 滤波器功能。在控制回路的输出端,MCU 结合了其增强的具有高分辨率脉冲宽度调制器 (HRPWM) 的 PWM 子系统,步长分辨率为 150 皮秒 (ps)(典型值)。在 PWM 模块中,跳闸子模块响应各种故障或强制事件条件,以缓解短路或过流条件等问题。
除了这些先进的 I/O 子系统,MCU 还提供了完善对高速控制回路设计的支持所需的专用模块。在这些块中,集成的可配置逻辑块 (CLB) 提供了实现逻辑功能所需的资源,否则这些逻辑功能需要额外的外部设备。对于开发人员,TI 提供了一系列配置 CLB 以支持特定类型功能的软件资源。
特别是对于高速电流环路,TI 提供了使用 CLB 提供位置管理器功能的软件,如图 5 所示。在这种情况下,位置管理器支持行业标准的双向编码器接口,例如 EnDat 和 BiSS。
这些双向编码器接口专为传输位置和控制数据而设计,具有很高的性能要求。BiSS 解决方案通常基于 FPGA 或 ASIC,特别是用于实现连续模式 BiSS 或 BiSS-C。相反,TI 的 BiSS-C 位置管理器使用在 MCU 上运行的软件和 MCU 硬件资源(包括 SPI 接口、交叉开关和 CLB)的组合来实现编码器接口(图 7)。
图 7:TI 使用 MCU 可配置逻辑块 (CLB) 和其他 MCU 功能来实现复杂逻辑,例如连续模式双向串行同步 (BiSS-C) 编码器接口。(图片来源:德州仪器)
在提供高速电流环路解决方案时,TI 将这些资源与其 FCL 库相结合,后者可处理前面提到的 FOC 计算。在这里,库进一步利用了专门的 MCU 硬件,包括集成的三角数学单元 (TMU) 和控制律加速器 (CLA),它们可以从处理器内核中卸载数学密集型处理。例如,控制回路代码可以使用 CLA 独立处理编码器反馈,并使用 TMU 以比基于处理器的计算快近一个数量级的速度执行 Park 和 Clarke 变换。
隐藏复杂性
也许最重要的是,FCL 库隐藏了实现伺服回路控制所需的所有详细操作的复杂性,使开发人员能够专注于他们的独特需求。FCL 应用程序编程接口 (API) 仅包含表 1 中所示的几个功能。
API函数描述
Uint32 FCL_GetSwVersion(void);返回一个 32 位常量;对于此版本,返回的值为 0x00000002
无效 FCL_Complex_Ctrl(无效);作为 FCL 的一部分执行复杂控制
无效 FCL_PI_Ctrl(无效);作为 FCL 的一部分执行 PI 控制
无效 FCL_PI_CtrlWrap(无效);PI 控制模式下 FCL 完成时用户应用程序调用的结束函数
无效 FLC_QEP_wrap(无效);由用户应用程序调用以处理 QEP 反馈完成。该函数仅在 FCL_LEVEL2 中使用。
无效 FCL_Complex_CtrlWrap(无效);复杂控制模式下 FCL 完成时用户应用程序调用的总结函数
无效 FCL_initPWM(易失性结构 EPWM_REGS *ePWM);为 FCL 操作初始化 PWM,此函数由用户应用程序在初始化或设置过程中调用
无效 FCL_ControllerReset(无效);调用以重置 FCL 变量,当用户想要停止和重新启动电机时很有用
表 1:德州仪器快速控制库 (FCL) 将基于 FOC 的电流环路控制的复杂性隐藏在一个简短的 API 后面。(表格来源:德州仪器)
除了这些函数的 C 接口声明外,FCL 头文件还包括一些额外的包引用和一个关键的 C 结构,该结构包含与当前循环相关的少数必需参数(清单 1)。
复制
// ==============================================================
typedef struct currentLoopPars {
float32 CARRIER_MID, // Mid point value of carrier count
ADC_SCALE, // ADC conversion scale to pu
cmidsqrt3; // internal variable
float32 tSamp, // sampling time
Rd, // Motor resistance in D axis
Rq, // Motor resistance in Q axis
Ld, // Motor inductance in D axis
Lq, // Motor inductance in Q axis
Vbase, // Base voltage for the controller
Ibase, // Base current for the controller
wccD, // D axis current controller bandwidth
wccQ, // Q axis current controller bandwidth
Vdcbus, // DC bus voltage
BemfK, // Motor Bemf constant
Wbase; // Controller base frequency (Motor) in rad/sec
} FastCurrentLoopPars_t;
清单 1:德州仪器 (TI) 的集成控制回路解决方案意味着开发人员只需要几个软件结构,例如这个用于 TI controlSUITE软件包中提供的控制回路参数的软件结构。(代码来源:德州仪器)
虽然 FCL 库隐藏了设计基于 FOC 的电流环路的复杂性,但伺服控制操作的复杂性是不可避免的。为帮助开发人员评估性能并获得伺服控制操作经验,德州仪器 (TI) 提供了TMDXIDDK379D DesignDrive 开发套件,该套件提供了基于 TI FCL 库的伺服控制设计的完整实现。除了硬件板,TI 还提供了一套完整的原理图和制造数据,开发人员可以扩展这些数据来开发他们的定制伺服应用。
由于关键控制回路机制内置于底层 MCU 和 FCL 库中,因此开发人员需要相对较少的附加组件来实现完整的伺服设计。如原理图中详述,设计可以使用几个无源元件和三个 TI 器件实现 EnDat 或 BiSS 编码器接口的硬件端:SN65HVD3088ED RS485 收发器;TXB0104DR电平转换器;和TPS27082L高侧负载开关(图 8)。
图 8:德州仪器 controlSUITE 包中包含的原理图演示了简单的硬件接口,例如这个最小的 EnDat-BiSS 接口,需要补充使用 MCU CLB 在片上实现的完整编码器功能。(图片来源:德州仪器)
与硬件设计一样,TI 快速控制环路解决方案的软件设计在概念上更为简单。因为 MCU 的专用硬件和专用固件的组合完成了所有工作,所以软件开发在很大程度上是一个设置 MCU 和配置平台的过程。例如,TI 软件包提供了一个简单的main()例程,其中包含数百行代码,这些代码严格关注初始化 MCU 和 FCL 功能并配置其设置。实际的主例程只是一个空的等待循环(清单 2)。
//*****************************************************************************
void main(void)
{
// Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F28M3Xx_SysCtrl.c file.
InitSysCtrl();
// Only used if running from FLASH
// Note that the variable FLASH is defined by the compiler
#ifdef _FLASH
// Call Flash Initialization to setup flash waitstates
// This function must reside in RAM
InitFlash(); // Call the flash wrapper init function
#endif //(FLASH)
// Enable Interrupt Generation from the PWM module
EPwm1Regs.ETSEL.bit.INTEN=1;
// This needs to be 1 for the INTFRC to work
EPwm1Regs.ETPS.bit.INTPRD=ET_1ST;
EALLOW;
PieVectTable.ADCC1_INT = &ResolverISR;
//PieVectTable.EPWM11_INT = &MotorControlISR;
// PieVectTable.ADCA1_INT = &MotorControlISR;
PieVectTable.EPWM1_INT = &MotorControlISR;
// PieVectTable.TIMER1_INT = &TimerISR;
// PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable ADCA1INT in PIE group 1
// PieCtrlRegs.PIEIER3.bit.INTx11 = 1; // Enable PWM11INT in PIE group 3
PieCtrlRegs.PIEIER3.bit.INTx1 = 1; //// Enable PWM1INT in PIE group 3
#if POSITION_ENCODER == RESOLVER_POS_ENCODER
PieCtrlRegs.PIEIER1.bit.INTx3 = 1; // Enable ADCC1INT in PIE group 1
#endif
IER |= M_INT3; // Enable group 3 interrupts - EPWM1, 11 are here
// IER |= M_INT1; // Enable group 1 interrupts - ADCA, B are here
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
EDIS;
// ***************************************************************************
// Initializations COMPLETE
// - IDLE loop. Just loop forever
// ***************************************************************************
for(;;) //infinite loop
{
// State machine entry & exit point
//===========================================================
(*Alpha_State_Ptr)(); // jump to an Alpha state (A0,B0,。。.)
//===========================================================
}
} //END MAIN CODE
清单 2:德州仪器 controlSUITE 中软件示例的这个片段演示了如何设置快速控制回路操作在很大程度上是一个初始化 MCU 和快速控制回路库的过程;主程序本身就是一个简单的等待循环。(代码来源:德州仪器)
一旦在启动时配置了 MCU,使用 TI 方法实现控制环路所需的大部分工作就是提供适当的中断服务例程 (ISR) 来处理电机控制任务。TI 使用快速控制回路示例软件模块中提供的 MotorControlISR 功能演示了此类 ISR。在设置期间启用(例如,PieVectTable.ADCC1_INT = &ResolverISR在清单 2 中),MotorControlISR 函数说明了软件工程师如何使用 FCL API 来执行测量和生成输出(清单 3)。
// =============================== FCL_LEVEL 3 ======================================
// Level 3 verifies the dq-axis current regulation performed by PID and speed
// measurement modules
// lsw=0: lock the rotor of the motor
// lsw=1: close the current loop
// NOTE:-
// 1. Iq loop is closed using actual QEP angle.
// Therefore, motor speed races to high speed with lighter load. It is better
// to ensure the motor is loaded during this test. Otherwise, the motor will
// run at higher speeds where it can saturate. It may be typically around the
// rated speed of the motor or higher.
// 2. clarke1.As and clarke1.Bs are not brought out from the FCL library
// as of library release version 0x02
// ==============================================================================
//TODO INCRBUILD 3
#if (BUILDLEVEL==FCL_LEVEL3)
#if (FCL_CNTLR == PI_CNTLR)
FCL_PI_Ctrl();
#endif
#if (FCL_CNTLR == CMPLX_CNTLR)
FCL_Complex_Ctrl();
#endif
// ------------------------------------------------------------------------------
// fcl_cycle_count calculations for debug
// customer can remove the below code in final implementation
// ------------------------------------------------------------------------------
get_FCL_time();
// ------------------------------------------------------------------------------
// Measure DC Bus voltage using SDFM Filter3
// ------------------------------------------------------------------------------
FCL_Pars.Vdcbus = (temp=SDFM1_READ_FILTER3_DATA_16BIT)*SD_VOLTAGE_SENSE_SCALE;
if (FCL_Pars.Vdcbus 《 1.0)
FCL_Pars.Vdcbus = 1.0;
// ------------------------------------------------------------------------------
// Fast current loop controller wrapper
// ------------------------------------------------------------------------------
#if (FCL_CNTLR == PI_CNTLR)
FCL_PI_CtrlWrap();
#endif
#if (FCL_CNTLR == CMPLX_CNTLR)
FCL_Complex_CtrlWrap();
#endif
// ------------------------------------------------------------------------------
// Alignment Routine: this routine aligns the motor to zero electrical angle
// and in case of QEP also finds the index location and initializes the angle
// w.r.t. the index location
// ------------------------------------------------------------------------------
if(!RunMotor)
{
lsw = 0;
pi_id.Ref = IdRef = 0;
FCL_ControllerReset();
}
else if (lsw == 0)
{
// alignment current
IdRef = IdRef_start; //IQ(0.1);
// set up an alignment and hold time for shaft to settle down
if (pi_id.Ref 》= IdRef)
{
if (++cntr 》= alignCnt)
{
cntr = 0;
// IdRef = IdRef_run;
#if POSITION_ENCODER==QEP_POS_ENCODER
lsw = 1; // for QEP, spin the motor to find the index pulse
#else
lsw = 2; // for absolute encoders no need for lsw=1
#endif
}
}
} // end else if (lsw=0)
else if (lsw == 2)
IdRef = IdRef_run;
// ------------------------------------------------------------------------------
// Connect inputs of the RMP module and call the ramp control macro
// ------------------------------------------------------------------------------
if(lsw==0) rc1.TargetValue = rc1.SetpointValue = 0;
else rc1.TargetValue = SpeedRef;
RC_MACRO(rc1)
// ------------------------------------------------------------------------------
// Connect inputs of the RAMP GEN module and call the ramp generator macro
// ------------------------------------------------------------------------------
rg1.Freq = rc1.SetpointValue;
RG_MACRO(rg1)
posEncElecTheta[POSITION_ENCODER] = qep1.ElecTheta;
speed1.ElecTheta = posEncElecTheta[POSITION_ENCODER];
SPEED_FR_MACRO(speed1)
//------------------------------------------------------------------------------
// Variable display on DACs B and C
//------------------------------------------------------------------------------
DacbRegs.DACVALS.bit.DACVALS = DAC_MACRO_PU(pi_iq.Ref); //rg1.Out*4096;
DaccRegs.DACVALS.bit.DACVALS = DAC_MACRO_PU(pi_iq.Fbk); //posEncElecTheta[POSITION_ENCODER]*4096;
// ------------------------------------------------------------------------------
// setup iqref for FCL
// ------------------------------------------------------------------------------
pi_iq.Ref = (lsw==0) ? 0 : IqRef;
// ------------------------------------------------------------------------------
// setup idref for FCL
// ------------------------------------------------------------------------------
pi_id.Ref = ramper(IdRef, pi_id.Ref, _IQ(0.00001));
// ------------------------------------------------------------------------------
// Connect inputs of the DATALOG module
// ------------------------------------------------------------------------------
DlogCh1 = posEncElecTheta[POSITION_ENCODER];
DlogCh2 = rg1.Out;
DlogCh3 = pi_iq.Ref;
DlogCh4 = pi_iq.Fbk;
#endif // (BUILDLEVEL==FCL_LEVEL3)
清单 3:德州仪器 controlSUITE 示例软件展示了开发人员如何在很大程度上将控制循环实现代码归类为中断服务例程,而中断服务例程只需要对 TI 快速控制循环 (FCL) 库进行几次 API 调用。(代码来源:德州仪器)
尽管演示套件和软件有助于简化开发,但对于经验不足的工程师来说,伺服控制操作可能会让人望而生畏。为了帮助设计人员更好地理解伺服控制,TI 开发套件让他们可以通过一系列增量构建级别来探索其操作。在这里,开发人员只需通过设置来选择构建级别BUILDLEVEL(例如,参见清单 3)。在演示了基本 PWM 信号输出(级别 1)和开环操作(级别 2)之后,开发人员使用接下来的三个构建级别来仔细检查全伺服控制设计的每个嵌套循环的操作(图 9)。
图 9:使用 TMDXIDDK379D DesignDrive 开发套件和 TI controlSUITE 软件,开发人员可以在一系列阶段探索伺服控制设计,首先评估最里面的电流控制环(绿色),然后添加速度环(蓝色),最后添加完整伺服设计中的位置环(橙色)。(图片来源:德州仪器)
BUILDLEVEL=FCL_LEVEL3例如,通过设置,开发人员可以探索内循环本身的操作。在这个级别内,开发人员甚至可以测试使用不同底层机制或参数的效果。例如,通过设置FCL_CNTLR 3 级 ISR(参见清单 3),开发人员可以选择使用 PI 控制器 ( FCL_CNTLR=PI_CNTLR) 或复杂控制器 ( FCL_CNTLR=CMPLX_CNTLR) 来操作循环。如清单 3 所示,基于FCL_CNTLR设置的条件编译只会调用相应的 FCL API 例程(参见表 1)。使用这种方法,开发人员可以逐步沉浸在完整伺服控制设计的操作中,最终在 TI 开发套件的基础上构建自己的高速伺服应用。
结论
在伺服回路中,内部电流控制回路的性能有效地定义了整个伺服控制应用的局限性。过去,希望增强内环的开发人员不得不提高 PWM 载波频率,并通过使用 FPGA 和高速 ADC 构建的子系统支持更高的频率。
开发人员无需面对与此方法相关的成本和可能的延迟,而是可以利用 TI 结合了专用 MCU 和软件库的更简单的解决方案。使用这种方法,开发人员可以创建伺服控制应用程序,仅使用基于 FPGA 的专门设计就可以实现内环性能,而时间和成本只是其中的一小部分。
全部0条评论
快来发表一下你的评论吧 !