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.

CCS/TMS320F28377S: PWM Frequency is not as per calculation

Part Number: TMS320F28377S

Tool/software: Code Composer Studio

Sir,

Im getting nearly 1khz. frequency in oscilloscope and I need at least 20 Khz frequency. I don't want to change TBPRD register of epwm 2 as it will impact the resolution of the duty cycle w.r.t PWM period. Here is the code for adc to pwm conversion, Im working on.

Please tell how to change the frequency of pwm. Ive used the code given in technical reference manual at page no. 110 of TMS320F2837xS Delfino Microcontrollers to change imult, fmult, pll, epwmclkdiv but frequency is not increasing to too much value I'm hoping for.

//###########################################################################
// FILE:   adc_soc_epwm_cpu01.c
// TITLE:  ADC triggering via epwm for F2837xS.
//
//! \addtogroup cpu01_example_list
//! <h1> ADC ePWM Triggering (adc_soc_epwm)</h1>
//!ADC pin 27 PWM output 80
//! This example sets up the ePWM to periodically trigger the ADC.
//!
//! After the program runs, the memory will contain:\n
//! - \b AdcaResults \b: A sequence of analog-to-digital conversion samples from
//! pin A0. The time between samples is determined based on the period
//! of the ePWM timer.
//
//###########################################################################
// $TI Release: F2837xS Support Library v190 $
// $Release Date: Mon Feb  1 16:59:09 CST 2016 $
// $Copyright: Copyright (C) 2014-2016 Texas Instruments Incorporated -
//             http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################

#include "F28x_Project.h"     // Device Headerfile and Examples Include File

void ConfigureADC(void);
void ConfigureEPWM(void);
void InitEPwm2Example(void);
__interrupt void epwm2_tzint_isr(void);
void InitEPwmGpio_TZ(void);

void InitTzGpio(void);

void SetupADCEpwm(Uint16 channel);
interrupt void adca1_isr(void);

//buffer for storing conversion results
#define RESULTS_BUFFER_SIZE 256
Uint16 AdcaResults[RESULTS_BUFFER_SIZE];
Uint16 resultsIndex;
Uint32  EPwm2TZIntCount;
Uint16 Volt;
volatile Uint16 bufferFull;

void main(void)
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xS_SysCtrl.c file.
    InitSysCtrl();

// Step 2. Initialize GPIO:
// This example function is found in the F2837xS_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
    InitGpio(); // Skipped for this example
    CpuSysRegs.PCLKCR2.bit.EPWM2=1;
    InitTzGpio();
    InitEPwmGpio_TZ();

// 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 F2837xS_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 F2837xS_DefaultIsr.c.
// This function is found in F2837xS_PieVect.c.
    InitPieVectTable();

//Map ISR functions
    EALLOW;
    PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1
    PieVectTable.EPWM2_TZ_INT = &epwm2_tzint_isr;
    EDIS;
        EALLOW;
           ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL=0x1;
           ClkCfgRegs.SYSPLLMULT.bit.IMULT=50;
           ClkCfgRegs.SYSPLLMULT.bit.FMULT=0x2;
           ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV=1;
           ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1;
           ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 1;
       //    ClkCfgRegs.PERCLKDIVSEL.bit.PERCLKDIVSEL=68;

        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =0;
        EDIS;
        InitEPwm2Example();
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =1;
        EDIS;
        EPwm2TZIntCount = 0;


//Configure the ADC and power it up
    ConfigureADC();

//Configure the ePWM
    ConfigureEPWM();

//Setup the ADC for ePWM triggered conversions on channel 0
    SetupADCEpwm(0);

//Enable global Interrupts and higher priority real-time debug events:
    IER |= M_INT1; //Enable group 1 interrupts
    IER |= M_INT2;

    EINT;  // Enable Global interrupt INTM
    ERTM;  // Enable Global realtime interrupt DBGM

//Initialize results buffer
    for(resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++)
    {
        AdcaResults[resultsIndex] = 0;
    }
    resultsIndex = 0;
    bufferFull = 0;

//enable PIE interrupt
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
    PieCtrlRegs.PIEIER2.bit.INTx2 = 1;

//sync ePWM
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;

//take conversions indefinitely in loop
    do
    {
        //start ePWM
        EPwm1Regs.ETSEL.bit.SOCAEN = 1;  //enable SOCA
        EPwm1Regs.TBCTL.bit.CTRMODE = 0; //unfreeze, and enter up count mode

        //wait while ePWM causes ADC conversions, which then cause interrupts,
        //which fill the results buffer, eventually setting the bufferFull
        //flag
        while(!bufferFull);
        bufferFull = 0; //clear the buffer full flag

        //stop ePWM
        EPwm1Regs.ETSEL.bit.SOCAEN = 0;  //disable SOCA
        EPwm1Regs.TBCTL.bit.CTRMODE = 3; //freeze counter

        //at this point, AdcaResults[] contains a sequence of conversions
        //from the selected channel

        //software breakpoint, hit run again to get updated conversions
        //asm("   ESTOP0");
        EINT;  // Enable Global interrupt INTM
        ERTM;  // Enable Global realtime interrupt
    }while(1);
}

//Write ADC configurations and power up the ADC for both ADC A and ADC B
void ConfigureADC(void)
{
    EALLOW;

    //write configurations
    AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
    AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);

    //Set pulse positions to late
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;

    //power up the ADC
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;

    //delay for 1ms to allow ADC time to power up
    DELAY_US(1000);

    EDIS;
}

void ConfigureEPWM(void)
{
    EALLOW;
    // Assumes ePWM clock is already enabled
    EPwm1Regs.ETSEL.bit.SOCAEN  = 0;            // Disable SOC on A group
    EPwm1Regs.ETSEL.bit.SOCASEL = 4;            // Select SOC on up-count
    EPwm1Regs.ETPS.bit.SOCAPRD = 1;             // Generate pulse on 1st event
    EPwm1Regs.CMPA.bit.CMPA = 0x0800;          // Set compare A value to 2048 counts
    EPwm1Regs.TBPRD = 0x1000;                   // Set period to 4096 counts
    EPwm1Regs.TBCTL.bit.CTRMODE = 3;            // freeze counter
    EDIS;
}

void SetupADCEpwm(Uint16 channel)
{
    Uint16 acqps;

    //determine minimum acquisition window (in SYSCLKS) based on resolution
    if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){
        acqps = 14; //75ns
    }
    else { //resolution is 16-bit
        acqps = 63; //320ns
    }

    //Select the channels to convert and end of conversion flag
    EALLOW;
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = channel;  //SOC0 will convert pin A0
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //trigger on ePWM1 SOCA/C
    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
}

interrupt void adca1_isr(void)
{
    AdcaResults[resultsIndex++] = AdcaResultRegs.ADCRESULT0;
    if(RESULTS_BUFFER_SIZE <= resultsIndex)
    {
        resultsIndex = 0;
        bufferFull = 1;
    }
    Volt=AdcaResultRegs.ADCRESULT0;
    set_duty(Volt);
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}


void set_duty(int a)
{
    EPwm2Regs.CMPA.bit.CMPA = a;
}

void InitEPwm2Example()
{
    // Enable TZ1 as one cycle-by-cycle trip sources
    EALLOW;
    EPwm2Regs.TZSEL.bit.CBC1 = 1;

    // What do we want the TZ1 to do?
    EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_HI;

    // Enable TZ interrupt
    EPwm2Regs.TZEINT.bit.CBC = 1;
    EDIS;

    EPwm2Regs.TBPRD = 4096;                       // Set timer period
    EPwm2Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
    EPwm2Regs.TBCTR = 0x0000;                     // Clear counter

    // Setup TBCLK
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
    EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4;       // Clock ratio to SYSCLKOUT
    EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV4;          // Slow just to observe on the scope

    // Setup compare
  //  EPwm2Regs.CMPA.bit.CMPA = 3000;

    // Set actions
    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;             // Set PWM2A on CAU
    EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;           // Clear PWM2A on CAD
}

__interrupt void epwm2_tzint_isr(void)
{
    GpioDataRegs.GPATOGGLE.bit.GPIO11 = 1;

    EPwm2TZIntCount++;

    // Clear the flags - we will continue to take
    // this interrupt until the TZ pin goes high
    EALLOW;
    EPwm2Regs.TZCLR.bit.CBC = 1;
    EPwm2Regs.TZCLR.bit.INT = 1;
    EDIS;

    // Acknowledge this interrupt to receive more interrupts from group 2
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP2;
}

void InitTzGpio(void)
{
    // For External Trigger, GPIO12 as the trigger for TripZone
    GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0;    // Enable pull-up on GPIO12 (TZ1)

    GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 3;  // Asynch input GPIO12 (TZ1)

    EALLOW;
    InputXbarRegs.INPUT1SELECT = 12;
    EDIS;

    // For monitoring when the TZ Interrupt has been entered
    EALLOW;
    GpioCtrlRegs.GPAPUD.bit.GPIO11 = 1;    // Disable pull-up on GPIO0 (EPWM1A)
    GpioCtrlRegs.GPAMUX1.bit.GPIO11 = 0;   // Configure GPIO0 as EPWM1A
    GpioCtrlRegs.GPADIR.bit.GPIO11 = 1;
    EDIS;
}

void InitEPwmGpio_TZ(void)
{
    EALLOW;
  //  GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1;    // Disable pull-up on GPIO0 (EPWM1A)
  //  GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   // Configure GPIO0 as EPWM1A
    GpioCtrlRegs.GPAPUD.bit.GPIO2 = 1;    // Disable pull-up on GPIO2 (EPWM2A)
    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;   // Configure GPIO2 as EPWM2A
    EDIS;
}