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.

ADC counting and pwm generation at the same time in TMS320F28335

Dear All,

Could you kindly help me to understand how to create PWM from ADC counter that can produce from analog input according to SPRU791f.

1. Should I use ePWM_SOCB  ?

2. I want to use I/O pins from 1A to 6A of  EPWM output.

3. If I need zero-crossing and fire angle in then what to do with code?

Take a look in example,  attached  here.

//============================================================================================
// ����ó�� ����
//--------------------------------------------------------------------------------------------
#include "DSP28x_Project.h"                                                // Device Headerfile and Examples Include File
#define BUFFER_LENGTH        64
//============================================================================================


//============================================================================================
//        �Լ� ����
//--------------------------------------------------------------------------------------------
interrupt void adc_isr(void);                                        // ADC ���ͷ�Ʈ �Լ� ����
//============================================================================================


//============================================================================================
// �ý��ۿ��� ����� ���� ���� ����
//--------------------------------------------------------------------------------------------
Uint16 ADC_buffer[8][BUFFER_LENGTH];
Uint16 i,j;
Uint16 Loop_cnt, ADC_cnt;
Uint16 Bufferful_flag;
//============================================================================================

void main(void)
{
//============================================================================================
// Step 1. ���� ���ͷ�Ʈ ��Ȱ��ȭ
//--------------------------------------------------------------------------------------------
        DINT;
//============================================================================================


//============================================================================================
// Step 2. �ý��� ��Ʈ�� �ʱ�ȭ:
//--------------------------------------------------------------------------------------------
        InitSysCtrl();
        EALLOW;
        SysCtrlRegs.HISPCP.bit.HSPCLK = 1;       // HSPCLK = SYSCLKOUT/(HISPCP*2)
        EDIS;                                                                        // HSPCLK = 150MHz/(1*2) = 75MHz
//============================================================================================


//============================================================================================
// Step 3. ���ͷ�Ʈ �ʱ�ȭ:
//--------------------------------------------------------------------------------------------
        InitPieCtrl();
        IER = 0x0000;
        IFR = 0x0000;
        InitPieVectTable();

        // Vector Remapping      
        EALLOW;
        PieVectTable.ADCINT = &adc_isr;
        EDIS;
//============================================================================================


//============================================================================================
// Step 4. ADC �ʱ�ȭ
//--------------------------------------------------------------------------------------------
        InitAdc();
   
        // ADC ����
        AdcRegs.ADCTRL3.bit.ADCCLKPS = 3;                           // ADCCLK = HSPCLK/(ADCCLKPS*2)/(CPS+1)
        AdcRegs.ADCTRL1.bit.CPS = 1;                                // ADCCLK = 75MHz/(3*2)/(1+1) = 6.25MHz 
        AdcRegs.ADCTRL1.bit.ACQ_PS = 3;                                // ����/Ȧ�� ����Ŭ = ACQ_PS + 1 = 4 (ADCCLK����)
         
        AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;                        // ������ ��� ����: ���� ������ ��� (0:���� ���, 1:���� ���)
        AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;                        // ���� ���ø� ���  
        AdcRegs.ADCMAXCONV.all = 7;                                  // ADC ä�μ� ����: 8��(=MAX_CONV+1)ä���� ADC
        AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;                 // ADC ���� ����: 1��°�� ADCINA0 ä���� ADC
        AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 1;                 // ADC ���� ����: 2��°�� ADCINA1 ä���� ADC
        AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 2;                 // ADC ���� ����: 3��°�� ADCINA2 ä���� ADC
        AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 3;                 // ADC ���� ����: 4��°�� ADCINA3 ä���� ADC
        AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 8;                // ADC ���� ����: 5��°�� ADCINB0 ä���� ADC
        AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 9;                // ADC ���� ����: 6��°�� ADCINB1 ä���� ADC
        AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 10;                // ADC ���� ����: 7��°�� ADCINB2 ä���� ADC
        AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 11;                // ADC ���� ����: 8��°�� ADCINB3 ä���� ADC

        AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ = 1;                 // ePWM_SOCB�� ADC ������ �õ�
        AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;                // ADC ������ �Ϸ�� ���ͷ�Ʈ �߻� ���� 

        //ePWM_SOCB �̺�Ʈ Ʈ���� ����  
        EPwm3Regs.ETSEL.bit.SOCBEN = 1;                                // SOCB �̺�Ʈ Ʈ���� Enable 
        EPwm3Regs.ETSEL.bit.SOCBSEL = 2;                        // SCCB Ʈ���� ���� : ī���� �ֱ� ��ġ ��
        EPwm3Regs.ETPS.bit.SOCBPRD = 1;                                // SOCB �̺�Ʈ ���� ���� : Ʈ���� ���� �ѹ� ����   
        EPwm3Regs.TBCTL.bit.CTRMODE = 0;                        // ī��Ʈ ��� ����: Up-conut ���
        EPwm3Regs.TBCTL.bit.HSPCLKDIV = 1;                        // TBCLK = [SYSCLKOUT / ((HSPCLKDIV*2) * 2^(CLKDIV))]
        EPwm3Regs.TBCTL.bit.CLKDIV = 1;                                // TBCLK = [150MHz / (2*2)] = 37.5MHz                 
           EPwm3Regs.TBPRD = 1874;                                                // TB�ֱ�= (TBPRD+1)/TBCLK = 1875/37.5MHz = 50us(20KHz)
        EPwm3Regs.TBCTR = 0x0000;                                        // TB ī���� �ʱ�ȭ

        // PIE�� ADC ���ͷ�Ʈ Ȱ��ȭ
        PieCtrlRegs.PIEIER1.bit.INTx6 = 1;                        // PIE ���ͷ�Ʈ(ADCINT) Ȱ��ȭ
        IER |= M_INT1;                                                                 // CPU ���ͷ�Ʈ(INT1)  Ȱ��ȭ
//============================================================================================


//============================================================================================
// Step 5. PWM �ʱ�ȭ
//--------------------------------------------------------------------------------------------
        InitEPwm1Gpio();

        // Time-Base Submodule �ʱ�ȭ
        EPwm1Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE;                // TBRRD �� ��� �ݿ�(shadow�������� ��� ����)
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;                // Up-count mode: 
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1;                                // TBCLK = [SYSCLKOUT / ((HSPCLKDIV*2) * 2^(CLKDIV))]
        EPwm1Regs.TBCTL.bit.CLKDIV = 1;                                        // TBCLK = [150MHz / (2*2)] = 37.5MHz                 
        EPwm1Regs.TBPRD = 37499;                                                // TB �ֱ�  = (TBPRD+1)/TBCLK =  37500/37.5MHz = 1ms(1KHz)
        EPwm1Regs.TBCTR = 0;                                                        // TB ī���� �ʱ�ȭ

        // Counter-Compare Submodule �ʱ�ȭ 
        EPwm1Regs.CMPA.half.CMPA = 11249;                                // ��ƼA ������ ���� (30%)
        EPwm1Regs.CMPB = 26249;                                                        // ��ƼB ������ ���� (70%)
        EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;                // �� �������Ϳ� Shadow �������� ���
        EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;        // ī���Ͱ� 0 �϶� Shadow �������Ϳ��� �� �������Ϳ� �� �� �ε�
        EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;                // �� �������Ϳ� Shadow �������� ���
        EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;        // ī���Ͱ� 0 �϶� Shadow �������Ϳ��� �� �������Ϳ� �� �� �ε�

        // Action-qualifier �ʱ�ȭ
        EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;                                // ī���Ͱ� ������ �� High
        EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;                        // ī���Ͱ� ����� �� �񱳰��� ��ġ�ϸ� Low
        EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;                                // ī���Ͱ� ������ �� High
        EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;                        // ī���Ͱ� ����� �� �񱳰��� ��ġ�ϸ� Low
//============================================================================================


//============================================================================================
// Step 6. Initialize Application Variables
//-------------------------------------------------------------------------------------------- 
        for(i=0;i<8;i++){
                for(j=0;j<BUFFER_LENGTH;j++)
                ADC_buffer[i][j] = 0;
        }
        Loop_cnt = 0;
        ADC_cnt = 0;
        Bufferful_flag = 0;
//============================================================================================


//============================================================================================ 
// ���� ���ͷ�Ʈ Ȱ��ȭ , ����Ÿ�� ����� ���ͷ�Ʈ Ȱ��ȭ:
//--------------------------------------------------------------------------------------------
        EINT;   // Enable Global interrupt INTM
        ERTM;   // Enable Global realtime interrupt DBGM
//============================================================================================


//============================================================================================
// IDLE loop. Just sit and loop forever :
//--------------------------------------------------------------------------------------------
        for(;;)
        {
                if(Bufferful_flag==1){
                        Bufferful_flag = 0;
                }                
                Loop_cnt++;
        }
//============================================================================================

}
//============================================================================================
//        ���� �Լ� - �� 
//============================================================================================


//============================================================================================
//        ���ͷ�Ʈ ���� ��ƾ ����
//--------------------------------------------------------------------------------------------
interrupt void adc_isr(void)
{
        ADC_buffer[0][ADC_cnt] = AdcRegs.ADCRESULT0;
        ADC_buffer[1][ADC_cnt] = AdcRegs.ADCRESULT1;
        ADC_buffer[2][ADC_cnt] = AdcRegs.ADCRESULT2;
        ADC_buffer[3][ADC_cnt] = AdcRegs.ADCRESULT3;
        ADC_buffer[4][ADC_cnt] = AdcRegs.ADCRESULT4;
        ADC_buffer[5][ADC_cnt] = AdcRegs.ADCRESULT5;
        ADC_buffer[6][ADC_cnt] = AdcRegs.ADCRESULT6;
        ADC_buffer[7][ADC_cnt] = AdcRegs.ADCRESULT7;

        // ADC �Է� ������ �׷����� �׸��� ���� ī����
        ADC_cnt==BUFFER_LENGTH-1 ? ADC_cnt=0,Bufferful_flag=1 : ADC_cnt++;

        // Reinitialize for next ADC sequence
        AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1
        AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE
}
//============================================================================================
/*======================================================================
	File name	:	EPWM01_1Ch_PWM_Asymmetric_Single_Edge_Control.c                    
                    
	Originator	:	Digital Control Systems Group
					SyncWorks

	Target		:	TMS320F28335

	Version		:	1.00
======================================================================*/

/*======================================================================
	History		:
		2011-07-29,		Version 1.00
		
======================================================================*/

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

#define	SYSTEM_CLOCK	150E6	/* 150MHz */
#define	TBCLK			150E6	/* 150MHz */
#define	PWM_CARRIER		20E3	/* 20kHz */
#define	PWM_DUTY_RATIO	2E-1	/* 0.2, 20% */

#define	UFEC	0	/* Up-Count, Falling Edge Control */
#define	UREC	0	/* Up-Count, Rising Edge Control */
#define	DFEC	0	/* Down-Count, Falling Edge Control */
#define	DREC	1	/* Down-Count, Rising Edge Control */

/* Prototype statements for functions found within this Example */
void InitEPwm4Module(void);

/* Global variables used in this Example */
Uint16	BackTicker;
float32	PwmCarrierFrequency;
float32	PwmDutyRatio;

void main(void)
{

/*-----------------------------------------------------------------------------
	Step 1
	Disable Global Interrupt & Interrupt Flag Clear
-----------------------------------------------------------------------------*/
	DINT;
	IER = 0x0000;
	IFR = 0x0000;

/*-----------------------------------------------------------------------------
	Step 2
	2.1 InitSysCtrl()
		2.1.1 Disables the watchdog
    	2.1.2 Set the PLLCR for proper SYSCLKOUT frequency 
    	2.1.3 Set the pre-scaler for the high and low frequency peripheral clocks
    	2.1.4 Enable the clocks to the peripherals
	2.2 Initialize GPIO MUX
-----------------------------------------------------------------------------*/
	InitSysCtrl();

	EALLOW;
	GpioCtrlRegs.GPAPUD.bit.GPIO6 = 0;	/* Enable pull-up on GPIO6 (EPWM4A) */
    GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 1;	/* Configure GPIO6 as EPWM4A */
    EDIS;

/*----------------------------------------------------------------------------- 
	Step 3
	3.1 Initialize Peripheral Interrupt Expansion circuit	
-----------------------------------------------------------------------------*/
	/* Not required for this example */

/*----------------------------------------------------------------------------- 
	Step 4
	4.1 Pie Vector Table Re-allocation
-----------------------------------------------------------------------------*/
	/* Not required for this example */

/*----------------------------------------------------------------------------- 
	Step 5
	5.1 Interrupt Service routine re-mapping and Interrupt vector enable
-----------------------------------------------------------------------------*/
	/* Not required for this example */

/*----------------------------------------------------------------------------- 
	Step 6
    6.1 Initialize Periphrals for User Application
-----------------------------------------------------------------------------*/
	/* Initialize EPWM4 Module */
	InitEPwm4Module();

/*----------------------------------------------------------------------------- 
	Step 7
	7.1 Initialize S/W modules and Variables
-----------------------------------------------------------------------------*/
	BackTicker = 0;
	
	PwmCarrierFrequency = PWM_CARRIER;
	PwmDutyRatio = PWM_DUTY_RATIO;

/*----------------------------------------------------------------------------- 
	Step 8
	8.1 Enable Global realtime interrupt DBGM
	8.2 Enable Global Interrupt
-----------------------------------------------------------------------------*/
	ERTM;	/* Enable Global realtime interrupt DBGM */
	EINT;   /* Enable Global interrupt INTM */

/*----------------------------------------------------------------------------- 
	Step 9
	9.1 Idle Loop
-----------------------------------------------------------------------------*/
	/* IDLE loop. Just sit and loop forever: */
	for(;;)
	{
		BackTicker++;
		
		#if(UFEC)
			EPwm4Regs.TBPRD = (TBCLK / PwmCarrierFrequency) - 1;
			EPwm4Regs.CMPA.half.CMPA = (EPwm4Regs.TBPRD + 1) * PwmDutyRatio;
		#endif

		#if(UREC)
			EPwm4Regs.TBPRD = (TBCLK / PwmCarrierFrequency) - 1;
			EPwm4Regs.CMPA.half.CMPA = EPwm4Regs.TBPRD - ((EPwm4Regs.TBPRD + 1) * PwmDutyRatio);
		#endif

		#if(DFEC)
			EPwm4Regs.TBPRD = (TBCLK / PwmCarrierFrequency) - 1;
			EPwm4Regs.CMPA.half.CMPA = EPwm4Regs.TBPRD - ((EPwm4Regs.TBPRD + 1) * PwmDutyRatio);
		#endif

		#if(DREC)
			EPwm4Regs.TBPRD = (TBCLK / PwmCarrierFrequency) - 1;
			EPwm4Regs.CMPA.half.CMPA = (EPwm4Regs.TBPRD + 1) * PwmDutyRatio;
		#endif
	}
}

/*----------------------------------------------------------------------------- 
	Step 10
	10.1 Local Interrupt Service Routines & Functions
-----------------------------------------------------------------------------*/
void InitEPwm4Module(void)
{
	/* Setup Counter Mode and Clock */
	#if(UFEC)
		EPwm4Regs.TBCTL.bit.CTRMODE = 0;	/* Count Up (Asymmetric) */
	#endif

	#if(UREC)
		EPwm4Regs.TBCTL.bit.CTRMODE = 0;	/* Count Up (Asymmetric) */
	#endif

	#if(DFEC)
		EPwm4Regs.TBCTL.bit.CTRMODE = 1;	/* Count Down (Asymmetric) */
	#endif

	#if(DREC)
		EPwm4Regs.TBCTL.bit.CTRMODE = 1;	/* Count Down (Asymmetric) */
	#endif
	
	EPwm4Regs.TBCTL.bit.HSPCLKDIV = 0;		/* TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV) = 150MHz */
	EPwm4Regs.TBCTL.bit.CLKDIV = 0;

	/* Setup Phase */
	EPwm4Regs.TBPHS.half.TBPHS = 0;			/* Phase is 0 */
	EPwm4Regs.TBCTL.bit.PHSEN = 0;			/* Disable phase loading */

	/* Setup Period (Carrier Frequency) */
	EPwm4Regs.TBPRD = (TBCLK/PWM_CARRIER)-1;	/* Set Timer Period, (150MHz/20KHz)-1 = 7,499 (0x1D4B) */
	EPwm4Regs.TBCTR = 0;						/* Clear Counter */

	/* Set Compare Value */
	#if(UFEC)
		/* Set Compare A Value to 20% */
		EPwm4Regs.CMPA.half.CMPA = (Uint16)((EPwm4Regs.TBPRD + 1) * PWM_DUTY_RATIO);
	#endif

	#if(UREC)
		/* Set Compare A Value to 20% */
		EPwm4Regs.CMPA.half.CMPA = (Uint16)(EPwm4Regs.TBPRD - ((EPwm4Regs.TBPRD + 1) * PWM_DUTY_RATIO));
	#endif

	#if(DFEC)
		/* Set Compare A Value to 20% */
		EPwm4Regs.CMPA.half.CMPA = (Uint16)(EPwm4Regs.TBPRD - ((EPwm4Regs.TBPRD + 1) * PWM_DUTY_RATIO));
	#endif

	#if(DREC)
		/* Set Compare A Value to 20% */
		EPwm4Regs.CMPA.half.CMPA = (Uint16)((EPwm4Regs.TBPRD + 1) * PWM_DUTY_RATIO);
	#endif
	
	/* Setup shadowing */
	EPwm4Regs.TBCTL.bit.PRDLD = 0;			/* Period Register is loaded from its shadow when CNTR=Zero */
	EPwm4Regs.CMPCTL.bit.SHDWAMODE = 0;		/* Compare A Register is loaded from its shadow when CNTR=Zero */
	EPwm4Regs.CMPCTL.bit.LOADAMODE = 0;

	/* Set actions */
	#if(UFEC)
		EPwm4Regs.AQCTLA.bit.ZRO = 2;		/* Set EPWM4A on CNTR=Zero */
		EPwm4Regs.AQCTLA.bit.CAU = 1;		/* Clear EPWM4A on CNTR=CMPA, Up-Count */
	#endif

	#if(UREC)
		EPwm4Regs.AQCTLA.bit.CAU = 2;		/* Set EPWM4A on CNTR=CMPA, Up-Count */
		EPwm4Regs.AQCTLA.bit.PRD = 1;		/* Clear EPWM4A on CNTR=PRD */
	#endif

	#if(DFEC)
		EPwm4Regs.AQCTLA.bit.PRD = 2;		/* Set EPWM4A on CNTR=PRD */
		EPwm4Regs.AQCTLA.bit.CAD = 1;		/* Clear EPWM4A on CNTR=CMPA, Down-Count */
	#endif

	#if(DREC)
		EPwm4Regs.AQCTLA.bit.CAD = 2;		/* Set EPWM4A on CNTR=CMPA, Down-Count */
		EPwm4Regs.AQCTLA.bit.ZRO = 1;		/* Clear EPWM4A on CNTR=Zero */
	#endif
}

/*======================================================================
	End of file.
======================================================================*/



  • Hello,

    Can you further explain what you are looking to do? Generally, you'll want to use the ePWM to trigger the ADC conversion. This is what the ePWM SOCA and SOCB signals will do. You will then use the Event Trigger to create the SOC signal to the ADC at a specific point(s) in your ePWM cycle.

    Kris