Tool/software:
Hi everyone,
I wrote a program that uses PWM to trigger an interrupt, but the ADCs inside the interrupt didn't return any values.
Can someone tell me what might be wrong with the settings?
// Included Files #include "f28x_project.h" #include "stdio.h" #include "math.h" // Defines #define RESULTS_BUFFER_SIZE 256 // Globals uint16_t adcAResults[RESULTS_BUFFER_SIZE]; // Buffer for results uint16_t index; // Index into result buffer volatile uint16_t bufferFull; // Flag to indicate buffer is full // ------------------------------------- Digital Variables ------------------------------------- // // ADC pins for detecting analog values (digital) unsigned int ADC_A6; // ADC_A6_Voltage_N unsigned int ADC_B6; // ADC_B6_Voltage_L unsigned int ADC_C0; // ADC_C0_Voltage_Out // ------------------------------------- Analog Variables -------------------------------------- // // Values for digital turning to analog (analog) float VAC_N_A6; // A6_Voltage_N float VAC_L_B6; // B6_Voltage_L float VO_C0; // C0_Voltage_Out int CMPA = 600.0; int CMPB = 1199.0; // Function Prototypes __interrupt void EPWM1ISR(void); void initEPWM(void); void initADC(void); void initADCSOC(void); // Main void main(void){ // Initialize device clock and peripherals InitSysCtrl(); // Initialize GPIO InitGpio(); EALLOW; // Setup GPIO ----------------------------------------------------------------------------- /// // GPIO20: It is for checking the EPWM1 interrupt is working properly or not. GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0; // Disable pull-up res. on GPIO20 GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0; // Configure GPIO20 as a GPIO pin GpioCtrlRegs.GPADIR.bit.GPIO20 = 1; // Configure GPIO20 as a output pin // GPIO0.GPIO1: They are set for output pins of the fast-legs ----------------------------- /// GpioCtrlRegs.GPAPUD.bit.GPIO0=1; // Disable pull-up res. on GPIO0 (EPWM1A) GpioCtrlRegs.GPAMUX1.bit.GPIO0=1; // Configure GPIO0 as EPWM1A GpioCtrlRegs.GPAPUD.bit.GPIO1=1; // Disable pull-up res. on GPIO1 (EPWM1B) GpioCtrlRegs.GPAMUX1.bit.GPIO1=1; // Configure GPIO1 as EPWM1B EDIS; // Disable CPU interrupts DINT; InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable(); // Map ISR functions EALLOW; PieVectTable.EPWM1_INT = &EPWM1ISR; // Function for EPWM1 interrupt 1 EDIS; // Configure the ePWM initEPWM(); // Configure the ADC and power it up initADC(); // Setup the ADC for ePWM triggered conversions on channel 1 initADCSOC(); // Configure the DAC //initDACA(); // Enable global Interrupts and higher priority real-time debug events: IER |= M_INT3; // Enable group 3 interrupts EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM // Initialize results buffer for(index = 0; index < RESULTS_BUFFER_SIZE; index++){ adcAResults[index] = 0; } index = 0; bufferFull = 0; // Enable PIE interrupt PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // Sync ePWM EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; // Take conversions indefinitely in loop while(1){ } } // // EPWM1ISR - EPWM1 Interrupt ISR // __interrupt void EPWM1ISR(void){ // For checking the start of the interrupt. GpioDataRegs.GPASET.bit.GPIO20 = 1; // For reading the ADC values of A6 & B6 & C0 pins of SOC0... // and A3 & B14 pins of SOC1. SOC2. SOC3 ADC_A6 = AdcaResultRegs.ADCRESULT0; // ADC of VAC_N ADC_B6 = AdcbResultRegs.ADCRESULT0; // ADC of VAC_L ADC_C0 = AdccResultRegs.ADCRESULT0; // ADC of Vout //For checking the end of the interrupt. GpioDataRegs.GPACLEAR.bit.GPIO20 = 1; EPwm1Regs.ETCLR.bit.INT = 1; PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; // Acknowledge the interrupt } // // End of program // // // initEPWM - Function to configure ePWM1 to generate the SOC. // void initEPWM(void){ EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Set TBCLKSYNC = 0 CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; // Enable ePWM module clocks in the PCLKCRx register //EPwm1Regs.EPWMSYNCINSEL.all = SYNC_IN_SRC_DISABLE_ALL; //EPwm1Regs.EPWMSYNCOUTEN.all = SYNC_OUT_SRC_DISABLE_ALL; // ePWM Phase setting EPwm1Regs.TBCTL.bit.PHSEN = 0; // (0)Disable phase loading EPwm1Regs.TBPHS.bit.TBPHS = 0; // Phase is 0 // TBCLK = EPWMCLK / (HSPCLKDIV * CLKDIV) EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV = 1 EPwm1Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1 // Config for the frequency and duty cycle of the EPWM1 EPwm1Regs.TBCTL.bit.CTRMODE = 0; // Counter mode: (0)Count up EPwm1Regs.TBCTR = 0; // Time Base Counter Register EPwm1Regs.TBPRD = 1199; // Set period counts EPwm1Regs.CMPA.bit.CMPA = CMPA; EPwm1Regs.CMPB.bit.CMPB = CMPB; // Setup Counter-Compare(CC) Submodule ---------------------------------------------------- /// EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0; EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0; EPwm1Regs.CMPCTL.bit.LOADAMODE = 0; // Load registers every ZERO EPwm1Regs.CMPCTL.bit.LOADBMODE = 0; // Load registers every ZERO // Setup Action-Qualifier(AQ) Submodule --------------------------------------------------- /// EPwm1Regs.AQCTLA.bit.ZRO = 2; // Action when TBCTR = 0 ; 2: force EPWM1A output high. EPwm1Regs.AQCTLA.bit.CAU = 1; // Action when TBCTR = CMPA on Up-count; 1: force EPWM1A output low. EPwm1Regs.AQCTLB.bit.CAU = 1; // Action when TBCTR = CMPA on Up-count; 1: force EPWM1B output low. EPwm1Regs.AQCTLB.bit.CBU = 2; // Action when TBCTR = CMPB on Up-count; 2: force EPWM1B output high. // Setup Dead-Band(DB) Submodule --------------------------------------------------- /// EPwm1Regs.DBCTL.bit.IN_MODE = 2; EPwm1Regs.DBCTL.bit.POLSEL = 2; // EPWMxA directly output(D); EPWMxB inverted output(1-D) EPwm1Regs.DBCTL.bit.OUT_MODE = 3; // Enable the dead-time. EPwm1Regs.DBRED.bit.DBRED = 48; // 1u = DBRED * (1/120M) => DBRED = 120 EPwm1Regs.DBFED.bit.DBFED = 47; // 24 = 200n(= 10u*2% );48 = 400n(= 10u*4% ) //EPwm1Regs.EPWMSYNCOUTEN.bit.ZEROEN = 1; EPwm1Regs.ETSEL.bit.SOCAEN = 1; EPwm1Regs.ETSEL.bit.SOCASEL = 1; // Event Trigger and Interrupt(ET) Submodule: EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable SOCA EPwm1Regs.ETSEL.bit.INTSEL = 1; // 001: Enable event time-base counter equal to zero EPwm1Regs.ETPS.bit.INTPRD = 1; // Generate pulse on 1st event EDIS; } // // initADC - Function to configure and power up ADCA. // void initADC(void){ // Setup VREF as internal for ADC-A & ADC-B & ADC-C SetVREF(ADC_ADCA, ADC_INTERNAL, ADC_VREF3P3); SetVREF(ADC_ADCB, ADC_INTERNAL, ADC_VREF3P3); SetVREF(ADC_ADCC, ADC_INTERNAL, ADC_VREF3P3); EALLOW; // ADC-A Group Settings AdcaRegs.ADCCTL2.bit.PRESCALE = 6; // Set ADCCLK divider to /4 AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; // Set pulse positions to late AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1; // Power up the ADC and then delay for 1 ms // ADC-B Group Settings AdcbRegs.ADCCTL2.bit.PRESCALE = 6; // Set ADCCLK divider to /4 AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1; // Set pulse positions to late AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1; // Power up the ADC and then delay for 1 ms // ADC-C Group Settings AdccRegs.ADCCTL2.bit.PRESCALE = 6; // Set ADCCLK divider to /4 AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1; // Set pulse positions to late AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1; // Power up the ADC and then delay for 1 ms EDIS; DELAY_US(1000); } // // initADCSOC - Function to configure ADCA's SOC0 to be triggered by ePWM1. // void initADCSOC(void){ EALLOW; /// SOCs Configuration -------------------------------------------------------------------- /// /// A6 & B6 & C0 Settings of SOC0 /// A6 - SOC0 AdcaRegs.ADCSOC0CTL.bit.CHSEL = 6; // SOC0 will convert pin A6 AdcaRegs.ADCSOC0CTL.bit.ACQPS = 19; // Sample window is 20 SYSCLK cycles AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // Triggered by ePWM1 /// B6 - SOC0 AdcbRegs.ADCSOC0CTL.bit.CHSEL = 6; // SOC0 will convert pin B6 AdcbRegs.ADCSOC0CTL.bit.ACQPS = 19; // Sample window is 20 SYSCLK cycles AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // Triggered by ePWM1 /// C0 - SOC0 AdccRegs.ADCSOC0CTL.bit.CHSEL = 0; // SOC0 will convert pin C0 AdccRegs.ADCSOC0CTL.bit.ACQPS = 19; // Sample window is 20 SYSCLK cycles AdccRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // Triggered by ePWM1 ///The INT1 settings. "INT1SEL" must configure according to the end of the SOCs.(ex: this program is end of SOC1) //AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 2; // End of SOC1 will set INT1 flag //AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; // Enable INT1 flag //AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Make sure INT1 flag is cleared EDIS; }
Best Regards,
Eric Tsai