This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工具/软件:Code Composer Studio
您好,
我正在尝试按照 SPRUI31中的指导在F2.8335万上实施您的数字控制器库。 但是,无论我的设置或KP,KI,上限/下限饱和度的值如何,PI结构中的值似乎都不同。 我相信我对如何使用和理解图书馆有一个误解,因此感谢您的帮助。 我使用两个桥之间的相位移控制,其中两个PWM通道之间的相位移应该在相位移寄存器内介于800和1460之间。 因此,我将饱和限值设置为800和1460。 我从KP=10开始,禁用集成商以使用纯P调节器(稍后将调整KI参数以正确控制DCDC转换器)。 这些值在PI_VALUES中定义,如下面给出的C代码所示。
ADC中断服务例程正常工作,ADC读数也正常工作。 调试代码时,我可以看到也调用了PI函数,并执行了DCL_PI.ASM代码。 通过检查PI调节器的值,我可以看到该值与我的设置不同。 此外,我可以看到PI调节器的输出被夹紧到Umin,这是绑定到b e 2039的较低饱和度,而不是我的设置中的800。 您对发生的事情和我做错的事情有什么想法吗? 感谢您的指导。
#include "DSP28x_Project.h" #include "DCL.h" void InitialADC(); void InitePWM1(); void InitePWM2(); void InitePWM5(); void InitePWM6(); __interrupt void ADC_ISR(); __interrupt void TZ_ISR(); //闪存功能 extern UINT16 RamfuncsLoadStart; extern UINT16 RamfuncsLoadEnd; extern UINT16 RamfuncsRunStart; //变量 #define DT 25 // Dead time calc:DT = value/CLKfr -> as25/1000.016f/ 控制器变量00.0160.0f, 1460.0f }// kp,ki,I10,Sat_max,Sat_min, sat_storage volatile float32 rk; //参考值 volatile float32 yk; //测量的ADC信号 挥发浮点32 uk; // pi输出 挥发PI pi1; volatile UINT16 ConversionCount; volat32 Voltage1[256]; volatile float32 current[256]; void main( 看门狗){//初始化PLL, Ctrl/启用外设时钟,启用外设 时钟,以使用void编程/ Memcopy (&RamfuncsLoadStart,&RamfuncsLoadEnd,&RamfuncsRunStart); // VecePWM和TZ InitEPwmGpio(); InitTzGpio(); //初始化PIE控制寄存器 InitPievector(); IER = 0x0000; IFR = 0x0000; // 初始化Isr_Pie =表;Isr_EPTEDMI; In_EPTEPTEPTI=初始化Isr_EPTEPTEPTEPTI= //设置ADC采样速率 EALLOW的第一步; SysCtrlRegs.HISPPP.ALL =3;// HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)= 25.0 MHZ EDIS; //同步已在InitSysCtrl()函数中完成-->要求TI支持来验证 SysReg1.PCW; SYLNC* = SYLLOKW.CLW; //从DSP EDIS中使用SYSCLKOUT启用时基时钟同步; */ InitFlash(); ConversionCount = 0; //初始化计数 UK = 0; rk = 2050; //大约 5A负载电压 PI pi1 = pi_values; //初始化PI控制器 //初始化ADC InitAdc(); phaseshift1 = 5; //补偿a ca。 ePWM1和ePWM6 InitialADC()之间的15ns延迟; //为电压和电流测量 EALLOW设置ADC; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; EDIS; InitePWM1(); InitePWM2(); InitePWM5(); InitePWM6(); EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; /* 将GPIO4设置为输出以测量ISR */ EALLOW内的执行时间; //将GPIO10设置为GPIO -已在InitGpio() GpioERlRegs.GPAMUX1.bit.GPIO4 = 0中完成; //将GPIO10设置为输出GpioCtrlRegs.GPADIR.bit.EDI1 = 1;1. //用于ADC PieCtrlRegs.PIEIER2.bit.INTx1 = 1的组1,位6; //用于ePWM1_TZ IER || M_INT1的组2,位1; //设置组1 IER || M_INT2的中断启用位; //设置组3 EINT的中断启用位; //启用全局中断INTM for(;) { } }__interrupt void ADC_ISR(void) { GpioDataRegs.GPASET.bit.GPIO4 =1; Voltage1[ConversionCount]= AdcRegs.ADCRESULT0>4; //从ADCINA5 电流读取值[CM1= REGP.CMPA] = 从ADCM1CM1CMP0.1CMP5.CMPASPf.CMPf.CMPPA/ REPA.1DAV= AD1CMP5.CMP5.CMP1DAV= AD1CMP5.CMP1DAV= AD1CMP5.CMP5.CMPf= ADCMP1.CMPfV = ADCMP1CMP1CMP1DAV0.1CMPfV = 0 EPwm6Regs.CMPA.Half.CMPA = 0; EPwm5Regs.CMPA.Half.CMPA = 1500; }/* *使用PI CONTROL */ YK = Current[ConversionCount]; UK = DCL_runPI (&pi1,rk, m6)计算两个网桥之间的相位移;EPwm5Regs.pyk = PT.Peshfs/TBwhs = pesphesfm1;EPwhs = PT/TBwhs = peshpasphasphes/ pesfhs = pesfhs。 ePWM6的16ns延迟 //如果记录了256个转换,请重新开始 IF (ConversionCount == 255) { ConversionCount = 0; } 否则 { ConversionCount++;} //重新初始化下一个ADC AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; //重置SEQ1 AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //清除 OST标志位PieCtrlRegs.PIEACK.ALL = PIEACK_GROUP1;//中断确认PIEPAX.1= PIEPOL.1; CLR = PIEPIEP.1= 1 =纯净EPOST.1; C1.TIP1.PERAST.POST.EP.1=纯1 =纯1 = 1 =纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯净=纯 EPwm6Regs.TZCLL.bit.OST = 1; EPwm1Regs.TZCLR.Bit.INT = 1; EDIS; PiectrlRegs.PIEACG.ALL = PIEACK_group2; //确认中断到PIE } void InitialADC(void) {// 配置ADC AdcRegs.ADCTRL3.bit.ADCCLL3=1; //设置ADC采样率= void.RCSCR1.CADR1.CAST_ADC= 1.CADR.R0.1= 0;CADR1.CADR1.CADR1.CAST_ADC= 0 ;CADR1.POST.R0.1= 1.CADR1.CADR1.CADR1.CADR.POST.POST.POST.POST= 0 = 0;ADC= ADC= ADC= ADC1.CADR1.CADR1.CADR1.CADR1.CADR1.CADR1.CADR.CADR.CADR.CADR.CADR.CADR.CADR.CAST.R0.1= 0 //同时采样模式 AdcRegs.ADCTRL2.bit.ePWM_SOCA_SEQ1 = 1;// ePWM启动SOCA触发 器AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;// 一个转换 器AdcRegs.ADCCHSEL1.bit.CONVI = 5;// ADCINCA.CA.INV1 启用ADCINV1 的ADCINV1和ADCINCA.CA_ADCINV5.INCA.CA.CA.CA.CA.CAV1的中断 EPwm1Regs.ETSEL.bit.SOCAEN = 1; //启用SOCA EPwm1Regs.ETSEL.bit.SOCASEL = 4; //在50 % 占空比下生成SOCA脉冲 EPwm1Regs.ETPS.bit.SOCAPRD = 1; //生成第一个事件的脉冲 EPwm1Regs.TBPRD = 1499; //将PWM周期时间 EPwm1Regs.CMPA.Half.CMPA =(1499+1)/2;EPw1Regs.TBPHPHPHPHPHPHPHPHPHPHPHPHPHPS.TBMPs.TR_REGs.PT.MP_DE.PTB.PTB.MP_1BE.PTB.PTB.= 0;SCMP_DE_REGP.PTB.PTB.MP_DE_DE_DE.PTB.PTB.PTB.MP.PTB.PTB.MP_DE_DE_DE.PTB.PTB.PTB.PE.PE.PE.PTB.PTB.= 0 = 0 //同步下流模块 EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; //将时基时钟设置为SYSCLKOUT EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_shadow;EPwm1Regs.CMCL=1PRD=DAMP0 或PRD=1DAMP0 PRD=DAMP0 PRD=1DAMP0 ;PRD = PRD_REG=1DAMP0 或DAMP0 PRD = PRD = PRD = PRD = 0;0 = 0 = PRD = PRD = 0;0 = 0 = 0 = 0;0 = 0 = 0 = 0;0 = 0 = 0 = 0 = 0 = 0;0 = 0 = 0 = 0;0 = 0 = 0 = 0;0 = 0;0 = 0 = 0 = 0 = 0;0 = 0; //在cTR=PRD EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR时设置pin; //在cTR=compa EALLOW时清除pin; EPwm1Regs.TZsel.OSHT3 = 1; //启用TZ3 EPwm1Regs.TZL.Bit.TZA = 2; 在EPT1.EPT1.01中启用T01 = EPT1.01;在EPT1.01时启用EPT1.01 // ePWMxA下降和上升边缘 EPwm1Regs.DBCTL.bit.ut_mode = DB_FULL启用; // DB full enable EPwm1Regs.DBCTL.bit.POPPA SEL = DB_ACTV_HIC; // Active high mTBEPwm1Regs.DBRED = DT = DT;DBw1EP.0; DBM12.P1= DE.P1PRD = DE.1= DB_12.1PRD = DB_12.1PRD = DE.EP.1= DB_12.1PRD = DE.1PED.1PED.1PED.P1.P1.P1.P12.1= DB1PRD = DE.1PRD = DE.1PRD = DE.1PED.1PED.1PED.1PED.1PED.1PED.1PED.2= DB/PRD = DE. //将相位寄存器设置为零 EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // UP计数模式 EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;//主模块 EPwm2Regs.HPTL.PRDLD = TB_SHADPCTB_SHADMPT.CMPCDAMPT.MPCMPC= 2DAMPT.DCME= DCMOS.DCMOS.DCMOS.D0 = 0;DCMSTREGMP0 = 0 = DCMOS.DCMOS.DCMSTDAMP0 = 0 = 0 = DCMSTMP0 = DCMSTMP0 = 0 = DCMSTREGMP0 = 0 = D0 = DCM0 = 0 // ctr=0或ctr=pD EPwm2Regs.CMPCTL.bit.LOADBMODE = 0; // ctr=0或ctr=PRD EPwm2Regs.HTCTLA.bit.ZRO = SEL_CLEAR; //在ctr=PRD=W2Regs.OSCLA.bit.PRD时清除引脚;在TR=AQEPw2LA.ZAQ= PIN_DE.ZWA.Z1.PIN= PIN.PIN.T时清除引脚 //在TZ事件 上清除ePWM2A EPwm2Regs.TZCTL.bit.TZB = 2; //在TZ事件 EDIS上清除ePWM2B; EPwm2Regs.DBCTL.bit.in_mode = 0; // ePWMxA下降和上升边缘DBwm2Regs.DBC.DB_REGDE.EPT.DE=2.EPmDE_DEF2bit =全模式DB_DEP.DE_DEPwDB_DE0; DB_DE_DEPw2DB_DE_DE_DEPwb.DB_DE.DB_DE_DE_DE_DEP.DBwb.DB_DE.DB_DE.DB_DE.DBw2b.DB_DE.DB_DE.DB_DE.DB_DE.DB_DE.DB_DE void InitePWM5 (void) { EPwm5Regs.TBPRD = 1499; //将PWM周期时间 EPwm5Regs.CMPA.Half.CMPA =(1499+1)/2; EPwm5Regs.HSSPHS.Half.TBPHPHPHPHPHPHPHPHPHPHPHPHPHPHHS =零 EPwm5Regs.PCMPs.PTC.MP_EPmSC_EPmSCN.PTT.PTB_DE=零 位= EPMPT.PTB.PTB.PTB.PTB.PTT.PE_EPMP_EPMPT.PTB.PTB.PTB.PTT.PE_DE= EPMPT.PE.PTB.PTB.PTT.PE.PTB.PTB.PTT.PE.PTB.PTB.PTB.PTB_DE=零位= EPMPT.PE.PTT.PE.PTB.PTB.PTT.PE.PTB.PTB.PTT.PE.PTB.PTT.PE.PTB.PTB.PTB.PTB.PTB.PTB.PTB.PTB.PTB.PTB.PTB= //将时基时钟设置为SYSCLKOUT EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADODE; EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHAD影子;EPwm5Regs.CMTR.CMCL=PRD=0 ; PA= Pin PRD.C=0 时,PRD=0 = Pin = CQ= PX.CQAR= P= P= P= P= P= P= P= P= P= P= P= P= P= P= P= P= P= P= P= P= PQPAQ= P= P= P= PQ= PQ= P= P= P= P= P= P= P= P= P= P= P= P= P= PQ= P= P= P= P= P= P= P= P= P= P= P= PQ= EPwm5Regs.TZsel.bit.OSHT3 = 1; //启用TZ3 EPwm5Regs.TZCTL.bit.TZA = 2; //在TZ事件上清除ePWM5A EPwm5Regs.TZCTL.Bit.TZB = 2; //清除ePWM5B在TZ事件中清除; DB_REGDEPT.EPT.DB_DEPT.DB_DEPT.EPT.= 全模式下的DB_DEPT.DB_DEPT.EPT.DB_DEPT.EPT.DB_DEPT.EPT.DB_DEP= //有源高互补 EPwm5Regs.DBRED = DT; EPwm5Regs.DBFED = DT; } void InitePWM6 (void) { EPwm6Regs.TBPRD = 1499;// 设置PWM周期时间 EPwm6Regs.CMPA.Half.CMPA =(1499+1)/2;EPwCTPS.PTB= 零位/PTBPHPS.PTB_REG=零位EPS.PTPS.PTB_REG.PTPS.PTPS.PTB= 0 =零位EPmPE.PTPS.PE.PTB_0 =零位EP_0 //从属模块 EPwm6Regs.TBCTL.bit.PRDLD = Tb_shadow; EPwm6Regs.TBCTL.bit.SYNCOSEL = Tb_ctr_zero;//同步下流模块 EPwm6Regs.TBCTL.bit.HSDBDE PCLDPPCLKDIV = 0; //将时基时基时钟设置为STDAMP0 = DMP0 ;SOMP0 = DMP0 = DMODAMP0 = D0 = DMODAMP0 = PMODAMP0 = PMODAMP0 = PMODAMP0 = P0 = 0 = 0 = 0 = PMODAMP0 = 0 = 0 = 0 = 0 = 0 = PMODAMP0 //在cTR=0或cTR=PRD EPwm6Regs.AQCTLA.bit.ZRO = AQ_SET时设置 引脚;//在cTR=PRD EPwm6Regs.AQCTLA.bit.CAU = ZB_CLEAR时 清除引脚;在ctr=compa EALLOW时清除引脚;PWwm6Regs.OSTZs.AQTZ/T6B= TTEZEPT1.ZEZEZEZ= T6B/ 在TTEX1.ZEZEZEZEPT1.TES/T6B= TTEXEZEZEZES/ T6B= T6B/ TTEXEZEZEZEZEZEZEZEZES/ T6B= T6B/ T6B/ EPwm6Regs.DBCTL.bit.in_mode = 0; // ePWMxA下降和上升边缘 EPwm6Regs.DBCTL.bit.out模式= DB_FULL启用; // DB完全启用 EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // DBEPm6DT = DBwRED.REP.DT = D5.REwDEV = DBw6DT补充D= DBwDED = DBwDEV
亚历山大
目前,你在两个地方宣布pi1。 您是否可以从注释第77行开始,并通过将第27行更改为以下内容来初始化声明中的结构:
易失性PI pi1 = pi_values;
然后,您是否可以在InitAdc()函数(第80行)上设置一个中断点,并检查PI结构是否在该点正确初始化? 如果是这样,请尝试在DCL_runPI()行上设置另一个中断点,然后重新检查。 我在您的代码中没有看到任何涉及控制器增益或限制的内容,因此它们已正确初始化,不应更改。
大多数问题与数字格式有关。 所有DCL功能都需要浮点输入并提供浮点输出。 您已正确地将rk,YK和UK声明为浮点,但您将rk和YK指定给定点数字。 在将它们传递到DCL_runPI()函数之前,需要将它们转换为浮点格式。
RK = 2050.0 f;
YK =(浮点)电流[ConversionCount];
您还将32位浮点结果UK分配给16位寄存器:
EPwm5Regs.TBPHS.Half.TBPHS = UK;
在将其写入寄存器之前,需要将其转换为16位无符号整数格式。 为此,您可以声明一个变量(例如x),然后将其分配给UK:
X =(长)英国;
...然后根据需要移动并将部分分配给16位无符号int (z)。 例如:
Z =(无符号int)(x >> 4);
然后,您可以将其写入寄存器,但要仔细检查以确保结果符合预期。
此致,
Richard
很抱歉重新激活此线程,但DCL对我来说还不是很清楚。 我仍在使用PI控制器。 我的代码的更新版本将在此文本之后。 我的问题是,我的输出已饱和,无论错误的迹象如何(即我的控制器的输入为正或负),输出都保持在该值。 随附两个数字(一个是测得的电压低于参考电压,另一个是测得的电压高于参考电压)。 在这两种情况下,输出保持不变。
我不能自己完全解释这种情况,我实际上想知道我的PI调节器中的I10和i6值。 您的技术参考中的离散PI补偿器的方框图也附在此信息中。
1)
I10似乎是上一次采样的累积值,因此:
I10 = v4[n-1],n为当前采样点。
因此,I10的值决定了我可以进行积分/求和的最大值。 因为它是浮点数,所以我会将I10设置得尽可能高,比如说2万.0f
我的理解是否正确?
2)
I6是(抗)饱和机制的反馈。 如果V5 = u(k),则差值为零,因此i6也为零。 在方程式14中,来自饱和的反馈消失,PI调节器正常工作。 相反,如果u (k)饱和,i6将反馈给积分器,如方程式14中所示。
如果我对(1)和(2)的理解是正确的,那么我感到惊讶的是,在CCS的表达式窗口中,i6的值为零,并且无论我的转换器工作点如何,都保持在零。 换言之,既然我正在饱和输出u(k),i6怎么能为0? 我希望它与0不同,以抵消我的集成商的windup。
离散PI调节器的方框图:
正极错误:e (k)= r (k)- y (k)
负错误:e (k)= r (k)- y (k)
我的c代码:
#include "DSP28x_Project.h" #include "DCL.h" void InitialADC(); void InitePWM1(); void InitePWM2(); void InitePWM5(); void InitePWM6(); __interrupt void ADC_ISR(); __interrupt void TZ_ISR(); //闪存功能 extern UINT16 RamfuncsLoadStart; extern UINT16 RamfuncsLoadEnd; extern UINT16 RamfuncsRunStart; //变量 #define DT 25 // Dead Time calc:DT = value/CLKfreq -> 25/25/0.00MHz ,0.00f, 0.0.115万f,控制 器0 2万.0f}// kp,ki,I10,Sat_max,Sat_min, sat_storage UINT16变频器; UINT16变频器1; 易失性Int32伪; 易失性浮子32 rk; //参考值 易失性浮子32 YK; //测量的ADC信号 易失性浮子32 UK; // PI输出 易失性PI pi1 = pi_values; 易失性UINT16转换计数; 易失性浮子32伏子1[256] ;易失性电流1[256]; void main(void){// 初始化PLL,监视器,启用外设时钟 InitSysCtrl();// 用于对闪存进行编程 Memcopy (&RamfuncsLoadStart,&RamfuncsLoadEnd,&RamfuncsRunStart); // VecePWM和TZ InitEPwmGpio(); InitTzGpio(); //初始化PIE控制寄存器 InitPievector(); IER = 0x0000; IFR = 0x0000; // 初始化Isr_Pie =表;Isr_EPTEDMI; In_EPTEPTEPTI=初始化Isr_EPTEPTEPTEPTI= //设置ADC采样速率 EALLOW的第一步; SysCtrlRegs.HISPPP.ALL =3;// HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)= 25.0 MHZ EDIS; //同步已在InitSysCtrl()函数中完成-->要求TI支持来验证 SysReg1.PCW; SYLNC* = SYLLOKW.CLW; //从DSP EDIS中使用SYSCLKOUT启用时基时钟同步; */ InitFlash(); ConvisionCount = 0; //初始化计数 伪=1460; UK = 1460.0f; // rk = 2050.0f; //大约 5A负载电流 rk = 300.0f; //约 10V负载电压 //pi pi1 = pi_values; //初始化ADC InitAdc (); phaseshift = 0; phaseshift1 = 4; //补偿a ca。 ePWM1和ePWM6 InitialADC()之间的15ns延迟; //为电压和电流测量 EALLOW设置ADC; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; EDIS; InitePWM1(); InitePWM2(); InitePWM5(); InitePWM6(); EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; /* 将GPIO4设置为输出以测量ISR */ EALLOW内的执行时间; //将GPIO10设置为GPIO -已在InitGpio() GpioERlRegs.GPAMUX1.bit.GPIO4 = 0中完成; //将GPIO10设置为输出GpioCtrlRegs.GPADIR.bit.EDI1 = 1;1. //用于ADC PieCtrlRegs.PIEIER2.bit.INTx1 = 1的组1,位6; //用于ePWM1_TZ IER || M_INT1的组2,位1; //设置组1 IER || M_INT2的中断启用位; //设置组3 EINT的中断启用位; //启用全局中断INTM for (;) { } __interrupt void ADC_ISR(void) { Voltage1[ConversionCount]= AdcRegs.ADCRESULT0 >>4; //从ADCINA5读取值 电流[ConversionCount]= AdcRegs.ADCREST1 Half >4;//从ADCM15.CMPA.1CMPA.1CMPA.1CMPA.0读取值= 0流0 = 0 EPwm5Regs.CMPA.Half.CMPA = 1500; }/* *使用PI CONTROL */ YK =(FLOW)Voltage1[ConversionCount]; //在达到最小输出电压 时调节,如果(YK>=200){ GpioDataRegs.GPASET.bit.IOpi4=1; 用于测试的gop.1; gop.cl_rema_1;用于测试的gpi1; gpi1; gop.gpi1= gpirk.gpi1; gpi1;用于测试的gpi1; gop.rk.rk.gpirk.gpi1; gpi1; gpi1;用于测试 EPwm5Regs.TBPHS.Half.TBPHS = dummy; // ePWM5和ePWM6将具有phaseshift EPwm6Regs.TBPHS.Half.TBPHS = phaseshift1; //补偿ca。 ePWM6的16ns延迟 //如果记录了256个转换,请重新开始 IF (ConversionCount == 255) { ConversionCount = 0; } 否则 { ConversionCount++;} //重新初始化下一个ADC AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; //重置SEQ1 AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //清除 CLR标志位PieCtrlRegs.PIEACK.ALL = PIEACK_GROUP1;//中断确认到PIE.EPm1; CLR = TIP1.EPT.1; CLR1.ECT.1STOSTOST.EP.1= P1.EPT.EP.1ECT.1ECT.1ECT.1ECT.1= EPwm1Regs.TZCLR.Bit.INT = 1; EDIS; PiectrlRegs.PIEACG.ALL = PIEACK_group2; //确认中断到PIE } void InitialADC(void) {// 配置ADC AdcRegs.ADCTRL3.bit.ADCCLL3=1; //设置ADC采样率= void.RCSCR1.CADR1.CAST_ADC= 1.CADR.R0.1= 0;CADR1.CADR1.CADR1.CAST_ADC= 0 ;CADR1.POST.R0.1= 1.CADR1.CADR1.CADR1.CADR.POST.POST.POST.POST= 0 = 0;ADC= ADC= ADC= ADC1.CADR1.CADR1.CADR1.CADR1.CADR1.CADR1.CADR.CADR.CADR.CADR.CADR.CADR.CADR.CAST.R0.1= 0 //同时采样模式 AdcRegs.ADCTRL2.bit.ePWM_SOCA_SEQ1 = 1;// ePWM启动SOCA触发 器AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;// 一个转换 器AdcRegs.ADCCHSEL1.bit.CONVI = 5;// ADCINCA.CA.INV1 启用ADCINV1 的ADCINV1和ADCINCA.CA_ADCINV5.INCA.CA.CA.CA.CA.CAV1的中断 EPwm1Regs.ETSEL.bit.SOCAEN = 1; //启用SOCA EPwm1Regs.ETSEL.bit.SOCASEL = 4; //在50 % 占空比下生成SOCA脉冲 EPwm1Regs.ETPS.bit.SOCAPRD = 1; //生成第一个事件的脉冲 EPwm1Regs.TBPRD = 1499; //将PWM周期时间 EPwm1Regs.CMPA.Half.CMPA =(1499+1)/2;EPw1Regs.TBPHPHPHPHPHPHPHPHPHPHPHPHPHPS.TBMPs.TR_REGs.PT.MP_DE.PTB.PTB.MP_1BE.PTB.PTB.= 0;SCMP_DE_REGP.PTB.PTB.MP_DE_DE_DE.PTB.PTB.PTB.MP.PTB.PTB.MP_DE_DE_DE.PTB.PTB.PTB.PE.PE.PE.PTB.PTB.= 0 = 0 //同步下流模块 EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; //将时基时钟设置为SYSCLKOUT EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_shadow;EPwm1Regs.CMCL=1PRD=DAMP0 或PRD=1DAMP0 PRD=DAMP0 PRD=1DAMP0 ;PRD = PRD_REG=1DAMP0 或DAMP0 PRD = PRD = PRD = PRD = 0;0 = 0 = PRD = PRD = 0;0 = 0 = 0 = 0;0 = 0 = 0 = 0;0 = 0 = 0 = 0 = 0 = 0;0 = 0 = 0 = 0;0 = 0 = 0 = 0;0 = 0;0 = 0 = 0 = 0 = 0;0 = 0; //在cTR=PRD EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR时设置pin; //在cTR=compa EALLOW时清除pin; EPwm1Regs.TZsel.OSHT3 = 1; //启用TZ3 EPwm1Regs.TZL.Bit.TZA = 2; 在EPT1.EPT1.01中启用T01 = EPT1.01;在EPT1.01时启用EPT1.01 // ePWMxA下降和上升边缘 EPwm1Regs.DBCTL.bit.ut_mode = DB_FULL启用; // DB full enable EPwm1Regs.DBCTL.bit.POPPA SEL = DB_ACTV_HIC; // Active high mTBEPwm1Regs.DBRED = DT = DT;DBw1EP.0; DBM12.P1= DE.P1PRD = DE.1= DB_12.1PRD = DB_12.1PRD = DE.EP.1= DB_12.1PRD = DE.1PED.1PED.1PED.P1.P1.P1.P12.1= DB1PRD = DE.1PRD = DE.1PRD = DE.1PED.1PED.1PED.1PED.1PED.1PED.1PED.2= DB/PRD = DE. //将相位寄存器设置为零 EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // UP计数模式 EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;//主模块 EPwm2Regs.HPTL.PRDLD = TB_SHADPCTB_SHADMPT.CMPCDAMPT.MPCMPC= 2DAMPT.DCME= DCMOS.DCMOS.DCMOS.D0 = 0;DCMSTREGMP0 = 0 = DCMOS.DCMOS.DCMSTDAMP0 = 0 = 0 = DCMSTMP0 = DCMSTMP0 = 0 = DCMSTREGMP0 = 0 = D0 = DCM0 = 0 // ctr=0或ctr=pD EPwm2Regs.CMPCTL.bit.LOADBMODE = 0; // ctr=0或ctr=PRD EPwm2Regs.HTCTLA.bit.ZRO = SEL_CLEAR; //在ctr=PRD=W2Regs.OSCLA.bit.PRD时清除引脚;在TR=AQEPw2LA.ZAQ= PIN_DE.ZWA.Z1.PIN= PIN.PIN.T时清除引脚 //在TZ事件 上清除ePWM2A EPwm2Regs.TZCTL.bit.TZB = 2; //在TZ事件 EDIS上清除ePWM2B; EPwm2Regs.DBCTL.bit.in_mode = 0; // ePWMxA下降和上升边缘DBwm2Regs.DBC.DB_REGDE.EPT.DE=2.EPmDE_DEF2bit =全模式DB_DEP.DE_DEPwDB_DE0; DB_DE_DEPw2DB_DE_DE_DEPwb.DB_DE.DB_DE_DE_DE_DEP.DBwb.DB_DE.DB_DE.DB_DE.DBw2b.DB_DE.DB_DE.DB_DE.DB_DE.DB_DE.DB_DE void InitePWM5 (void) { EPwm5Regs.TBPRD = 1499; //将PWM周期时间 EPwm5Regs.CMPA.Half.CMPA =(1499+1)/2; EPwm5Regs.HSSPHS.Half.TBPHPHPHPHPHPHPHPHPHPHPHPHPHPHHS =零 EPwm5Regs.PCMPs.PTC.MP_EPmSC_EPmSCN.PTT.PTB_DE=零 位= EPMPT.PTB.PTB.PTB.PTB.PTT.PE_EPMP_EPMPT.PTB.PTB.PTB.PTT.PE_DE= EPMPT.PE.PTB.PTB.PTT.PE.PTB.PTB.PTT.PE.PTB.PTB.PTB.PTB_DE=零位= EPMPT.PE.PTT.PE.PTB.PTB.PTT.PE.PTB.PTB.PTT.PE.PTB.PTT.PE.PTB.PTB.PTB.PTB.PTB.PTB.PTB.PTB.PTB.PTB.PTB= //将时基时钟设置为SYSCLKOUT EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADODE; EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHAD影子;EPwm5Regs.CMTR.CMCL=PRD=0 ; PA= Pin PRD.C=0 时,PRD=0 = Pin = CQ= PX.CQAR= P= P= P= P= P= P= P= P= P= P= P= P= P= P= P= P= P= P= P= P= PQPAQ= P= P= P= PQ= PQ= P= P= P= P= P= P= P= P= P= P= P= P= P= PQ= P= P= P= P= P= P= P= P= P= P= P= PQ= EPwm5Regs.TZsel.bit.OSHT3 = 1; //启用TZ3 EPwm5Regs.TZCTL.bit.TZA = 2; //在TZ事件上清除ePWM5A EPwm5Regs.TZCTL.Bit.TZB = 2; //清除ePWM5B在TZ事件中清除; DB_REGDEPT.EPT.DB_DEPT.DB_DEPT.EPT.= 全模式下的DB_DEPT.DB_DEPT.EPT.DB_DEPT.EPT.DB_DEPT.EPT.DB_DEP= //有源高互补 EPwm5Regs.DBRED = DT; EPwm5Regs.DBFED = DT; } void InitePWM6 (void) { EPwm6Regs.TBPRD = 1499;// 设置PWM周期时间 EPwm6Regs.CMPA.Half.CMPA =(1499+1)/2;EPwCTPS.PTB= 零位/PTBPHPS.PTB_REG=零位EPS.PTPS.PTB_REG.PTPS.PTPS.PTB= 0 =零位EPmPE.PTPS.PE.PTB_0 =零位EP_0 //从属模块 EPwm6Regs.TBCTL.bit.PRDLD = Tb_shadow; EPwm6Regs.TBCTL.bit.SYNCOSEL = Tb_ctr_zero;//同步下流模块 EPwm6Regs.TBCTL.bit.HSDBDE PCLDPPCLKDIV = 0; //将时基时基时钟设置为STDAMP0 = DMP0 ;SOMP0 = DMP0 = DMODAMP0 = D0 = DMODAMP0 = PMODAMP0 = PMODAMP0 = PMODAMP0 = P0 = 0 = 0 = 0 = PMODAMP0 = 0 = 0 = 0 = 0 = 0 = PMODAMP0 //在cTR=0或cTR=PRD EPwm6Regs.AQCTLA.bit.ZRO = AQ_SET时设置 引脚;//在cTR=PRD EPwm6Regs.AQCTLA.bit.CAU = ZB_CLEAR时 清除引脚;在ctr=compa EALLOW时清除引脚;PWwm6Regs.OSTZs.AQTZ/T6B= TTEZEPT1.ZEZEZEZ= T6B/ 在TTEX1.ZEZEZEZEPT1.TES/T6B= TTEXEZEZEZES/ T6B= T6B/ TTEXEZEZEZEZEZEZEZEZES/ T6B= T6B/ T6B/ EPwm6Regs.DBCTL.bit.in_mode = 0; // ePWMxA下降和上升边缘 EPwm6Regs.DBCTL.bit.out模式= DB_FULL启用; // DB完全启用 EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // DBEPm6DT = DBwRED.REP.DT = D5.REwDEV = DBw6DT补充D= DBwDED = DBwDEV
大家好,
我想请您再详细说明一下我在上一篇文章中提出的两个问题,因为我仍然不确定PI监管机构内I10和i6的含义(价值调整)。
1)
I10似乎是上一次采样的累积值,因此:
I10 = v4[n-1],n为当前采样点。
因此,I10的值决定了我可以进行积分/求和的最大值。 因为它是浮点数,所以我会将I10设置得尽可能高,比如说2万.0f
我的理解是否正确?
2)
I6是(抗)饱和机制的反馈。 如果V5 = u(k),则差值为零,因此i6也为零。 在方程式14中,来自饱和的反馈消失,PI调节器正常工作。 相反,如果u (k)饱和,i6将反馈给积分器,如方程式14中所示。
我不清楚为什么i6一直是0.0 ,即使我正在饱和我的PI输出。
谢谢!
亚历山大
PI控制器的工作方式不是这样。 变量I10是集成器输出。 您应该将其初始化为0,然后不要触摸它。 饱和在输出端使用Umax和Umin来处理。
i6的用途是反windup。 它只能保持值1.0f (输出不饱和)或0.0f (输出饱和)。 如果您看图i6与v3相乘以形成V8,则它会启用或禁用集成。
我现在正在旅行,但如果您仍有困难,我会在明天回复。
此致,
Richard
谢谢你Richard。 虽然DCL的PI监管机构对我来说更加清晰,但我仍在努力实现实际实施。
我根据我的波德图解分析设计了PI控制器:
请注意,图OL表示开环系统。 大家可以看到,在我的交叉频率下,我拥有足够多的相位余量(在设计的这一阶段不需要最佳控制器)。
MATLAB中的PI调节器设置为:
%% PI控制器
KP = 1.5 ;
Ki = 300;
Ka = Kp;
KB = KI/Ka;
num_pi =[Ka Ka*KB];
DEN_PI =[1 0];
G_PI = TF (num_pi,den_pi)
G_PIdiscr = C2D (G_PI,TSW,'Tustin')
在不复制整个C代码(再次)的情况下,这就是在CCS中实现PI调节器的方式:
#define pi_values { 1.5f, 300.0f, 0.0f, 1125.0f, 900.0f, 1.0f}// kp,ki,I10,Sat_max,Sat_min, SAT_STORAGE
ISR内的PI调节器:
__interrupt void ADC_ISR(void) { Voltage1[ConversionCount]= AdcRegs.ADCRESULT0 >>4; //从ADCINA5中读取值 电流[ConversionCount]= AdcRegs.ADCRESULT1 >>4; //从ADCINB5 /*读取值ADC= 在计算电流时达到两个电桥之间的浮点 电压<1=1;Conversioned.ed.Conversionk;// // pi调节 器dummy =(Llong) uK; } EPwm5Regs.TBPHS.Half.TBPHS = dummy; // ePWM5和ePWM6将具有phaseshift EPwm6Regs.TBPHS.Half.TBPHHS = phaseshift1; //补偿ca。 ePWM6的16ns延迟 //如果记录了256个转换,请重新开始 IF (ConversionCount == 255) { ConversionCount = 0; } 否则 { ConversionCount++;} //重新初始化下一个ADC AdcRegs.ADCTRL2.bit.RST_SEQ1 =1; //重置SEQ1 AdcRegs.ADCST.bit.INT_SEQ1_CLR =1; //清除中断标志位 PieCtrlRegs.PIEACK/ALL = PIEACK_Group1; //中断确认PIE }
有了这些值,积分器输出(I10)变得过大,因此KI值必须更小。
所以我想知道KP和KI的实际值应该用于PI调节器。 事实上,从我的输出电流到ADC电压也有一个刻度,即在100A时,ADC测量值为3V。 因此,刻度为0.03。 该缩放是否应包含在DCL函数的KP和KI参数中? 如果是这样,则必须缩小PI的结果。 但在那种情况下,我又忽略了饱和限值。
总之,我面临的挑战是将理论结果转化为实际微控制器并使其发挥作用。 对于如何进一步调试/解决此问题有什么想法? 我希望避免"尝试和错误"的做法。
谢谢你。
您好,Alexander,
我认为您在Matlab中建模的PI实施不太正确。 如果您在第一个POST中查看DCL控制器的图表,则比例增益(KP)与控制器串联显示。 这被称为"系列"或"理想" PI控制器。 Matlab脚本看起来像一个"并行"类型,其中比例增益位于并行路径中。 在Matlab中,系列控制器将是:
num_pi =[KP KP*KI];
这将对结果产生影响。 如果要使用并行实现,您需要DCL的v 2.0 ,您可以在C2000Ware中找到:
http://www.ti.com/tool/c2000ware
应用Tustin转换时,将对结果应用缩放因子以匹配转换前后的增益,因此,如果您使用手动计算检查Matlab结果,则需要记住该因子。
正确的是,应用了缩放来考虑ADC和PWM增益的变化。 我附上了一张图表,说明如何在典型的电压控制环路中实现这一点。
您的C代码看起来正常。 我认为您需要做的只是更改控制器初始化过程中的KP和KI增益。
我希望这能推动你们向前发展。 如果我能提供更多帮助,请告诉我。
此致,
Richard
e2e.ti.com/.../C2000-Digital-Power-Control-Workshop-_2D00_-v3_2D00_2-_2D00_-scaling.pdf
嗨,Richard,
感谢您对PI调节器的评论,我更改为PI调节器的系列版本。 我认为我的一个大问题是C函数DCL_runPI,因为我不熟悉它中的程序集实现,因此也不熟悉PI算法的执行方式。 对我来说,汇编代码似乎是从SPRUI31文档中的公式(14)中逐步执行的。
模拟PI调节器的指定为
G_PI = Y (s)/E (s)=(KP*s+KP*KI)/s
我已在Matlab确定了我的KP和KI收益。
当我手动离散PI控制器时,我将在完成一些mastematic代数后具有以下传输功能:
G_PI (z)= Y (z)/E (z)=(2*KP (1-z^-1)+TsKpKI (1+z^-1))/(2*(1-z^-1))
重新排列术语,我将以线性差等式结束:
y[n]= y[n-1]+(-KP+TS/2KpKI) e[n-1]+(KP+TS/2KpKI) e[n]
现在,进行数学计算让我们:
(-KP+TS/2KpKI)=- 1.497
和
(KP+TS/2KpKI)= 1.502
当我使用C2D功能分解PI调节器时,这些结果与Matlab匹配。 但不确定这些值是否是我的代码中实际需要/需要的值。
因为我已经获得了LDE,所以我现在不再拥有KP和KI。 相反,DCL_runPI函数要求KP和KI,因此我很困惑,到底需要为DCL_runPI函数使用哪些值?
谢谢你
您好,Alexander,
欢迎您,感谢您发布此帖子。
很高兴知道一切顺利。
此致,
Richard