Thread 中讨论的其他器件:SFRA、 C2000WARE、 controlSUITE
工具/软件:Code Composer Studio
主席先生,
我已经计算了升压转换器的受控体传递函数、并且还使用 MATLAB 中的 SISO 工具为其设计了一个2类补偿器。 然后我使用......将传输函数从 s 域转换为 z 域 方法并获得系数、还可 通过 DF22控制器在 CCS 中实现。
无论如何、请建议我检查此控制器的性能。
此致、
Soumya
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
主席先生,
我已经计算了升压转换器的受控体传递函数、并且还使用 MATLAB 中的 SISO 工具为其设计了一个2类补偿器。 然后我使用......将传输函数从 s 域转换为 z 域 方法并获得系数、还可 通过 DF22控制器在 CCS 中实现。
无论如何、请建议我检查此控制器的性能。
此致、
Soumya
您好、Soumya、
对 DCL_runDF22的调用在 ISR 中发生、因此以控制循环速率发生、但您可以在主程序中定义和修改 rk。 通常、这就是我们要做的事情。
对于电压模式升压转换器、控制环路仅具有级联连接中的控制器(请参阅随附的 C2000双向直流/直流套件文档)。 在 ADC ISR 代码中、您将读取 ADC (附件中的 Vhv_fb)、转换为浮点、从基准中减去、然后将其传递到 DF22控制器。 如下所示:
YK=((浮点) AdcRegs.ADCRESULT0)/4096.0f;
EK = rk - YK;
UK = DCL_runDF22_C1 (&controller1、EK);
此致、
Richard
主席先生,
我尝试在闭环电压控制模式下运行升压转换器。 此外、我已经成功地在 MATLAB 中仿真并运行模型。
现在、我已经在 条件循环中编写了您之前建议的代码。 但 EPwm2端口上仍然没有输出。
此外、我随附了最终代码。
//###################################################################################################################### //$TI 发布:F2833x/F2823x 头文件和外设示例 V142 $ //$发布 日期:2016年11月1日$ //$版权:版权所有(C) 2007-2016德州仪器(TI)公司- // http://www.ti.com/ 保留所有权利$ //############################################################################################################ #include "DSP28x_Project.h" //设备头文件和示例包括文件 #include "DCL.h" //#include "F2833x_Device.h" //#include "F2833x_examples.h" //#include "F2833x_GlobalPrototypes.h" #include "DCLF32.h" #include "DCL_fdlog.h" //原型文件中找到的函数。 _interrupt void ADC_ISR (void); void InitEPwm2Example (void); #define EPWM1_TIMER_TBPRD 1500 //周期寄存 器#define EPWM1_CMPA 1050 //input data #define DATA_LENG_DEFAULTS; //完整控制器结果 #pragma DATA_SECTION (U1_array、"QDataLogSection") float e_array[DATA_LENG];FDLOG eBuf = FDLOG_DEFAULTS;//完整控制器结果#pragma DATA_SECTION (U1_DATA );float_OUT_RATION_OUT_DATA_SECTION = FAULT_AULT_AULT_AULT_AULT_AULT_AULT_SECTION; FDLOG dBuf = FDLOG_DEFAULTS; // extern 中断 void CONTROL_ISR (void); __interrupt void ADC_ISR (void); //全局变量 long IdleLoopCount = 0; long IsrCount = 0; float u1k; float u2k; float Udk; upperLim; float lowerLim; uint16_t v; DCL_DF22 控制器1 = DF22_DEFAULTS;DCL_DF22控制器2 = DF22_DEFAULTS;int vadc=0;FDLOG eBUf = FDLOG_DEFAULTS;int out=0;//本示例中使用的全局变量:// uint16 Conversionc=0;float = 1.40f (rf);(float)(r16f = 1.40f);(rf)/float = 1.40f)。 初始化系统控制: // PLL、看门狗、启用外设时钟 //此示例函数位于 DSP2833x_sysctrl.c 文件中。 InitSysCtrl(); DINT; InitEPwm2Gpio(); /* ADC_BLOCK .................. */ EALLOW; #IF (CPU_FRQ_150MHz) //默认- 150MHz SYSCLKOUT #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)= 25.0MHz #endif (CPU_FRQ_100MHz) #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)= 25.0MHz #endif EDIS; //定义 ADCCLK 时钟频率(小于或等于25MHz) //假设 InitSysCtrl()已将 SYSCLKOUT_MOCLK 设置为150MHz; //高速外设时钟设置为25MHz EDIS; //步骤2。 初始化 GPIO: //此示例函数位于 DSP2833x_GPIO.c 文件中, //说明了如何将 GPIO 设置为其默认状态。 // InitGpio();//跳过此示例 //步骤3。 清除所有中断并初始化 PIE 矢量表: //禁用 CPU 中断 //将 PIE 控制寄存器初始化为默认状态。 //默认状态是禁用所有 PIE 中断并 清除标志//。 //此函数位于 DSP2833x_PIECTRL.c 文件中。 EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC=0; EDIS; InitEPwm2Examples(); EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC=1; EDIS; InitPieCtrl(); //禁用 CPU 中断并清除所有 CPU 中断标志: IER = 0x0000; IFR = 0x0000; //使用指向 shell 中断 //服务例程(ISR)的指针初始化 PIE 矢量表。 //这将填充整个表,即使在 本示例中未使用中断//也是如此。 这对于调试很有用。 //可以在 DSP2833x_DefaultIsr.c 中找到 shell ISR 例程 //此函数可在 DSP2833x_PieVect.c 中找到 InitPieVectTable(); //此示例中使用的中断被重新映射到 这个文件中的// ISR 函数。 EALLOW;//这是写入 EALLOW 受保护寄存 器 PieVectTable.ADCINT =&ADC_ISR; PieVectTable.TINT0 =&ADC_ISR; EDIS;//这是禁用写入 EALLOW 受保护寄存器 所必需的//步骤4。 初始化所有器件外设: //此函数可在 DSP2833x_InitPeripherals.c 中找到// InitPeripherals ();//此示例 InitAdc ()不需要;//对于此示例,初始化 ADC //步骤5。 特定于用户的代码、启用中断: //在 PIE PieCtrlRegs.PIEIER1.bit.INTx6中启用 ADCINT = 1; IER |= M_INT1;//启用 CPU 中断1 EINT; //启用全局中断 INTM ERTM; //启用全局实时中断 DBGM v = 0; //配置 ADC AdcRegs.ADCTRL1.bit.ACQ_PS = 0x2; AdcRegs.ADCTRL1.bit.CPS = 0x1; //AdcRegs.ADCTRL3.bit.ADCCLKPS= 0x1; AdcRegs.ADCMAX0000 = 0x0000;全部; //在 SEQ1 AdcRegs.ADCCHSELSEQ1.bit.CONV00上设置2 conv = 0x0;//将 ADCINA0设置为第一个 SEQ1转换器 //AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;//将 ADCINA1设置为第2个 SEQ1转换器 AdcRegs.ADCTRL2.bit.ePWM_SOCA_SEQ1 = 1;//从 ePWM 启用 SOCA 以启动 SEQ1 AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;//启用 SEQ1中断(每个 EOS) AdcRegs.ADCTRL3.bit.SMODE_SEQ1 = 1;// 假设已启用 eETQ1 中断(每个 EOS = 1);AdcRegs.ADCTRL3.bit.SMODE_EN.USTRL = 1;//已启用 eUSTREN.USTRL = 1;eUSTREMP.ETRL = 1;eEN.EN.USTRL //在组 EPwm1Regs.ETSEL.bit.SOCASEL = 2上启用 SOC; //从 CPMA 中选择 SOC,向上计数 EPwm1Regs.ETPS.bit.SOCAPRD = 1; //在第一个事件 EPwm1Regs.CMPA.half.CMPA = 0x08FF 时生成脉冲; //设置比较 A 值 EPwm1Regs.TBPRD = 0x0FFF; //为 ePWM1 EPwm1Regs.TBCTL.bit.SYNCOSEL 设置周期= 0x01; EPwm1Regs.TBCTL.bit.CTRMODE = 0; //递增计数并开始 //等待 ADC 中断 /* for (;) { }*/ *.......... 控制器部分................... // 配置 CPU 定时器0 InitCpuTimer(); ConfigCpuTimer (&CpuTimer0、90.0、1.0e+03); //初始化数据数组 DCL_initLog (&eBuf、e_array、data_length); DCL_initLog (&u1Buf、U1_array、data_length); DCL_initLog (&u2Buf、U2_array、data_length); DCL_initLog (&dBuf、d_array、data_length); DCL_clearLog (&u1Buf); DCL_clearLog (&u2Buf); DCL_fillLog (&dBuf、1.234567f); //初始化完整的控制器 Controller1.A1 =-0.5075f; Controller1.A2 =-0.4925f; Controller1.b0 = 0.01614f; Controller1.B1 = 3.84e-5F; Controller1.B2 =-0.0161f; //初始化预计算控制器 controller2.A1 = controller1.A1; controller2.A2 = controller1.A2; controller2.b0 = controller1.b0; controller2.b1 = controller1.b1; controller2.b2= controller1.b2; //钳位限制 upLIM = 1000.0f; LIM 下限=-1000.0f; //启用中断 PieCtrlRegs.PIEIER1.bit.INTx7=1; IER |= M_INT1; EINT; StartCpuTimer0(); //空闲循环 while (1) { IdleLoopCount++; } }// main __interrupt void ADC_ISR (void)结束 { /*.................................. 控制块.......................... * //清除计时器标志&确认中断 CpuTimer0Regs.TCR.bit.TIF = 1; PieCtrlRegs.PIEACX.ALL = PIEACK_Group1; //读取数据并运行控制器 if (eBuf.dptr < eBuf.lptr) { //读取输入数据 YK=((浮点) AdcRegs.ADCRESULT0)/4096.0f; EK = rk - YK; //运行完整的控制器 u1k = DCL_runDF22_C1 (&controller1、EK); OUT =(int) u1k; EPwm2Regs.CMPA.half.CMPA = u1k * 4096.0f; //运行预计算的控制器 u2k = DCL_runDF22_C2 (&controller2、EK); V = DCL_runClamp_C1 (&u2k、upperLim、lowerLim); 如果(0 == v) { DCL_runDF22_C3 (&controller2、EK、u2k); } //计算差异 dk = u1k - u2k; //存储结果 DCL_writeLog (&u1Buf、u1k); DCL_writeLog (&u2Buf、u2k); DCL_writeLog (&dBuf、dk); } 其他 { //在此处放置断点 asm (" NOP"); } IsrCount++; if (IdleLoopCount=0){ if (v =data_length) { V = 0; IdleLoopCount=1; } 否则 { vadc =(AdcRegs.ADCRESULT0>>4)/4096.0f; // IADC =~(AdcRegs.ADCRESULT1 >>4)- 3478)+1; e_array[v]= vadc; // adc_val2[ConversionCount]= IADC; V++; } } //重新初始化下一个 ADC 序列 AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; //重置 SEQ1 AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //清除 INT SEQ1位 PieCtrlRegs.PIEACK.all = PIEACK_Group1;//确认到 PIE 返回的中断; } void InitEPwm2Examples() { //设置 TBCLK EPwm2Regs.TBPRD = 0x0FFF; //设置定时器周期801 TBCLK EPwm2Regs.TBPHS.Half.TBPHS = 0x0000; //相位为0 EPwm2Regs.TBCTR = 0x0000; //清除计数 器//设置比较值 EPwm2Regs.CMPA.half.CMPA = vadc * 4096.0f; //设置比较旧数据1953 EPwm2Regs.CMPB = EPWM1_CMPA; //设置比较 B 值 //设置计数器模式 EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;//向上计数 n 向下计数 EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; //禁用相位加载 EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; //时钟与 SYSCLKOUT EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm2Regs.TBCTL.bit.SYNCOSEL = 0x00; //设置重影 EPwm2Regs.CMCTL.bit.EPTL.ADCMOREG= CC_ZERO; EPwCMOCC.ADDR.ADCMTL.ADCMTL.R0_ADCMTL.ADCMTL.ADDR.CLK = 0_ADCMTL.ADCMTL.ADCMTL.ADDR.AM_ADCMTL.RCODE=OCC_MOTL.RTO.R0_ADCMTL.RCMTL.RCMTL.RCMTL.RCMTL.RCMTL.RCMTL.RCMTL.RCMTL.RCMTL.RCMTL.RCMTL.RCMTL.RCMTL.RCMTL.RCMTL. //在事件 A 上设置 PWM1A、向上计数 EPwm2Regs.AQCTLA.bit.CAD = AQ_SET; //在事件 A 上清除 PWM1A,倒计数 }
请帮我解决问题、哪里出了问题?
N.B:-当我在无限循环中注释时,显示了一条名为“无法到达语句 InitCpuTimer();”的警告。
此致、
Soumya。
//###################################################################################################################### //描述//! 添加到组 F2833x_example_list//!
Soumya、
您已经发布了几个不同的问题、因此我将尝试按顺序处理这些问题。
1.-"请告诉我代码中需要哪些修改才能获得输出。"
这与 PWM2上没有输出有关。 假设您已正确配置 PWM 模块、并且计数器正在递增(我在之前的帖子中要求您检查)、则问题最有可能与 GPIO 引脚配置有关。 检查您是否已将所需的 PWM2引脚配置为输出(F28069上的 GPIO2和 GPIO3)-有关更多信息、请参阅用户指南和头文件示例。
2.-"...在闭环中运行受控体的代码修改应该是什么。"
应删除"if (eBuf.dptr < eBuf.lptr)"测试。 除非您使用测试数据、否则 ISR 只需读取输入、运行控制器以及计算和输出 PWM 占空比。
3.-"...根据我在第198和199行中必须选择的上限和下限值?"
我不清楚您在运行哪个控制器。 示例代码显示了 DF22补偿器的完整(C1)和预计算(C2和 C3)形式。 您只需要具有预计算类型的钳位。 上限和下限将限制控制器的输出。 由于我认为您使用的是标准化占空比、通常下限为零、上限为1.0f、但这取决于您如何缩放环路中的变量。 思考数字对于工厂意味着什么。
4.-"当我运行程序时、它进入 ILLEGAL_ISR (void)。 为什么会这样呢?"
通常会发生非法 ISR、因为已尝试访问无效存储器。 这可能是因为您正在对缓冲区的末尾进行索引。 可能是上面的#2。
BTW、这个线程变得很长。 我建议关闭它并打开一个新的问题、以便本论坛上的其他人可以在不浏览多个页面的情况下查看该问题。 谢谢。
此致、
Richard
Soumya、
请再次 ping 另一个线程。 我想、有时事情会意外落下、因此发送提醒没有任何问题。 这个主题很难遵循、因为有很多帖子。 我将在这里发表评论、但请专注于新话题。
帖子中没有足够的信息来确定代码为什么以 ILLEGAL_ISR 结束。 这很可能是因为您正在访问无效存储器、但要了解发生这种情况的位置和原因并不明显。 仔细检查代码中未初始化的变量或索引超出范围的数组。 此外、查看.map 文件以检查所有程序和数据段是否符合预期。 这可能是链接器命令文件中的错误。
如果您仍然找不到它、请尝试设置断点并单步执行代码以查看是否可以找到它。 如果没有、则必须删除代码、直到代码开始工作、然后从代码中生成代码、从而进行反向跟踪。 请记住、可以依赖 C2000Ware 中的 TI 示例来工作、因此值得仔细比较您的代码与类似示例(例如 F2833x PWM 示例)。 遗憾的是、没有简单的答案。
此致、
Richard