工具与软件:
您好!
我想使 PWM1信号具有仅200ns 的周期。 我已经尝试使用事件触发器寄存器和功能将信号设置为低电平。 我已经将事件触发器配置为在第一个周期中断信号、然后将 PWM 信号设置为低电平。 信号确实变为零、但在2到3个周期之后、由于程序完成代码行所需的时间:程序溢出。
您有什么建议、其他方法可用于实现单个高频 PWM 周期、还是有建议可避免事件触发信号连接的时间?
感谢您的认可、
Florentin。
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.
工具与软件:
您好!
我想使 PWM1信号具有仅200ns 的周期。 我已经尝试使用事件触发器寄存器和功能将信号设置为低电平。 我已经将事件触发器配置为在第一个周期中断信号、然后将 PWM 信号设置为低电平。 信号确实变为零、但在2到3个周期之后、由于程序完成代码行所需的时间:程序溢出。
您有什么建议、其他方法可用于实现单个高频 PWM 周期、还是有建议可避免事件触发信号连接的时间?
感谢您的认可、
Florentin。
您好、Florentin:
您能否共享 PWM init 和 ISR 代码以便了解您当前正在执行的操作?
为了实现一个时间段并关闭 PWM、我最初的想法是生成一个中断、以更改动作限定符 。我想看看当我们可以改变时序时你们是如何做到这一点的。 否则、您是否考虑了启动和停止 ePWM 时钟(TBCLKSYNC 位)、或者也许是否考虑了实施跳闸区来关闭 PWM?
我能不能问为什么 PWM 信号只具有一个周期? 想知道是否能够为此而不使用 ePWM 来切换 GPIO。
此致、
Allison
void init_PWM1() { EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the EPWM EDIS; EALLOW; EPwm1Regs.TZSEL.bit.CBC1 = 1; //TZ1 on CBC EPwm1Regs.TZSEL.bit.CBC2 = 1; //TZ2 on CBC EPwm1Regs.TZSEL.bit.OSHT5 = 1; //TZ5 connect to CLOCKFAIL //EPwm1Regs.TZSEL.bit.OSHT6 = 1; //TZ6 connect to EMUSTOP EPwm1Regs.TZCTL.bit.TZA = 2; // force Epwm1A state LOW EPwm1Regs.TZCTL.bit.TZB = 2; // force Epwm1B state LOW EPwm1Regs.TZEINT.bit.CBC = 1; //Enable CBC and OST EPwm1Regs.TZEINT.bit.OST = 1; EDIS; //------------------ TIME BASE/ CMP --------------------// EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load EPwm1Regs.TBPRD= 0; // PWM frequency = 1/(2*TBPRD)) EPwm1Regs.CMPA.all = (long) CMP << 16 | CMPHR << 8; //Enable HRPWM duty EPwm1Regs.CMPB.all = (long) CMP << 16 | CMPHR << 8; EPwm1Regs.TBPHS.all = 0; EPwm1Regs.TBCTR = 0; EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Select up-down count mode EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO ; EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT EPwm1Regs.TBCTL.bit.FREE_SOFT = 3; //-------------------- SHADOWS -------------------------// EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD; // LOAD CMPA on CTR = PRD EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD; EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; //------------------ ACTION QUALIFIER -------------------// EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // PWM toggle high/low EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; //DO NOT SET TO ZRO, HR period is not stable // Active les interruptions pour le module PWM1 EPwm1Regs.ETSEL.bit.INTEN = 1; EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD; // Déclenche une interruption lorsqu'il atteint le compteur zéro EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Déclenche l'interruption à chaque période //--------------------- HRPWM --------------------------// EALLOW; EPwm1Regs.HRCNFG.all = 0x0; EPwm1Regs.HRCNFG.bit.EDGMODE = HR_BEP; // BOht Edge for the HR period to work EPwm1Regs.HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR and TBPRDHR HR control. EPwm1Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD EPwm1Regs.HRCNFG.bit.EDGMODEB = HR_BEP; // BOht Edge for the HR period to work EPwm1Regs.HRCNFG.bit.CTLMODEB = HR_CMP; // CMPBHR and TBPRDHR HR control EPwm1Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD EPwm1Regs.HRCNFG.bit.SWAPAB = 0; // ePWMxA and ePWMxB outputs are unchanged EPwm1Regs.HRCNFG.bit.AUTOCONV = 1; // Enable autoconversion for HR period EPwm1Regs.HRPCTL.bit.TBPHSHRLOADE = 0; // Enable TBPHSHR sync (required for updwn count HR control) EPwm1Regs.HRPCTL.bit.HRPE = 1; // Turn on high-resolution period control. //-------------------- DEAD BAND -----------------------// EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; //ICI EPWMxA est la source des retards de front descendant et de front montant. EPwm1Regs.DBCTL.bit.OUT_MODE= DB_FULL_ENABLE ; // See table 15-8 EPwm1Regs.DBCTL.bit.POLSEL=0; // DB_ACTV_HIC; //Active High Complementary -> tableau 15-8 EPwm1Regs.DBCTL.bit.HALFCYCLE= 1; //this bit must be set 1 for HR deadband (clock 5ns for DB) EPwm1Regs.DBCTL.bit.OUTSWAP = 0; EPwm1Regs.DBCTL.bit.SHDWDBREDMODE = 1; EPwm1Regs.DBCTL.bit.SHDWDBFEDMODE = 1; EPwm1Regs.DBCTL.bit.LOADREDMODE = 2; EPwm1Regs.DBCTL.bit.LOADFEDMODE = 2; EPwm1Regs.DBRED.all = FED; //Unpacking the assembly EPwm1Regs.DBFED.all = FED; EPwm1Regs.HRCNFG2.bit.EDGMODEDB= HR_BEP; // DBREDHR and DBFEDHR EPwm1Regs.HRCNFG2.bit.CTLMODEDBFED =2; // Load on ZRO EPwm1Regs.HRCNFG2.bit.CTLMODEDBRED =2; EPwm1Regs.DBREDHR.bit.DBREDHR = FEDHR; //Unpacking the ascent of the two PW1Ms EPwm1Regs.DBFEDHR.bit.DBFEDHR = FEDHR; //Unpacking the descent of the two PW1Ms EPwm1Regs.TBCTL.bit.SWFSYNC = 1; // Synchronize high resolution phase to start HR period CpuSysRegs.PCLKCR0.bit.HRPWM= 1; // Enable TBCLK within the EPWM EPwm1Regs.TBPRDHR= PRD1_HR<<8; EDIS; } __interrupt void epwm1_isr (void) { Int_count_pwm1++; //nombre de période PWM2 EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; EALLOW; EPwm1Regs.DBCTL.bit.POLSEL= 0; EDIS; EPwm1Regs.ETSEL.bit.INTEN = 0; // // Clear INT flag for this timer EPwm1Regs.ETCLR.bit.INT = 1; // // Acknowledge this interrupt to receive more interrupts from group 3 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; }
我进行了一项测试,以了解微控制器处理代码的速度有多快。 在 GPIO0上设置该代码、然后将 GPIO0清零以查看两行代码之间的周期(参阅汇编代码+源)。 我使用 CSS、在调试代码后、我确实恢复、并发现在两个设定/清除之间有一个80ns 的周期、然后为 while (1)循环返回330ns。
我不明白为什么设置/清除操作之间没有10ns (对于 PWM 配置)、因为根据汇编的代码、此操作是或、根据"TMS320C28x CPU 和指令集"数据、它需要单个时钟周期。 而不是持续80ns 需要8个周期。 这是时钟配置问题还是使用 CCS Degug?
提前感谢
InitSysCtrl(); main(): //MAIN CODE 082d1e: 764825B1 LCR InitSysCtrl 23 initGPIO(); 082d20: 76482D2D LCR initGPIO 27 GpioDataRegs.GPASET.bit.GPIO0 = 1; //SET C$L1: 082d22: 761F01FC MOVW DP, #0x1fc 082d24: 1A020001 OR @0x2, #0x0001 28 GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; //CLEAR 082d26: 1A040001 OR @0x4, #0x0001 29 GpioDataRegs.GPASET.bit.GPIO0 = 1; //SET 082d28: 1A020001 OR @0x2, #0x0001 30 GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; //CLEAR 082d2a: 1A040001 OR @0x4, #0x0001 25 while(1) // BOUCLE WHILE 082d2c: 6FF6 SB C$L1, UNC 40 EALLOW; // Permettre l'accès aux registres protégés initGPIO(): 082d2d: 7622 EALLOW 43 GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // Mettre GPIO00 en mode GPIO 082d2e: 761F01F0 MOVW DP, #0x1f0 082d30: 1806FFFC AND @0x6, #0xfffc 44 GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // Configurer GPIO00 comme sortie 082d32: 1A0A0001 OR @0xa, #0x0001 47 GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; // Mettre GPIO00 à 0 (LOW) 082d34: 761F01FC MOVW DP, #0x1fc 082d36: 1A040001 OR @0x4, #0x0001 50 GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0; // Mettre GPIO00 en mode GPIO 082d38: 761F01F0 MOVW DP, #0x1f0 082d3a: 1806FFCF AND @0x6, #0xffcf 51 GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; // Configurer GPIO00 comme sortie 082d3c: 1A0A0004 OR @0xa, #0x0004 54 GpioDataRegs.GPASET.bit.GPIO2 = 1; // Mettre GPIO00 à 0 (LOW) 082d3e: 761F01FC MOVW DP, #0x1fc 082d40: 1A020004 OR @0x2, #0x0004 56 EDIS; // Désactiver l'accès aux registres protégés 082d42: 761A EDIS 58 }
您好、Florentin:
对于您之前发布的帖子、我认为这是正确的方法。 动作限定符设置的影子加载方案是什么、因为这些设置是您要在 ISR 中更新的设置? 是影子加载还是使用立即加载?
我 看到您还启用了跳闸区、将两个通道驱动为低电平。 您还可以使用它在一个周期后关闭 PWM -您只需要另一个信号作为跳闸源、并在 PWM 周期结束时变为低电平。
此致、
Allison