基于tms320f2812的永磁同步电动机svpwm空间矢量控制算法实现的源代码(终稿)
- 格式:doc
- 大小:72.50 KB
- 文档页数:20
基于空间矢量控制(SVPWM)技术的三相电压型整流器设计作者:佚名来源:本站整理发布时间:2010-9-9 10:54:01 [收藏] [评论]传统的变压整流器和非线性负载的大量使用使电网中电流谐波含量较高,对飞机供电系统和供电质量造成很大影响。
消除电网谐波污染、提高整流器的功率因数是电力电子领域研究的热点。
空间矢量PWM(SVPWM)控制具有直流侧电压利用率高、动态响应快和易于数字化实现的特点。
本文采用空间矢量技术对三相电压型整流器进行研究,使其网侧电压与电流同相位,从而实现高功率因数整流。
1 空间矢量控制技术SVPWM控制技术通过控制不同开关状态的组合,将空间电压矢量V控制为按设定的参数做圆形旋转。
对任意给定的空间电压矢量V均可由这8条空间矢量来合成,如图1所示。
任意扇形区域的电压矢量V均可由组成这个区域的2个相邻的非零矢量和零矢量在时间上的不同组合来得到。
这几个矢量的作用时间可以一次施加,也可以在一个采样周期内分多次施加。
也就是说,SVPWM通过控制各个基本空间电压矢量的作用时间,最终形成等幅不等宽的PWM脉冲波,使电压空间矢量接近按圆轨迹旋转。
主电路功率开关管的开关频率越高,就越逼近圆形旋转磁场。
为了减少开关次数,降低开关损耗,对于三相VSR某一给定的空间电压矢量,采用图2所示的合成方法。
在扇区I中相应开关函数如图3所示。
零矢量均匀地分布在矢量的起、终点上,除零矢量外,由V1、V2、V4合成,且中点截出2个三角形。
一个开关周期中,VSR上桥臂功率开关管共开关4次,由于开关函数波形对称,谐波主要集中在整数倍的开关频率上。
2 直接电流控制策略三相VSR的电流控制策略主要分为直接电流控制和间接电流控制。
直接电流控制采用网侧电流闭环控制,提高了网侧电流的动、静态性能,并增强电流控制系统的鲁棒性。
而在直接控制策略中固定开关频率的PWM电流控制因其算法简单、实现较为方便,得到了较好应用,在三相静止坐标系中,固定开关频率的PWM电流控制电流内环的稳态电流指令是一个正弦波信号,其电流指令的幅值信号来源于直流电压调节器的输出,频率和相位信号来源于电网;PI电流调节器不能实现电流无静差控制,且对有功电流和无功电流的独立控制很难实现。
异步电机矢量控制的数字化系统的设计与实现摘要:为了满足交流传动系统对异步电机控制的要求,根据异步电机的工作原理和矢量控制的原理,详细分析了空间矢量脉宽调制(svpwm)算法和控制实现方法,建立了以tms320f2812型dsp 为控制核心的异步电机矢量控制数字化实验平台,实现了对异步电机的高效控制。
实验结果表明,该数字化系统具有良好的性能,实现方法简单有效便于工程实际应用。
关键词:异步电机矢量控制空间矢量脉冲调制 tms320f28121 引言矢量控制以磁通这一旋转的空间矢量为参考坐标,利用从静止坐标系下的交流量变换到旋转坐标系下的直流量,可以将定子电流分为励磁电流与转矩电流进行分别控制,进而控制异步电机的转矩、转速[1],从而使电机的控制效果达到直流电机的控制效果。
本文采用基于转子磁场定向的矢量控制结合svpwm对异步电机进行控制[2,3]。
以三相对称正弦电压供电时的理想圆形磁通为基准,用逆变器不同开关模式进行组合,使实际磁通逼近基准磁通。
以tms320f2812型dsp为控制核心,进行了数字化异步电机调速控制系统的研究。
2 svpwm原理及实现2.1 svpwm原理交流电机的对称三相正弦供电电压所合成的电压矢量us是一个旋转的空间矢量,以角速度ω=2πf按逆时针方向匀速旋转。
逆变器三相桥臂共有6个开关管,为了研究不同开关组合时逆变器输出的空间电压矢量,定义开关函数 sx (x=a、b、c)为:(sa、sb、sc)的全部可能组合共有八个,6个非零矢量ul(001)、u2(010)、u3(011)、u4(100)、u5(101)、u6(110)和两个零矢量u0(000)、u7(111),如图1所示。
图 1 电压空间矢量图2.2电压空间时间作用时间的计算对于任意的电压矢量,可以通过某两个基本空间矢量来合成,以第一扇区为例:(2)其中ts为参考旋转电压矢量uref的作用时间,t1和t2分别为电压矢量u4和u6的作用时间,在αβ坐标系下有:(3)从上式可以得到,相邻电压空间矢量作用时间t1、t2。
基于TMS320F28335的SVPWM实现方法SVPWM/TMS320F28335/DSP/电机控制1引言随着电机控制理论的日趋成熟和微处理器的不断优化,脉宽调制(PWM)技术在变频器中得到了广泛的应用。
如今,PWM开关信号的控制方法最常见的有正弦脉宽调制(SPWM)和空间矢量脉宽调制(SVPWM)。
与SPWM方法相比,SVPWM方法具有电压谐波小,直流电压利用率高,电动机的动态响应快,减少电动机的转矩脉动,易于实现数字化等显著的优点,从而使SVPWM方法的实际应用愈来愈广泛[1,5]。
TMS320F28335数据信号处理器是TI公司最新推出的32位浮点DSP控制器,具有150MHz的高速处理能力,18路PWM输出,与TI前几代数字信号处理器相比,性能平均提高了50%,并可与定点C28x控制器软件兼容[2,3]。
其浮点运算单元,可以显著地提高控制系统的控制精度和处理器的运算速度,是目前控制领域最先进的处理器之一。
可以应用到参数辨识等需要大运算量的电机实时控制系统中。
以下介绍基于TMS320F28335的SVPWM基本原理和实现方法。
2 SVPWM的基本原理SVPWM是利用逆变器的功率开关器件的不同开关组合合成有效电压矢量来逼近基准圆[4.5]。
图1为三相电压源逆变器(VSI)的拓扑结构[2.3]。
图1三相电压型逆变器为便于分析理解,图1可以简化为图2所示。
图2三相电压型逆变器电路桥在图1中,V a、V b、V c是逆变器的输出相电压,Q1~Q6为6个功率开关晶体管,它们分别由a,a’,b,b’,c,c’个控制信号控制。
当逆变器上桥臂的一个功率开关晶体管开通状态(a或b 或c为1)时,下半桥臂的相对功率开关晶体管必须为关闭状态(a’或b’或c’为0);同理,当下桥臂开关晶体管为开通状态(a’或b’或c’为1)时上桥臂的相对功率开关晶体管必须为关闭状态(a或b或c为0)。
对于图1、图2所示的逆变器,其开关状态组合(c b a)有8种基本工作状态,即:000、001、010、011、100、101、110、111,其中除了000和111工作状态为无效状态,称为零矢量外,其余六种工作状态为有效状态,称为非零矢量。
基于霍尔信号的PMSM初始位置定位研究张英范;黄晓红;高军礼【摘要】针对现行永磁同步电机初始位置定位方法的缺陷,提出一种基于电压空间矢量原理生成高分辨率的脉冲电压.并结合复合式增量编码器的UVW信号,自动检测霍尔信号进行永磁同步电机初始位置定位的智能方法.通过自主开发的以数字信号处理器为核心的实验平台进行了功能验证,实现了永磁同步电机无机械冲击和最大转矩启动.【期刊名称】《广东轻工职业技术学院学报》【年(卷),期】2011(010)001【总页数】4页(P1-4)【关键词】复合式光电编码器;电压空间矢量;霍尔信号;永磁同步电机【作者】张英范;黄晓红;高军礼【作者单位】广东工业大学自动化学院,广东,广州,510006;广东轻工职业技术学院,广东,广州,510300;广东工业大学自动化学院,广东,广州,510006【正文语种】中文【中图分类】TP273+.2永磁同步电机 (PM SM)以其高效率、高动态性能、高精确度等一系列优点得到广泛的应用。
在永磁同步电机传动系统中,转子位置检测与初始位置定位是系统运行和矢量控制解耦的前提条件,只有准确知道永磁同步电机的转子位置,才可实现最大转矩启动。
用于永磁同步电机的转子位置检测的方法主要有脉冲电压注入法、高频信号注入法、高频电流注入法等,所采用传感器包括旋转变压器、光电编码器、电机内置位置传感器法和无位置传感器检测等[1]。
其中,脉冲电压注入法由于对齐过程中转子转向和转动范围的不确定性,转子产生较大的扭动和机械冲击,不适于精度高的场合[2];对于高频信号注入法,电机在低频或静止时,感应反电动势可观测性低,转子的磁极位置不易检测;高频电流注入法则利用永磁同步电机的凸性和磁路的饱和特性检测转子的初始位置,不适合于面装式永磁同步电机[3-4]。
在永磁同步电机无传感器检测方法中,基于反电势的直接计算法、基于观测器的估算法、模型参考自适应法这些方法理论上可以达到较高估算精度,但是在实际应用中还不够成熟,对电流、电压检测硬件电路要求较高,算法较复杂[5]。
SVPWM 算法在T MS320F2812上的实现王宏民,赵振民,李 娜(黑龙江科技学院电气与信息工程学院,哈尔滨150027)摘要:叙述了空间电压矢量脉宽调制(S VPW M )的基本原理、工程算法以及T MS320F2812特点,并给出该算法在T MS320F2812上所需硬件配置和软件流图,最后给出了实验结果。
实验结果表明与理论分析相符,并且这种在先进的高速控制芯片上实现控制算法的方法对控制伺服系统有良好的可靠应用性。
关键词:空间电压矢量;T MS320F2812;脉宽调制中图分类号:T M38315 文献标志码:A 文章编号:100320794(2008)1020042203Implementation Algorithm of V oltage SVPW M B ased on T MS320F2812WANG H ong -min ,ZH AO Zhen -min ,LI N a(C ollege of E lectric and In formation Engineering ,Heilongjiang Science and T echnology C ollege ,Harbin 150027,China )Abstract :Describes the principles and project alg orithm of the space vector pulse width m odulation (S VPW M ),and the advantages of T MS320F2812.Hardware configuration and s oftware flow chart based on T MS320F2812were introduced.The testing rusult indicates consistent with the theoretical analysis ,and the control alg orithm based on hige -speed chip run well in serv o control system.K ey w ords :v oltage space vector ;T MS320F2812;pulse width m odulation1 S VPW M 的基本原理S VPW M 是通过逆变器功率器件的不同开关模式产生有效电压矢量来逼近基准圆,图1是一个典型的电压源型PW M 逆变器模型。
第7章基于TMS320F2812的永磁同步电动机控制例1、空间矢量算法实现SVGEN_DQ对象结构体定义typedef struct {_iq Ualpha; // 输入:α轴参考电压_iq Ubeta; // 输入:β轴参考电压_iq Ta; // 输出:参考相位a开关函数_iq Tb; // 输出:参考相位b开关函数_iq Tc; // 输出:参考相位c开关函数void (*calc)(); // 函数指针} SVGENDQ;typedef SVGENDQ *SVGENDQ_handle;SVGEN_DQ模块调用方法:main(){}void interrupt periodic_interrupt_isr(){svgen_dq1.Ualpha = Ualpha1; // 提供输入参数:svgen_dq1svgen_dq1.Ubeta = Ubeta1; // 提供输入参数:svgen_dq1svgen_dq2.Ualpha = Ualpha2; // 提供输入参数:vgen_dq2svgen_dq2.Ubeta = Ubeta2; // 提供输入参数:svgen_dq2svgen_dq1.calc(&svgen_dq1); // 调用函数模块svgen_dq1svgen_dq2.calc(&svgen_dq2); // 调用函数模块svgen_dq2Ta1 = svgen_dq1.Ta; // 访问运算结果svgen_dq1Tb1 = svgen_dq1.Tb; // 访问运算结果svgen_dq1Tc1 = svgen_dq1.Tc; // 访问运算结果svgen_dq1Ta2 = svgen_dq2.Ta; // 访问运算结果svgen_dq2Tb2 = svgen_dq2.Tb; // 访问运算结果svgen_dq2Tc2 = svgen_dq2.Tc; // 访问运算结果svgen_dq2}为进一步了解空间矢量算法的基本原理,下面给出空间矢量模块的源代码:void svgendq_calc(SVGENDQ *v){_iq Va,Vb,Vc,t1,t2;_iq sector = 0; /*设相位置(sector)等于Q0 *//*逆clarke变换*/Va = v->Ubeta;Vb = _IQmpy(_IQ(-0.5),v->Ubeta) + _IQmpy(_IQ(0.8660254),v->Ualfa); /* 0.8660254 = sqrt(3)/2 */Vc = _IQmpy(_IQ(-0.5),v->Ubeta) - _IQmpy(_IQ(0.8660254),v->Ualfa); /* 0.8660254 = sqrt(3)/2 *//* 60度sector的确定*/if (Va>_IQ(0))sector = 1;if (Vb>_IQ(0))sector = sector + 2;if (Vc>_IQ(0))sector = sector + 4;/* X,Y,Z (Va,Vb,Vc)的计算*/Va = v->Ubeta; /* X = Va */Vb = _IQmpy(_IQ(0.5),v->Ubeta) + _IQmpy(_IQ(0.8660254),v->Ualfa); /* Y = Vb */Vc = _IQmpy(_IQ(0.5),v->Ubeta) - _IQmpy(_IQ(0.8660254),v->Ualfa); /* Z = Vc */if (sector==1) /* sector 1: t1=Z and t2=Y (abc ---> Tb,Ta,Tc) */{t1 = Vc;t2 = Vb;v->Tb = _IQmpy(_IQ(0.5),(_IQ(1)-t1-t2)); /* tbon = (1-t1-t2)/2 */v->Ta = v->Tb+t1; /* taon = tbon+t1 */v->Tc = v->Ta+t2; /* tcon = taon+t2 */}else if (sector==2) /* sector 2: t1=Y and t2=-X (abc ---> Ta,Tc,Tb) */{t1 = Vb;t2 = -Va;v->Ta = _IQmpy(_IQ(0.5),(_IQ(1)-t1-t2)); /* taon = (1-t1-t2)/2 */v->Tc = v->Ta+t1; /* tcon = taon+t1 */v->Tb = v->Tc+t2; /* tbon = tcon+t2 */}else if (sector==3) /* sector 3: t1=-Z and t2=X (abc ---> Ta,Tb,Tc) */{t1 = -Vc;t2 = Va;v->Ta = _IQmpy(_IQ(0.5),(_IQ(1)-t1-t2)); /* taon = (1-t1-t2)/2 */v->Tb = v->Ta+t1; /* tbon = taon+t1 */v->Tc = v->Tb+t2; /* tcon = tbon+t2 */}else if (sector==4) /* sector 4: t1=-X and t2=Z (abc ---> Tc,Tb,Ta) */{t1 = -Va;t2 = Vc;v->Tc = _IQmpy(_IQ(0.5),(_IQ(1)-t1-t2)); /* tcon = (1-t1-t2)/2 */v->Tb = v->Tc+t1; /* tbon = tcon+t1 */v->Ta = v->Tb+t2; /* taon = tbon+t2 */}else if (sector==5) /* sector 5: t1=X and t2=-Y (abc ---> Tb,Tc,Ta) */{t1 = Va;t2 = -Vb;v->Tb = _IQmpy(_IQ(0.5),(_IQ(1)-t1-t2)); /* tbon = (1-t1-t2)/2 */v->Tc = v->Tb+t1; /* tcon = tbon+t1 */v->Ta = v->Tc+t2; /* taon = tcon+t2 */}else if (sector==6) /* sector 6: t1=-Y and t2=-Z (abc ---> Tc,Ta,Tb) */{t1 = -Vb;t2 = -Vc;v->Tc = _IQmpy(_IQ(0.5),(_IQ(1)-t1-t2)); /* tcon = (1-t1-t2)/2 */v->Ta = v->Tc+t1; /* taon = tcon+t1 */v->Tb = v->Ta+t2; /* tbon = taon+t2 */}v->Ta = _IQmpy(_IQ(2),(v->Ta-_IQ(0.5)));v->Tb = _IQmpy(_IQ(2),(v->Tb-_IQ(0.5)));v->Tc = _IQmpy(_IQ(2),(v->Tc-_IQ(0.5)));}在相位置(sector)3中的一个矢量的例子:PWM1PWM3PWM5图相位置(sector)PWM 实例及其占空比例2、事件管理器配置EvaRegs.T1PR = p->n_period; /* SYSTEM_FREQUENCY*1000000*T/2 *//*初始化Timer 1周期寄存器*//* 预定标器X1 (T1),ISR周期= T x 1 */ EvaRegs.T1CON.all = PWM_INIT_STATE; /* 对称操作模式*/ EvaRegs.DBTCONA.all = DBTCON_INIT_STATE;EvaRegs.ACTRA.all = ACTR_INIT_STATE;CONA.all = 0xA200;EvaRegs.CMPR1 = p->n_period;EvaRegs.CMPR2 = p->n_period;EvaRegs.CMPR3 = p->n_period;EALLOW;GpioMuxRegs.GPAMUX.all |= 0x003F;例3、TMS320F2812电流及DC母线电压检测//******************************************************************************// TMS320F2812电流及DC母线电压检测// 文件名称:F28XILEG_VDC.C//****************************************************************************** #include "DSP28_Device.h"#include "f28xileg_vdc.h"#include "f28xbmsk.h"#define CPU_CLOCK_SPEED 6.6667L // CPU时钟速度150MHz#define ADC_usDELAY 5000L#define DELAY_US(A) DSP28x_usDelay(((((long double) A * 1000.0L)/ (long double)CPU_CLOCK_SPEED) - 9.0L) / 5.0L) extern void DSP28x_usDelay(unsigned long Count);void F28X_ileg2_dcbus_drv_init(ILEG2DCBUSMEAS *p){DELAY_US(ADC_usDELAY);AdcRegs.ADCTRL1.all = ADC_RESET_FLAG; /*复位ADC模块*/asm(" NOP ");asm(" NOP ");AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0x3; /* 为bandgap和参考电路供电*/DELAY_US(ADC_usDELAY); /*为ADC其他单元上电前延时*/AdcRegs.ADCTRL3.bit.ADCPWDN = 1; /*为ADC其他单元上电*/AdcRegs.ADCTRL3.bit.ADCCLKPS = 3; /* 设置ADCTRL3寄存器*/DELAY_US(ADC_usDELAY);AdcRegs.ADCTRL1.all = ADCTRL1_INIT_STATE; /*设置ADCTRL1寄存器*/AdcRegs.ADCTRL2.all = ADCTRL2_INIT_STATE; /*设置ADCTRL2寄存器*/AdcRegs.ADCMAXCONV.bit.MAX_CONV = 2; /* 确定3个转换*/AdcRegs.ADCCHSELSEQ1.all = p->Ch_sel; /* 配置通道选择*/EvaRegs.GPTCONA.bit.T1TOADC = 1; /*设置采用Timer1 UF触发ADC转换*/ }void F28X_ileg2_dcbus_drv_read(ILEG2DCBUSMEAS *p){int dat_q15;long tmp;/* 等待ADC转换结束*/while (AdcRegs.ADCST.bit.SEQ1_BSY == 1){};dat_q15 = AdcRegs.ADCRESULT0^0x8000; /*将转换结果变成Q15格式双极性数据*/tmp = (long)(p->Imeas_a_gain*dat_q15);p->Imeas_a = (int)(tmp>>13);p->Imeas_a += p->Imeas_a_offset;p->Imeas_a *= -1; /*正向,电流流向电动机*/dat_q15 = AdcRegs.ADCRESULT1^0x8000; /*将转换结果变成Q15格式双极性数据*/tmp = (long)(p->Imeas_b_gain*dat_q15);p->Imeas_b = (int)(tmp>>13);p->Imeas_b += p->Imeas_b_offset;p->Imeas_b *= -1; /*正向,电流流向电动机*/dat_q15 = (AdcRegs.ADCRESULT2>>1)&0x7FFF; /*将转换结果变成Q15格式双极性数据*/tmp = (long)(p->Vdc_meas_gain*dat_q15);p->Vdc_meas = (int)(tmp>>13);p->Vdc_meas += p->Vdc_meas_offset;p->Imeas_c = -(p->Imeas_a + p->Imeas_b);AdcRegs.ADCTRL2.all |= 0x4040; /* 复位排序器*/}例4、电动机位置检测/******************************************************************************// TMS320F2812电动机位置检测QEP电路初始化及应用// 文件名称:F28XQEP.C//******************************************************************************#include "DSP28_Device.h"#include "f28xqep.h"#include "f28xbmsk.h"void F28X_EV1_QEP_Init(QEP *p){EvaRegs.CAPCON.all = QEP_CAP_INIT_STATE; /*设置捕捉单元*/EvaRegs.T2CON.all = QEP_TIMER_INIT_STATE; /*设置捕捉定时器*/EvaRegs.T2PR = 0xFFFF;EvaRegs.EV AIFRC.bit.CAP3INT = 1; /*清除CAP3标志*/EvaRegs.EV AIMRC.bit.CAP3INT = 1; /*使能CAP3中断*/GpioMuxRegs.GPAMUX.all |= 0x0700; /*配置捕捉单元的引脚*/}void F28X_EV1_QEP_Calc(QEP *p){long tmp;p->dir_QEP = 0x4000&EvaRegs.GPTCONA.all;p->dir_QEP = p->dir_QEP>>14;p->theta_raw = EvaRegs.T2CNT + p->cal_angle;tmp = (long)(p->theta_raw*p->mech_scaler); /* Q0*Q26 = Q26 */tmp &= 0x03FFF000;p->theta_mech = (int)(tmp>>11); /* Q26 -> Q15 */p->theta_mech &= 0x7FFF;p->theta_elec = p->pole_pairs*p->theta_mech; /* Q0*Q15 = Q15 */p->theta_elec &= 0x7FFF;}void F28X_EV1_QEP_Isr(QEP *p){p->QEP_cnt_idx = EvaRegs.T2CNT;EvaRegs.T2CNT = 0;p->index_sync_flag = 0x00F0;}//****************************************************************************** // TMS320F2812电动机位置检测QEP电路初始化参数及函数定义// 文件名称:F28XQEP.H//******************************************************************************#ifndef __F28X_QEP_H__#define __F28X_QEP_H__#include "f28xbmsk.h"/* 初始化T2CON和CAPCON */#define QEP_CAP_INIT_STATE 0x9004#define QEP_TIMER_INIT_STATE (FREE_RUN_FLAG + \TIMER_DIR_UPDN + \TIMER_CLK_PRESCALE_X_1 + \TIMER_ENABLE_BY_OWN + \TIMER_ENABLE + \TIMER_CLOCK_SRC_QEP + \TIMER_COMPARE_LD_ON_ZERO)/* 定义QEP (正交编码电路) 驱动的对象*/typedef struct {int theta_elec; /* 输出: 电动机电角度(Q15) */ int theta_mech; /* 输出: 电动机机械角度(Q15) */int dir_QEP; /* 输出: 电动机转动方向(Q0) */int QEP_cnt_idx; /* 变量: 编码器计数(Q0) */int theta_raw; /* 变量: 定时器2得出的角度(Q0) */int mech_scaler; /* 参数: 0.9999/计数最大值,计数最大值= 4000 (Q26) */int pole_pairs; /* 参数: 极对数(Q0) */int cal_angle; /* 参数: 编码器和相之间的角度偏移量(Q0) */int index_sync_flag; /* 输出: Index sync status (Q0) */void (*init)(); /* 初始化函数指针*/void (*calc)(); /* 计算函数指针*/void (*isr)(); /* 中断程序指针*/} QEP;/* 定义一个QEP_handle */typedef QEP *QEP_handle;#define QEP_DEFAULTS { 0x0, 0x0,0x0,0x0,0x0,16776,2,-2365,0x0, \(void (*)(long))F28X_EV1_QEP_Init, \(void (*)(long))F28X_EV1_QEP_Calc, \(void (*)(long))F28X_EV1_QEP_Isr }void F28X_EV1_QEP_Init(QEP_handle);void F28X_EV1_QEP_Calc(QEP_handle);void F28X_EV1_QEP_Isr(QEP_handle);#endif /* __F28X_QEP_H__ */例5、TMS320F2812实现三相永磁同步电动机的磁场定向控制//****************************************************************************** // 采用TMS320F2812实现三相永磁同步电动机的磁场定向控制// 文件名称:PMSM3_1.C//****************************************************************************** //初始化程序#include "IQmathLib.h" /* 包含IQmath库函数的头文件*/#include "DSP28_Device.h"#include "pmsm3_1.h"#include "parameter.h"#include "build.h"// 函数声明interrupt void EvaTimer1(void);interrupt void EvaTimer2(void);// 全局变量定义float Vd_testing = 0; /* Vd testing (pu) */float Vq_testing = 0.25; /* Vq testing (pu) */float Id_ref = 0; /* Id reference (pu) */float Iq_ref = 0.4; /* Iq reference (pu) */float speed_ref = 0.2; /* Speed reference (pu) */float T = 0.001/ISR_FREQUENCY; /* Samping period (sec), see parameter.h */int isr_ticker = 0;int pwmdac_ch1=0;int pwmdac_ch2=0;int pwmdac_ch3=0;volatile int enable_flg=0;int lockrtr_flg=1;int speed_loop_ps = 10; // 速度环定标器int speed_loop_count = 1; // 速度环计数器CLARKE clarke1 = CLARKE_DEFAULTS;PARK park1 = PARK_DEFAULTS;IPARK ipark1 = IPARK_DEFAULTS;PIDREG3 pid1_id = PIDREG3_DEFAULTS;PIDREG3 pid1_iq = PIDREG3_DEFAULTS;PIDREG3 pid1_spd = PIDREG3_DEFAULTS;PWMGEN pwm1 = PWMGEN_DEFAULTS;PWMDAC pwmdac1 = PWMDAC_DEFAULTS;SVGENDQ svgen_dq1 = SVGENDQ_DEFAULTS;QEP qep1 = QEP_DEFAULTS;SPEED_MEAS_QEP speed1 = SPEED_MEAS_QEP_DEFAULTS; DRIVE drv1 = DRIVE_DEFAULTS;RMPCNTL rc1 = RMPCNTL_DEFAULTS;RAMPGEN rg1 = RAMPGEN_DEFAULTS;ILEG2DCBUSMEAS ilg2_vdc1 = ILEG2DCBUSMEAS_DEFAULTS;// 主函数void main(void){// 系统初始化InitSysCtrl();// HISPCP 设置EALLOW;SysCtrlRegs.HISPCP.all = 0x0000; /* SYSCLKOUT/1 */ EDIS;// 禁止并清除所有CPU中断:DINT;IER = 0x0000;IFR = 0x0000;// 初始化Pie到默认状态InitPieCtrl();// 初始化PIE相量表InitPieVectTable();// 初始化EV A 定时器1://设置定时器1寄存器(EV A)EvaRegs.GPTCONA.all = 0;//等待使能标志位while (enable_flg==0){// 使能定时器1的下溢中断EvaRegs.EV AIMRA.bit.T1UFINT = 1;EvaRegs.EV AIFRA.bit.T1UFINT = 1;// 使能CAP3中断(定时器2)EvaRegs.EV AIMRC.bit.CAP3INT = 1;EvaRegs.EV AIMRC.bit.CAP3INT = 1;};// 重新分配中断向量EALLOW;PieVectTable.T1UFINT = &EvaTimer1;PieVectTable.CAPINT3 = &EvaTimer2;EDIS;// 使能PIE组2的中断6(T1UFINT)PieCtrlRegs.PIEIER2.all = M_INT6;// 使能PIE组3的中断7(CAPINT3)PieCtrlRegs.PIEIER3.all = M_INT7;// 使能CPU INT2(T1UFINT)和INT3(CAPINT3):IER |= (M_INT2 | M_INT3);// 使能全局中断和最高优先级适时调试事件管理器功能:EINT; //使能全局中断INTMERTM; // 使能适时调试中断DBGM/* 模块初始化*/pwm1.n_period = SYSTEM_FREQUENCY*1000000*T/2; /* 预定标器X1 (T1), ISR周期= T x 1 */ pwm1.init(&pwm1);pwmdac1.pwmdac_period = 2500; /* PWM频率= 30 kHz */pwmdac1.PWM_DAC_IPTR0 = &pwmdac_ch1;pwmdac1.PWM_DAC_IPTR1 = &pwmdac_ch2;pwmdac1.PWM_DAC_IPTR2 = &pwmdac_ch3;pwmdac1.init(&pwmdac1);qep1.init(&qep1);drv1.init(&drv1);ilg2_vdc1.init(&ilg2_vdc1);/* 初始化SPEED_FRQ模块*/speed1.K1 = _IQ21(1/(BASE_FREQ*T));speed1.K2 = _IQ(1/(1+T*2*PI*30)); /* 低通截至频率= 30 Hz */speed1.K3 = _IQ(1)-speed1.K2;speed1.rpm_max = 120*BASE_FREQ/P;/*初始化RAMPGEN模块*/rg1.step_angle_max = _IQ(BASE_FREQ*T);/* 初始化PID_REG3 Id调节模块*/pid1_id.Kp_reg3 = _IQ(0.75);pid1_id.Ki_reg3 = _IQ(T/0.0005);pid1_id.Kd_reg3 = _IQ(0/T);pid1_id.Kc_reg3 = _IQ(0.2);pid1_id.pid_out_max = _IQ(0.30);pid1_id.pid_out_min = _IQ(-0.30);/* 初始化PID_REG3 Iq调节模块*/pid1_iq.Kp_reg3 = _IQ(0.75);pid1_iq.Ki_reg3 = _IQ(T/0.0005);pid1_iq.Kd_reg3 = _IQ(0/T);pid1_iq.Kc_reg3 = _IQ(0.2);pid1_iq.pid_out_max = _IQ(0.95);pid1_iq.pid_out_min = _IQ(-0.95);/*初始化PID_REG3 速度调节模块*/pid1_spd.Kp_reg3 = _IQ(1);pid1_spd.Ki_reg3 = _IQ(T*speed_loop_ps/0.1);pid1_spd.Kd_reg3 = _IQ(0/(T*speed_loop_ps));pid1_spd.Kc_reg3 = _IQ(0.2);pid1_spd.pid_out_max = _IQ(1);pid1_spd.pid_out_min = _IQ(-1);// 循环等待for(;;);}interrupt void EvaTimer1(void){isr_ticker++;if (speed_loop_count==speed_loop_ps){11pid1_spd.pid_ref_reg3 = _IQ(speed_ref);pid1_spd.pid_fdb_reg3 = speed1.speed_frq;pid1_spd.calc(&pid1_spd);speed_loop_count=1;}else speed_loop_count++;pid1_iq.pid_ref_reg3 = pid1_spd.pid_out_reg3;pid1_iq.pid_fdb_reg3 = park1.qe;pid1_iq.calc(&pid1_iq);pid1_id.pid_ref_reg3 = _IQ(Id_ref);pid1_id.pid_fdb_reg3 = park1.de;pid1_id.calc(&pid1_id);ipark1.de = pid1_id.pid_out_reg3;ipark1.qe = pid1_iq.pid_out_reg3;ipark1.ang = speed1.theta_elec;ipark1.calc(&ipark1);svgen_dq1.Ualfa = ipark1.ds;svgen_dq1.Ubeta = ipark1.qs;svgen_dq1.calc(&svgen_dq1);pwm1.Mfunc_c1 = (int)_IQtoIQ15(svgen_dq1.Ta); /* Mfunc_c1 is in Q15 */pwm1.Mfunc_c2 = (int)_IQtoIQ15(svgen_dq1.Tb); /* Mfunc_c2 is in Q15 */pwm1.Mfunc_c3 = (int)_IQtoIQ15(svgen_dq1.Tc); /* Mfunc_c3 is in Q15 */pwm1.update(&pwm1);ilg2_vdc1.read(&ilg2_vdc1);clarke1.as = _IQ15toIQ((long)ilg2_vdc1.Imeas_a);clarke1.bs = _IQ15toIQ((long)ilg2_vdc1.Imeas_b);clarke1.calc(&clarke1);park1.ds = clarke1.ds;park1.qs = clarke1.qs;park1.ang = speed1.theta_elec;park1.calc(&park1);qep1.calc(&qep1);speed1.theta_elec = _IQ15toIQ((long)qep1.theta_elec);speed1.dir_QEP = (long)(qep1.dir_QEP);12speed1.calc(&speed1);pwmdac_ch1 = (int)_IQtoIQ15(svgen_dq1.Ta);pwmdac_ch2 = (int)_IQtoIQ15(clarke1.as);pwmdac_ch3 = (int)_IQtoIQ15(speed1.theta_elec);drv1.enable_flg = enable_flg;drv1.update(&drv1);pwmdac1.update(&pwmdac1);// 使能定时器中断EvaRegs.EV AIMRA.bit.T1UFINT = 1;EvaRegs.EV AIFRA.all = BIT9;PieCtrlRegs.PIEACK.all |= PIEACK_GROUP2;}interrupt void EvaTimer2(void){qep1.isr(&qep1);EvaRegs.EV AIMRC.bit.CAP3INT = 1;EvaRegs.EV AIFRC.all = BIT2;PieCtrlRegs.PIEACK.all |= PIEACK_GROUP3;}具体参考《零基础学TMS320F281xDSP C语言开发》,与书上重合率很高。
课程设计任务书电气与信息工程系自动化专业班题目转速闭环转差频率控制的变压变频调速系统设计任务起止日期:2016 年 6 月 6 日~ 2016年6月17日学生姓名学号指导教师一、设计要求:设计一个转速闭环转差频率控制的变压变频调速系统:系统包括速度设定、速度显示、速度测量、速度控制、正反转控制等,且根据交流异步电动机的容量采用由三相二极管整流桥、电容滤波、基于全控型开关器件 IGBT 或 MOSFET 的三相 PWM 逆变桥构成的主电路给异步电动机供电。
已知:(1)异步电动机:额定容量 PN =3KW ,额定电压 UN =380V ,额定电流 IN =6.9A ,额定转速为 nN =1400 r/min,额定频率 fN =50Hz ,定子绕组 Y 联接。
由实验测得定子电阻 Rs =Ω,转子电阻 Rr =Ω,定子自感 Ls =,转子自感 L r = ,定、转子互感 L m =,转子参数已折算到定子侧,系统转动惯量J =0.1284kg.m2。
(2)变频电源主要技术指标:1)输入电压额定值:三相、380VAC 、50Hz,2)效率: 80%以上,3)额定输出容量: 4KVA 或 250VA ,4)额定输出电压:三相、380VAC ,5)输出频率: 5~400Hz,6)控制方式:转速闭环转差频率控制方式,SPWM 或 SVPWM 脉冲产生方式。
二、设计任务:1、绘出异步电动机T 型等效电路和简化等效电路;2、求额定运行时的转差率、定子额定电流和额定定子转矩;3、定子电压和频率均为额定值时,求空载时的额定电流;4、定子电压和频率均为额定值时,求临界转差率和临界转矩,绘出异步电动机的机械特性;5、完成系统电气原理图的设计三、设计说明书的格式要求:1、绪论a. 设计的目的和意义。
b. 设计要求。
c. 设计对象及有关数据。
2、系统结构方案的选择:3、系统结构及性能分析4、主回路的选择。
5、触发器的设计和同步相位的配合: a. 触发电路的设计与选择。
TMS320F2812在电机控制系统的应用1 引言在电机控制领域,TI公司推出2000系列电机控制DSP。
TMS320F2812属于最新高端产品,适合工业控制、机床控制等高精度应用。
目前2000系列芯片在电气传动中的应用以TMS320LF240x为主,应用TMS320F(C)28x的比较少。
但28x比24x系列的DSP具有更完备的外围控制接口和更丰富的电机控制外设电路,更高的主频,指令执行时间仅为6.67ns,流水线采样最高速率60ns,12位A/D转换通道16个,PWM输出通道12个。
资源足够同时控制两台三相电机,使控制系统价格大大降低而体积缩小、可靠性提高,可在高度集成的环境中实现高性能电机控制。
电机控制系统基本结构见图1,本文阐述基于TMS320F2812的DSP电机控制系统设计中的重点。
图1 电机控制系统结构原理图2 引导加载ROM引导加载是指器件复位时执行一段引导程序,一般用于从端口(异步串口、I/O口或HPI 主机接口)将EPROM/FLASH等非易失性存储器中加载程序到高速RAM 中。
2.1 TMS320 812的启动模式TMS320F2812提供了几种不同的启动模式,四个通用I/O引脚用于确定选择何种启动模式,如表1所示。
2.2 SCI SPI启动加载器通过SPI同步传输和SCI异步传输实现FLASHROM引导加载。
硬件电路见图2,JP15为SPI或SCI引导加载器选择,1—2时选择SPI,2—3时选择SCI;JP4是SPI数据传输路径的选择,位于1—2时,连接至外部扩展接口J6或串行ROM,位于2—3时连接至J5仿真数据传输接口。
图2 SCI SPI启动加载器3 A/D转换模块TMS320F2812电机控制芯片内部集成了16路12位A/D转换模块,模拟量信号采样输入范围是0~ 3.3V,16路A/D通道分为两组,AD0~AD7为一组,AD8~AD15为一组。
每组都有一个专门输入端。
基于TMS320F2812的三相SPWM波的实现一、PWM的简介与发展脉宽调制(PWM:(Pulse Width Modulation)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
简而言之,PWM是一种对模拟信号电平进行数字编码的方法。
通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。
PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。
电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。
通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。
只要带宽足够,任何模拟值都可以使用PWM进行编码。
PWM的一个优点是从处理器到被控系统信号都是数字形式的,无需进行数模转换。
让信号保持为数字形式可将噪声影响降到最小。
噪声只有在强到足以将逻辑1改变为逻辑0或将逻辑0改变为逻辑1时,也才能对数字信号产生影响。
对噪声抵抗能力的增强是PWM相对于模拟控制的另外一个优点,而且这也是在某些时候将PWM用于通信的主要原因。
从模拟信号转向PWM可以极大地延长通信距离。
在接收端,通过适当的RC或LC网络可以滤除调制高频方波并将信号还原为模拟形式。
PWM控制技术一直是变频技术的核心技术之一。
1964年A.Schonung和H.stemmler 首先提出把这项通讯技术应用到交流传动中,从此为交流传动的推广应用开辟了新的局面。
从最初采用模拟电路完成三角调制波和参考正弦波比较,产生正弦脉宽调制SPWM信号以控制功率器件的开关开始,到目前采用全数字化方案,完成优化的实时在线的PWM信号输出,可以说直到目前为止,PWM在各种应用场合仍在主导地位,并一直是人们研究的热点。
由于PWM可以同时实现变频变压反抑制谐波的特点。
由此在交流传动及至其它能量变换系统中得到广泛应用。
基于TMS320F28035的永磁同步电机矢量控制系统研究赵森;李迪;王世勇【摘要】基于实现永磁同步电机伺服系统矢量控制,得到良好的系统动态响应的目的,采用以TMS320F28035为控制核心的全数字DSP速度控制方案,通过硬、软件设计、参数整定以及波形图分析,实验结果表明,该系统电流跟踪性能提升10%,稳态精度提升15%.【期刊名称】《电子设计工程》【年(卷),期】2014(022)024【总页数】4页(P120-123)【关键词】永磁同步电机;TMS320F28035;矢量控制系统;速度控制【作者】赵森;李迪;王世勇【作者单位】华南理工大学机械与汽车工程学院,广东广州510640;华南理工大学机械与汽车工程学院,广东广州510640;华南理工大学机械与汽车工程学院,广东广州510640【正文语种】中文【中图分类】TN492永磁同步电动机(PMSM)具有体积小、重量轻、结构多样、可靠性高等优点。
在数控机床、工业机器人等自动化领域得到了广泛的应用。
数字化交流伺服调速系统采用的是目前非常流行的矢量控制算法,即电压空间矢量脉宽调制[1](SVPWM)。
SVPWM的主要思想是:以三相对称正弦波电压供电时三相对称电动机定子理想磁链圆为参考标准,以三相逆变器不同开关模式作适当的切换,从而形成脉宽调制(PWM)波,以所形成的实际磁链矢量来追踪其准确磁链圆[2]。
由于矢量控制算法对采集PMSM转子的电流、电压等参数的实时性要求很高,且计算量大,一般的微处理器很难达到要求。
因此,文中采用TI公司C2000系列高压数字电机开发套件,利用其DSP芯片TMS320F28035高速数据处理能力,使得整个电机控制系统具有控制精度高,实时性强的特点。
1 系统结构针对永磁同步电机高阶、多变量、非线性、强耦合的控制特点,如何有效解耦进而实现直流电机般的转矩控制方式,一直以来都是主要的研究热点。
永磁同步电机的转子机械位置和磁通位置的一致性,决定了其实现矢量控制方面的优越性。
/*====================================================================== ========System Name: PMSM34File Name: PMSM3_4.CDescription: Primary system file for the Real Implementation of Position ControlBased Sensored Field Orientation Control for a Three Phase Permanent-Magnet Synchronous Motor (PMSM) using QEP sensorOriginator: Digital control systems Group - Texas InstrumentsNote: In this software, the default inverter is supposed to be DMC550 board.====================================================================== ===============History:-------------------------------------------------------------------------------------04-15-2005 Version 3.20: Support both F280x and F281x targets04-25-2005 Version 3.21: Move EINT and ERTM down to ensure that all initializationis completed before interrupts are allowed.====================================================================== =========== */// Include header files used in the main function#include "target.h"#include "DSP281x_Device.h"#include "IQmathLib.h"#include "pmsm3_4.h"#include "parameter.h"#include "build.h"#include <math.h>// Prototype statements for functions found within this file.interrupt void MainISR(void);interrupt void QepISR(void);interrupt void PDPINTAISR(void);// Global variables used in this systemfloat32 VdTesting = 0; // Vd testing (pu)float32 VqTesting = 0.25; // Vq testing (pu)float32 IdRef = 0; // Id reference (pu)float32 IqRef = 0.2; // Iq reference (pu)float32 SpeedRef = 0.1; // Speed reference (pu)float32 PositionRef = 0.5; // Position reference (Mechanical rotor Anglele (pu) float32 T = 0.001/ISR_FREQUENCY; // Samping period (sec), see parameter.hUint16 IsrTicker = 0;Uint16 BackTicker = 0;volatile Uint16 EnableFlag = FALSE;Uint16 LockRotorFlag = FALSE;Uint16 SpeedLoopPrescaler = 10; // Speed loop prescalerUint16 SpeedLoopCount = 1; // Speed loop counter// Instance a few transform objectsCLARKE clarke1 = CLARKE_DEFAULTS;PARK park1 = PARK_DEFAULTS;IPARK ipark1 = IPARK_DEFAULTS;// Instance PID regulators to regulate the d and q synchronous axis currents,// speed and positionPIDREG3 pid1_id = PIDREG3_DEFAULTS;PIDREG3 pid1_iq = PIDREG3_DEFAULTS;PIDREG3 pid1_pos = PIDREG3_DEFAULTS;PIDREG3 pid1_spd = PIDREG3_DEFAULTS;// Instance a PWM driver instancePWMGEN pwm1 = PWMGEN_DEFAULTS;// Instance a Space Vector PWM modulator. This modulator generates a, b and c// phases based on the d and q stationery reference frame inputsSVGENDQ svgen_dq1 = SVGENDQ_DEFAULTS;// Instance a QEP interface driverQEP qep1 = QEP_DEFAULTS;// Instance a speed calculator based on QEPSPEED_MEAS_QEP speed1 = SPEED_MEAS_QEP_DEFAULTS;// Instance a ramp controller to smoothly ramp the frequencyRMPCNTL rc1 = RMPCNTL_DEFAULTS;// Instance a ramp generator to simulate an AngleleRAMPGEN rg1 = RAMPGEN_DEFAULTS;// Create an instance of the current/dc-bus voltage measurement driverILEG2DCBUSMEAS ilg2_vdc1 = ILEG2DCBUSMEAS_DEFAULTS;void main(void){// ******************************************// Initialization code for DSP_TARGET = F2812// ******************************************// Initialize System Control registers, PLL, WatchDog, Clocks to default state: // This function is found in the DSP281x_SysCtrl.c file.InitSysCtrl();// HISPCP prescale register settings, normally it will be set to default values EALLOW; // This is needed to write to EALLOW protected registers SysCtrlRegs.HISPCP.all = 0x0000; // SYSCLKOUT/1EDIS; // This is needed to disable write to EALLOW protected registers// Disable and clear all CPU interrupts:DINT;IER = 0x0000;IFR = 0x0000;// Initialize Pie Control Registers To Default State:// This function is found in the DSP281x_PieCtrl.c file.InitPieCtrl();// Initialize the PIE Vector Table To a Known State:// This function is found in DSP281x_PieVect.c.// This function populates the PIE vector table with pointers// to the shell ISR functions found in DSP281x_DefaultIsr.c.InitPieVectTable();//Initialize GPIO;MUX为0,表示IO;MUX为1表示外围;//DIR为0,表示输入;DIR为1表示输出EALLOW;GpioMuxRegs.GPAMUX.all=0X073F;GpioMuxRegs.GPADIR.all=0XC0C0;GpioMuxRegs.GPBMUX.all=0X0000;GpioMuxRegs.GPBDIR.all=0X0000;GpioMuxRegs.GPDMUX.bit.T1CTRIP_PDPA_GPIOD0=1; //功能PDPINTA GpioMuxRegs.GPDMUX.bit.T2CTRIP_SOCA_GPIOD1=0; // INPUTGpioMuxRegs.GPDDIR.bit.GPIOD1=0;GpioMuxRegs.GPDMUX.bit.T3CTRIP_PDPB_GPIOD5=0;GpioMuxRegs.GPDDIR.bit.GPIOD5=0;GpioMuxRegs.GPDMUX.bit.T4CTRIP_SOCB_GPIOD6=0;GpioMuxRegs.GPDDIR.bit.GPIOD6=0;GpioMuxRegs.GPEMUX.bit.XINT1_XBIO_GPIOE0=0;GpioMuxRegs.GPEMUX.bit.XINT2_ADCSOC_GPIOE1=0;GpioMuxRegs.GPEMUX.bit.XNMI_XINT13_GPIOE2=0;GpioMuxRegs.GPEDIR.bit.GPIOE0=0;GpioMuxRegs.GPEDIR.bit.GPIOE1=0;GpioMuxRegs.GPEDIR.bit.GPIOE2=0;GpioMuxRegs.GPFMUX.all=0X4037;GpioMuxRegs.GPFDIR.all=0X01C8;GpioMuxRegs.GPGMUX.bit.SCITXDB_GPIOG4=0;GpioMuxRegs.GPGMUX.bit.SCIRXDB_GPIOG5=0;GpioMuxRegs.GPGDIR.bit.GPIOG4=1;GpioMuxRegs.GPGDIR.bit.GPIOG5=1;EDIS;// User specific functions, Reassign vectors (optional), Enable Interrupts:// Initialize EV A Timer 1:// Setup Timer 1 Registers (EV A)EvaRegs.GPTCONA.all = 0;// Waiting for enable flag setwhile (EnableFlag==FALSE){BackTicker++;}// Enable Underflow interrupt bits for GP timer 1EvaRegs.EVAIMRA.bit.T1UFINT = 1;EvaRegs.EVAIFRA.bit.T1UFINT = 1;// Enable CAP3 interrupt bits for GP timer 2EvaRegs.EVAIMRC.bit.CAP3INT = 1;EvaRegs.EVAIFRC.bit.CAP3INT = 1;// Reassign ISRs.// Reassign the PIE vector for T1UFINT and CAP3INT to point to a different// ISR then the shell routine found in DSP281x_DefaultIsr.c.// This is done if the user does not want to use the shell ISR routine// but instead wants to use their own ISR.EALLOW; // This is needed to write to EALLOW protected registersPieVectTable.T1UFINT = &MainISR;PieVectTable.CAPINT3 = &QepISR;PieVectTable.PDPINTA = &PDPINTAISR;EDIS; // This is needed to disable write to EALLOW protected registers// Enable PIE group 2 interrupt 6 for T1UFINTPieCtrlRegs.PIEIER2.all = M_INT6;// Enable PIE group 3 interrupt 7 for CAP3INTPieCtrlRegs.PIEIER3.all = M_INT7;// Enable PIE group 1 interrupt 1 for PDPINTAPieCtrlRegs.PIEIER1.all = M_INT1;// Enable CPU INT2 for T1UFINT and INT3 for CAP3INT:IER |= (M_INT2 | M_INT3 | M_INT1);// Initialize PWM modulepwm1.PeriodMax = SYSTEM_FREQUENCY*1000000*T/2; // Perscaler X1 (T1), ISR period = T x 1pwm1.init(&pwm1);// Initialize QEP moduleqep1.LineEncoder = 2000;qep1.MechScaler = _IQ30(0.25/qep1.LineEncoder);qep1.PolePairs = P/2;qep1.CalibratedAngle = -1250;qep1.init(&qep1);// Initialize the Speed module for QEP based speed calculationspeed1.K1 = _IQ21(1/(BASE_FREQ*T));speed1.K2 = _IQ(1/(1+T*2*PI*30)); // Low-pass cut-off frequencyspeed1.K3 = _IQ(1)-speed1.K2;speed1.BaseRpm = 120*(BASE_FREQ/P);// Initialize ADC module// Note for DMC550:// - At 24 dc-bus volt, the ADC input for measured Vdc_bus range is 24*1/(24.9+1) = 0.927 volt // - Then, Vdc_bus gain = 3.0/0.927 = 3.2375 (or 0x675C in Q13)ilg2_vdc1.VdcMeasGain = 0x675C;ilg2_vdc1.ChSelect = 0x0610;ilg2_vdc1.init(&ilg2_vdc1);// Initialize the RAMPGEN modulerg1.StepAngleMax = _IQ(BASE_FREQ*T);// Initialize the RAMPGEN modulerc1.RampDelayMax = 5;// Initialize the PID_REG3 module for Idpid1_id.Kp = _IQ(0.1);pid1_id.Ki = _IQ(T/0.02);pid1_id.Kd = _IQ(0/T);pid1_id.Kc = _IQ(0.5);pid1_id.OutMax = _IQ(0.30);pid1_id.OutMin = _IQ(-0.30);// Initialize the PID_REG3 module for Iqpid1_iq.Kp = _IQ(0.1);pid1_iq.Ki = _IQ(T/0.02);pid1_iq.Kd = _IQ(0/T);pid1_iq.Kc = _IQ(0.5);pid1_iq.OutMax = _IQ(0.95);pid1_iq.OutMin = _IQ(-0.95);// Initialize the PID_REG3 module for speed controlpid1_spd.Kp = _IQ(1);pid1_spd.Ki = _IQ(T*SpeedLoopPrescaler/0.3);pid1_spd.Kd = _IQ(0/(T*SpeedLoopPrescaler));pid1_spd.Kc = _IQ(0.2);pid1_spd.OutMax = _IQ(1);pid1_spd.OutMin = _IQ(-1);// Initialize the PID_REG3 module for position controlpid1_pos.Kp = _IQ(28.2);pid1_pos.Ki = _IQ(0); // Integral term is not usedpid1_pos.Kd = _IQ(0); // Derivative term is not usedpid1_pos.Kc = _IQ(0);pid1_pos.OutMax = _IQ(1);pid1_pos.OutMin = _IQ(-1);// Enable global Interrupts and higher priority real-time debug events:EINT; // Enable Global interrupt INTMERTM; // Enable Global realtime interrupt DBGM// IDLE loop. Just sit and loop forever:for(;;) BackTicker++;}interrupt void MainISR(void){// Verifying the ISRIsrTicker++;// ***************** LEVEL1 *****************#if (BUILDLEVEL==LEVEL1)// ------------------------------------------------------------------------------// Connect inputs of the RMP module and call the Ramp control// calculation function.// ------------------------------------------------------------------------------rc1.TargetValue = _IQ(SpeedRef);rc1.calc(&rc1);// ------------------------------------------------------------------------------// Connect inputs of the RAMP GEN module and call the Ramp generator// calculation function.// ------------------------------------------------------------------------------rg1.Freq = rc1.SetpointValue;rg1.calc(&rg1);// ------------------------------------------------------------------------------// Connect inputs of the INV_PARK module and call the inverse park transformation // calculation function.// ------------------------------------------------------------------------------ipark1.Ds = _IQ(VdTesting);ipark1.Qs = _IQ(VqTesting);ipark1.Angle = rg1.Out;ipark1.calc(&ipark1);// ------------------------------------------------------------------------------// Connect inputs of the SVGEN_DQ module and call the space-vector gen.// calculation function.// ------------------------------------------------------------------------------svgen_dq1.Ualpha = ipark1.Alpha;svgen_dq1.Ubeta = ipark1.Beta;svgen_dq1.calc(&svgen_dq1);// ------------------------------------------------------------------------------// Connect inputs of the PWM_DRV module and call the PWM signal generation // update function.// ------------------------------------------------------------------------------pwm1.MfuncC1 = (int16)_IQtoIQ15(svgen_dq1.Ta); // MfuncC1 is in Q15pwm1.MfuncC2 = (int16)_IQtoIQ15(svgen_dq1.Tb); // MfuncC2 is in Q15pwm1.MfuncC3 = (int16)_IQtoIQ15(svgen_dq1.Tc); // MfuncC3 is in Q15pwm1.update(&pwm1);#endif // (BUILDLEVEL==LEVEL1)// ***************** LEVEL2 *****************#if (BUILDLEVEL==LEVEL2)// ------------------------------------------------------------------------------// Connect inputs of the RMP module and call the Ramp control// calculation function.// ------------------------------------------------------------------------------rc1.TargetValue = _IQ(SpeedRef);rc1.calc(&rc1);// ------------------------------------------------------------------------------// Connect inputs of the RAMP GEN module and call the Ramp generator// calculation function.// ------------------------------------------------------------------------------rg1.Freq = rc1.SetpointValue;rg1.calc(&rg1);// ------------------------------------------------------------------------------// Call the ILEG2_VDC read function.// ------------------------------------------------------------------------------ilg2_vdc1.read(&ilg2_vdc1);// ------------------------------------------------------------------------------// Connect inputs of the CLARKE module and call the clarke transformation// calculation function.// ------------------------------------------------------------------------------clarke1.As = _IQ15toIQ((int32)ilg2_vdc1.ImeasA);clarke1.Bs = _IQ15toIQ((int32)ilg2_vdc1.ImeasB);clarke1.calc(&clarke1);// ------------------------------------------------------------------------------// Connect inputs of the PARK module and call the park transformation// calculation function.// ------------------------------------------------------------------------------park1.Alpha = clarke1.Alpha;park1.Beta = clarke1.Beta;park1.Angle = rg1.Out;park1.calc(&park1);// ------------------------------------------------------------------------------// Connect inputs of the INV_PARK module and call the inverse park transformation // calculation function.// ------------------------------------------------------------------------------ipark1.Ds = _IQ(VdTesting);ipark1.Qs = _IQ(VqTesting);ipark1.Angle = rg1.Out;ipark1.calc(&ipark1);// ------------------------------------------------------------------------------// Connect inputs of the SVGEN_DQ module and call the space-vector gen.// calculation function.// ------------------------------------------------------------------------------svgen_dq1.Ualpha = ipark1.Alpha;svgen_dq1.Ubeta = ipark1.Beta;svgen_dq1.calc(&svgen_dq1);// ------------------------------------------------------------------------------// Connect inputs of the PWM_DRV module and call the PWM signal generation// update function.// ------------------------------------------------------------------------------pwm1.MfuncC1 = (int16)_IQtoIQ15(svgen_dq1.Ta); // MfuncC1 is in Q15pwm1.MfuncC2 = (int16)_IQtoIQ15(svgen_dq1.Tb); // MfuncC2 is in Q15pwm1.MfuncC3 = (int16)_IQtoIQ15(svgen_dq1.Tc); // MfuncC3 is in Q15pwm1.update(&pwm1);#endif // (BUILDLEVEL==LEVEL2)// ***************** LEVEL3 *****************#if (BUILDLEVEL==LEVEL3)// ------------------------------------------------------------------------------// Connect inputs of the RMP module and call the Ramp control// calculation function.// ------------------------------------------------------------------------------ rc1.TargetValue = _IQ(SpeedRef);rc1.calc(&rc1);// ------------------------------------------------------------------------------// Connect inputs of the RAMP GEN module and call the Ramp generator // calculation function.// ------------------------------------------------------------------------------ rg1.Freq = rc1.SetpointValue;rg1.calc(&rg1);// ------------------------------------------------------------------------------// Call the ILEG2_VDC read function.// ------------------------------------------------------------------------------ ilg2_vdc1.read(&ilg2_vdc1);// ------------------------------------------------------------------------------// Connect inputs of the CLARKE module and call the clarke transformation // calculation function.// ------------------------------------------------------------------------------ clarke1.As = _IQ15toIQ((int32)ilg2_vdc1.ImeasA);clarke1.Bs = _IQ15toIQ((int32)ilg2_vdc1.ImeasB);clarke1.calc(&clarke1);// ------------------------------------------------------------------------------// Connect inputs of the PARK module and call the park transformation// calculation function.// ------------------------------------------------------------------------------ park1.Alpha = clarke1.Alpha;park1.Beta = clarke1.Beta;park1.Angle = rg1.Out;park1.calc(&park1);// ------------------------------------------------------------------------------// Connect inputs of the PID_REG3 module and call the PID IQ controller // calculation function.// ------------------------------------------------------------------------------ pid1_iq.Ref = _IQ(IqRef);pid1_iq.Fdb = park1.Qs;pid1_iq.calc(&pid1_iq);// ------------------------------------------------------------------------------// Connect inputs of the PID_REG3 module and call the PID ID controller// calculation function.// ------------------------------------------------------------------------------pid1_id.Ref = _IQ(IdRef);pid1_id.Fdb = park1.Ds;pid1_id.calc(&pid1_id);// ------------------------------------------------------------------------------// Connect inputs of the INV_PARK module and call the inverse park transformation // calculation function.// ------------------------------------------------------------------------------ipark1.Ds = pid1_id.Out;ipark1.Qs = pid1_iq.Out;ipark1.Angle = rg1.Out;ipark1.calc(&ipark1);// ------------------------------------------------------------------------------// Connect inputs of the SVGEN_DQ module and call the space-vector gen.// calculation function.// ------------------------------------------------------------------------------svgen_dq1.Ualpha = ipark1.Alpha;svgen_dq1.Ubeta = ipark1.Beta;svgen_dq1.calc(&svgen_dq1);// ------------------------------------------------------------------------------// Connect inputs of the PWM_DRV module and call the PWM signal generation// update function.// ------------------------------------------------------------------------------pwm1.MfuncC1 = (int16)_IQtoIQ15(svgen_dq1.Ta); // MfuncC1 is in Q15pwm1.MfuncC2 = (int16)_IQtoIQ15(svgen_dq1.Tb); // MfuncC2 is in Q15pwm1.MfuncC3 = (int16)_IQtoIQ15(svgen_dq1.Tc); // MfuncC3 is in Q15pwm1.update(&pwm1);#endif // (BUILDLEVEL==LEVEL3)// ***************** LEVEL4 *****************#if (BUILDLEVEL==LEVEL4)// ------------------------------------------------------------------------------// Connect inputs of the RMP module and call the Ramp control// calculation function.// ------------------------------------------------------------------------------rc1.TargetValue = _IQ(SpeedRef);rc1.calc(&rc1);// ------------------------------------------------------------------------------// Connect inputs of the RAMP GEN module and call the Ramp generator// calculation function.// ------------------------------------------------------------------------------rg1.Freq = rc1.SetpointValue;rg1.calc(&rg1);// ------------------------------------------------------------------------------// Call the ILEG2_VDC read function.// ------------------------------------------------------------------------------ilg2_vdc1.read(&ilg2_vdc1);// ------------------------------------------------------------------------------// Connect inputs of the CLARKE module and call the clarke transformation// calculation function.// ------------------------------------------------------------------------------clarke1.As = _IQ15toIQ((int32)ilg2_vdc1.ImeasA);clarke1.Bs = _IQ15toIQ((int32)ilg2_vdc1.ImeasB);clarke1.calc(&clarke1);//-------------------------------------------------------------------------------------// Checking LockRotorFlag=FALSE for spinning mode, LockRotorFlag=TRUE for locked rotor mode//-------------------------------------------------------------------------------------if(LockRotorFlag==TRUE) // locked rotor mode if LockRotorFlag = 1{// ------------------------------------------------------------------------------// Connect inputs of the PARK module and call the park transformation// calculation function.// ------------------------------------------------------------------------------park1.Alpha = clarke1.Alpha;park1.Beta = clarke1.Beta;park1.Angle = 0;park1.calc(&park1);// ------------------------------------------------------------------------------// Connect inputs of the PID_REG3 module and call the PID IQ controller// calculation function.// ------------------------------------------------------------------------------pid1_iq.Ref = _IQ(IqRef);pid1_iq.Fdb = park1.Qs;pid1_iq.calc(&pid1_iq);// ------------------------------------------------------------------------------// Connect inputs of the PID_REG3 module and call the PID ID controller// calculation function.// ------------------------------------------------------------------------------pid1_id.Ref = _IQ(IdRef);pid1_id.Fdb = park1.Ds;pid1_id.calc(&pid1_id);// ------------------------------------------------------------------------------// Connect inputs of the INV_PARK module and call the inverse park transformation // calculation function.// ------------------------------------------------------------------------------ipark1.Ds = pid1_id.Out;ipark1.Qs = pid1_iq.Out;ipark1.Angle = 0;ipark1.calc(&ipark1);} // End: LockRotorFlag==TRUEelse if(LockRotorFlag==FALSE) // spinning mode if LockRotorFlag = 0{// ------------------------------------------------------------------------------// Connect inputs of the PARK module and call the park transformation// calculation function.// ------------------------------------------------------------------------------park1.Alpha = clarke1.Alpha;park1.Beta = clarke1.Beta;park1.Angle = rg1.Out;park1.calc(&park1);// ------------------------------------------------------------------------------// Connect inputs of the PID_REG3 module and call the PID IQ controller// calculation function.// ------------------------------------------------------------------------------pid1_iq.Ref = _IQ(IqRef);pid1_iq.Fdb = park1.Qs;pid1_iq.calc(&pid1_iq);// ------------------------------------------------------------------------------// Connect inputs of the PID_REG3 module and call the PID ID controller// calculation function.// ------------------------------------------------------------------------------pid1_id.Ref = _IQ(IdRef);pid1_id.Fdb = park1.Ds;pid1_id.calc(&pid1_id);// ------------------------------------------------------------------------------// Connect inputs of the INV_PARK module and call the inverse park transformation // calculation function.// ------------------------------------------------------------------------------ipark1.Ds = pid1_id.Out;ipark1.Qs = pid1_iq.Out;ipark1.Angle = rg1.Out;ipark1.calc(&ipark1);} // End: LockRotorFlag==FALSE// ------------------------------------------------------------------------------// Connect inputs of the SVGEN_DQ module and call the space-vector gen.// calculation function.// ------------------------------------------------------------------------------svgen_dq1.Ualpha = ipark1.Alpha;svgen_dq1.Ubeta = ipark1.Beta;svgen_dq1.calc(&svgen_dq1);// ------------------------------------------------------------------------------// Connect inputs of the PWM_DRV module and call the PWM signal generation// update function.// ------------------------------------------------------------------------------pwm1.MfuncC1 = (int16)_IQtoIQ15(svgen_dq1.Ta); // MfuncC1 is in Q15pwm1.MfuncC2 = (int16)_IQtoIQ15(svgen_dq1.Tb); // MfuncC2 is in Q15pwm1.MfuncC3 = (int16)_IQtoIQ15(svgen_dq1.Tc); // MfuncC3 is in Q15pwm1.update(&pwm1);// ------------------------------------------------------------------------------// Call the QEP_DRV calculation function.// ------------------------------------------------------------------------------qep1.calc(&qep1);// ------------------------------------------------------------------------------// Connect inputs of the SPEED_FR module and call the speed calculation function // ------------------------------------------------------------------------------speed1.ElecTheta = _IQ15toIQ((int32)qep1.ElecTheta);speed1.DirectionQep = (int32)(qep1.DirectionQep);speed1.calc(&speed1);#endif // (BUILDLEVEL==LEVEL4)// ***************** LEVEL5 *****************#if (BUILDLEVEL==LEVEL5)// ------------------------------------------------------------------------------// Call the ILEG2_VDC read function.// ------------------------------------------------------------------------------ilg2_vdc1.read(&ilg2_vdc1);// ------------------------------------------------------------------------------// Connect inputs of the CLARKE module and call the clarke transformation// calculation function.// ------------------------------------------------------------------------------clarke1.As = _IQ15toIQ((int32)ilg2_vdc1.ImeasA);clarke1.Bs = _IQ15toIQ((int32)ilg2_vdc1.ImeasB);clarke1.calc(&clarke1);// ------------------------------------------------------------------------------// Connect inputs of the PARK module and call the park transformation// calculation function.// ------------------------------------------------------------------------------park1.Alpha = clarke1.Alpha;park1.Beta = clarke1.Beta;park1.Angle = speed1.ElecTheta;park1.calc(&park1);// ------------------------------------------------------------------------------// Connect inputs of the PID_REG3 module and call the PID speed controller// calculation function.// ------------------------------------------------------------------------------if (SpeedLoopCount==SpeedLoopPrescaler){pid1_spd.Ref = _IQ(SpeedRef);pid1_spd.Fdb = speed1.Speed;pid1_spd.calc(&pid1_spd);SpeedLoopCount=1;else SpeedLoopCount++;// ------------------------------------------------------------------------------// Connect inputs of the PID_REG3 module and call the PID IQ controller// calculation function.// ------------------------------------------------------------------------------pid1_iq.Ref = pid1_spd.Out;pid1_iq.Fdb = park1.Qs;pid1_iq.calc(&pid1_iq);// ------------------------------------------------------------------------------// Connect inputs of the PID_REG3 module and call the PID ID controller// calculation function.// ------------------------------------------------------------------------------pid1_id.Ref = _IQ(IdRef);pid1_id.Fdb = park1.Ds;pid1_id.calc(&pid1_id);// ------------------------------------------------------------------------------// Connect inputs of the INV_PARK module and call the inverse park transformation // calculation function.// ------------------------------------------------------------------------------ipark1.Ds = pid1_id.Out;ipark1.Qs = pid1_iq.Out;ipark1.Angle = speed1.ElecTheta;ipark1.calc(&ipark1);// ------------------------------------------------------------------------------// Connect inputs of the SVGEN_DQ module and call the space-vector gen.// calculation function.// ------------------------------------------------------------------------------svgen_dq1.Ualpha = ipark1.Alpha;svgen_dq1.Ubeta = ipark1.Beta;svgen_dq1.calc(&svgen_dq1);// ------------------------------------------------------------------------------// Connect inputs of the PWM_DRV module and call the PWM signal generation// update function.// ------------------------------------------------------------------------------pwm1.MfuncC1 = (int16)_IQtoIQ15(svgen_dq1.Ta); // MfuncC1 is in Q15pwm1.MfuncC2 = (int16)_IQtoIQ15(svgen_dq1.Tb); // MfuncC2 is in Q15pwm1.MfuncC3 = (int16)_IQtoIQ15(svgen_dq1.Tc); // MfuncC3 is in Q15pwm1.update(&pwm1);// ------------------------------------------------------------------------------// Call the QEP calculation function// ------------------------------------------------------------------------------qep1.calc(&qep1);// ------------------------------------------------------------------------------// Connect inputs of the SPEED_FR module and call the speed calculation function // ------------------------------------------------------------------------------speed1.ElecTheta = _IQ15toIQ((int32)qep1.ElecTheta);speed1.DirectionQep = (int32)(qep1.DirectionQep);speed1.calc(&speed1);#endif // (BUILDLEVEL==LEVEL5)// ***************** LEVEL6 *****************#if (BUILDLEVEL==LEVEL6)// ------------------------------------------------------------------------------// Specify the initial position reference when DC-bus voltage is less than 25%// ------------------------------------------------------------------------------if (_IQ15toIQ((int32)ilg2_vdc1.VdcMeas) < _IQ(0.25))PositionRef = _IQtoF(_IQ15toIQ((int32)qep1.MechTheta));// ------------------------------------------------------------------------------// Connect inputs of the RMP_CNTL module and call the Ramp control// calculation function.// ------------------------------------------------------------------------------rc1.TargetValue = _IQ(PositionRef);rc1.calc(&rc1);// ------------------------------------------------------------------------------// Call the ILEG2_VDC read function.// ------------------------------------------------------------------------------ilg2_vdc1.read(&ilg2_vdc1);// ------------------------------------------------------------------------------// Connect inputs of the CLARKE module and call the clarke transformation// calculation function.// ------------------------------------------------------------------------------clarke1.As = _IQ15toIQ((int32)ilg2_vdc1.ImeasA);clarke1.Bs = _IQ15toIQ((int32)ilg2_vdc1.ImeasB);clarke1.calc(&clarke1);。