//! //! This example configures ePWM1 to produce an 2 sec //! waveform with independent modulation on EPWMxA and //! EPWMxB. //! //! The compare values CMPA modified within the ePWM's ISR. //! //! The TB counter is in up count mode for this example. //! //! View the EPWM1A(PA0_GPIO0) /* For Default maxSysclkout = 200 Mhz. and maxEpwmclkout = 100Mhz to change the maxEpwmclkout use ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 1 0r 2 TBCLK = 10Mhz / (HSPCLKDIV * CLKDIV) = 10M/(10*1) = 10Mhz As we know TBPRD = FTBCLK/FTPWM = 10Mhz / 25Khz to change the the FTPWM then change period TBPRD so we get required pwm for particular frequency. In this we are using 100% duty cycle. means CMPA = TBPRD. for up-down = TBPRD = (10M/25k)*1/2 = 200 for up = TBPRD = (10M/25k)-1 = 399 #####----IMP- there is two PWM o/p EPWMA and EMPWMB Duty modulation for EPWMxA is set by CMPA, and is active low, that is, low time duty proportional to CMPA. Duty modulation for EPWMxB is set by CMPB and is active high, that is, high time duty proportional to CMPB. We can set EPWMxA is by CMPA and CMPB. */ // Included Files #include "F28x_Project.h" #include "DPlib.h" // // Defines // #define EPWM1_TIMER_TBPRD 1250 // Period register #define EPWM1_MAX_CMPA 1000 #define EPWM1_MIN_CMPA 5 #define EPWM1_MAX_CMPB 625 #define EPWM1_MIN_CMPB 5 #define EPWM_CMP_UP 1 #define EPWM_CMP_DOWN 0 float32 buffer1[10]; // DLOG instance DLOG_1ch_F_C dlog1ch ; //int var = 0; // Globals typedef struct { volatile struct EPWM_REGS *EPwmRegHandle; Uint16 EPwm_CMPA_Direction; Uint16 EPwm_CMPB_Direction; Uint16 EPwmTimerIntCount; Uint16 EPwmMaxCMPA; Uint16 EPwmMinCMPA; Uint16 EPwmMaxCMPB; Uint16 EPwmMinCMPB; }EPWM_INFO; EPWM_INFO epwm1_info; // Function Prototypes void InitEPwm1Example(void); __interrupt void epwm1_isr(void); void update_compare(EPWM_INFO*); void my_clock(void); int count = 0; // Main void main(void) { // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the F2837xD_SysCtrl.c file. InitSysCtrl(); // InitSysPll(INT_OSC2,IMULT_1,FMULT_0,PLLCLK_BY_1); // Step 2. Initialize GPIO: // This example function is found in the F2837xD_Gpio.c file and // illustrates how to set the GPIO to it's default state. // InitGpio(); // Enable PWM1 CpuSysRegs.PCLKCR2.bit.EPWM1=1; DLOG_1ch_F_C_INIT(dlog1ch); dlog1ch.OutputBuff = buffer1 ; dlog1ch.PreScaler = 8; dlog1ch.TrigVal = 0.54; dlog1ch.Size = 50; // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3 // These functions are in the F2837xD_EPwm.c file InitEPwm1Gpio(); // Step 3. Clear all interrupts and initialize PIE vector table: // Disable CPU interrupts DINT; // Initialize the PIE control registers to their default state. // The default state is all PIE interrupts disabled and flags // are cleared. // This function is found in the F2837xD_PieCtrl.c file. InitPieCtrl(); // Disable CPU interrupts and clear all CPU interrupt flags: IER = 0x0000; IFR = 0x0000; // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in F2837xD_DefaultIsr.c. // This function is found in F2837xD_PieVect.c. InitPieVectTable(); // // Interrupts that are used in this example are re-mapped to // ISR functions found within this file. // EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.EPWM1_INT = &epwm1_isr; EDIS; // This is needed to disable write to EALLOW protected registers // For this example, only initialize the ePWM // The TBCLKSYNC bit in the peripheral clock enable registers allows all users to globally synchronize all // enabled ePWM modules to the time-base clock (TBCLK). EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 1; // 200 / 2 = 100Mhz EDIS; InitEPwm1Example(); EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; // // Step 4. User specific code, enable interrupts: // // Enable CPU INT3 which is connected to EPWM1-3 INT: // IER |= M_INT3; // // Enable EPWM INTn in the PIE: Group 3 interrupt 1-3 // PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // // Enable global Interrupts and higher priority real-time debug events: // EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM // // Step 5. IDLE loop. Just sit and loop forever (optional): // for(;;) { asm (" NOP"); } } // epwm1_isr - EPWM1 ISR to update compare values __interrupt void epwm1_isr(void) { //static int16 var; // // Update the CMPA and CMPB value s // count++; //var = GpioDataRegs.GPADAT.bit.GPIO0 ; dlog1ch.Input = count; DLOG_1ch_F_C(dlog1ch); //update_compare(&epwm1_info); // 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; } void my_clock(void) { // Clock Setting need -> 500khz clock for pwm // INTOSC1 (10 MHz) -> Clock Setting for System Clock/PLLSYSCLK //EALLOW; /*ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF = 1; ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 0x00; // 10 Mhz -- INTOSC2 ClkCfgRegs.SYSPLLMULT.bit.IMULT = 0x1; // 10 (1+0) ClkCfgRegs.SYSPLLMULT.bit.FMULT = 0x00; ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = 0x00; // 10Mhz /1 = 10MHz ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0x1; // Enable clock */ ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 1; // 100M // EDIS; } // // InitEPwm1Example - Initialize EPWM1 values // void InitEPwm1Example() { // // Setup Time Base - TBCLK // EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD; // Set timer period EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm1Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm1Regs.TBCTR = 0x0000; // Clear counter //EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x5; // Clock ratio to SYSCLKOUT //EPwm1Regs.TBCTL.bit.CLKDIV = 0x01; EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x05; // Clock ratio to SYSCLKOUT -- 100m/(10*1) = 10M EPwm1Regs.TBCTL.bit.CLKDIV = 0x00; // // Setup shadow register load on ZERO // EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // // Set Compare values // EPwm1Regs.CMPA.bit.CMPA = EPWM1_MAX_CMPA; // Set compare A value EPwm1Regs.CMPB.bit.CMPB = EPWM1_MAX_CMPB; // Set Compare B value // Set actions //EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Clear on Zero //EPwm1Regs.AQCTLA.bit.CBD = AQ_SET; // Set on CMPB down EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // SET OF CMPA UP EPwm1Regs.AQCTLA.bit.CBD = AQ_CLEAR; // CLEAR ON CMPB DOWN //EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; // Set PWM1B on Zero //EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Clear PWM1B on event B, // // Interrupt where we will change the Compare Values // EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm1Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event // // Information this example uses to keep track // of the direction the CMPA/CMPB values are // moving, the min and max allowed values and // a pointer to the correct ePWM registers // epwm1_info.EPwm_CMPA_Direction = EPWM_CMP_UP; // Start by increasing // CMPA & CMPB //epwm1_info.EPwm_CMPB_Direction = EPWM_CMP_UP; epwm1_info.EPwmTimerIntCount = 0; // Zero the interrupt counter epwm1_info.EPwmRegHandle = &EPwm1Regs; // Set the pointer to the // ePWM module epwm1_info.EPwmMaxCMPA = EPWM1_MAX_CMPA; // Setup min/max // CMPA/CMPB values epwm1_info.EPwmMinCMPA = EPWM1_MIN_CMPA; epwm1_info.EPwmMaxCMPB = EPWM1_MAX_CMPB; epwm1_info.EPwmMinCMPB = EPWM1_MIN_CMPB; } // update_compare - Update the compare values for the specified EPWM void update_compare(EPWM_INFO *epwm_info) { // TO GET VARING PWM UNCOMMENT THE BELOW /* // Every 10'th interrupt, change the CMPA/CMPB values if(epwm_info->EPwmTimerIntCount == 10) { epwm_info->EPwmTimerIntCount = 0; // // If we were increasing CMPA, check to see if // we reached the max value. If not, increase CMPA // else, change directions and decrease CMPA // if(epwm_info->EPwm_CMPA_Direction == EPWM_CMP_UP) { if(epwm_info->EPwmRegHandle->CMPA.bit.CMPA < epwm_info->EPwmMaxCMPA) { epwm_info->EPwmRegHandle->CMPA.bit.CMPA++; } else { epwm_info->EPwm_CMPA_Direction = EPWM_CMP_DOWN; epwm_info->EPwmRegHandle->CMPA.bit.CMPA--; } } // If we were decreasing CMPA, check to see if // we reached the min value. If not, decrease CMPA // else, change directions and increase CMPA else { if(epwm_info->EPwmRegHandle->CMPA.bit.CMPA == epwm_info->EPwmMinCMPA) { epwm_info->EPwm_CMPA_Direction = EPWM_CMP_UP; epwm_info->EPwmRegHandle->CMPA.bit.CMPA++; } else { epwm_info->EPwmRegHandle->CMPA.bit.CMPA--; } } // If we were increasing CMPB, check to see if // we reached the max value. If not, increase CMPB // else, change directions and decrease CMPB if(epwm_info->EPwm_CMPB_Direction == EPWM_CMP_UP) { if(epwm_info->EPwmRegHandle->CMPB.bit.CMPB < epwm_info->EPwmMaxCMPB) { epwm_info->EPwmRegHandle->CMPB.bit.CMPB++; } else { epwm_info->EPwm_CMPB_Direction = EPWM_CMP_DOWN; epwm_info->EPwmRegHandle->CMPB.bit.CMPB--; } } // If we were decreasing CMPB, check to see if // we reached the min value. If not, decrease CMPB // else, change directions and increase CMPB else { if(epwm_info->EPwmRegHandle->CMPB.bit.CMPB == epwm_info->EPwmMinCMPB) { epwm_info->EPwm_CMPB_Direction = EPWM_CMP_UP; epwm_info->EPwmRegHandle->CMPB.bit.CMPB++; } else { epwm_info->EPwmRegHandle->CMPB.bit.CMPB--; } } */ // else // { epwm_info->EPwmTimerIntCount++; // } return; } // End of file /* Clock Setting need -> 500khz clock for pwm * * INTOSC1 (10 MHz) -> Clock Setting for System Clock/PLLSYSCLK * ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 0; // 10 Mhz -- INTOSC2 ClkCfgRegs.SYSPLLMULT.IMULT = 1; // 10 (1+0) ClkCfgRegs.SYSPLLMULT.FMULT = 0; ClkCfgRegs.SYSCLKDIVSEL.PLLSYSCLKDIV = 0; // 10Mhz /1 = 10MHz ClkCfgRegs.SYSPLLCTL1.PLLCLKEN = 1 // Enable clock ClkCfgRegs.PERCLKDIVSEL.EPWMCLKDIV = 0 * * So TBCLK = 10MHz *------------------------------------------------------------------------- For PWM Setting to get TBCLK -> EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x05; // Clock ratio to SYSCLKOUT as in Register data sheet EPwm1Regs.TBCTL.bit.CLKDIV = 0x01; CLKDIV = 10Mhz/2 HSPCLKDIV = CLKDIV/10 Fpwm = 500Khz -------------------------------------------------------------------------- TBPRD = Ftbclk / Fpwm - 1 = 10Mhz/500kHz = 199 (TBPRD) CMPA = (100% - 50(Duty Cycle) )* (199 + 1) - 1 = 99 ------------------------------------------------------------------------- Every 2 us pwm is generated * */