Trouble while generating two SOC triggers (CTR=0 and CTR=PRD) with their respective ISRs on Microcontroller TI F28388D
Ältere Kommentare anzeigen
Hi everyone, i am struggling generating to events one on CTR = 0 and one on CTR = PRD cause i want to read my ADC values twice in a cycle, so i wanna configure two SOC triggers: one at CTR=0 and one at CTR=PRD and i want a ISR at CTR=0 with load at PRD and another ISR at CTR=PRD with load at ZERO by using the shadow mode. this is my code, from epwm side i saw on oscilloscope and everything works fine on the 4 channels with frequency ,duty and death time working fine but from ADC side i cannot read any values from the registers and i think i am doing some mistakes with the various enables and interrupt..I tried to see an example from TI on which my ADC code is based to see how to sincronize epwm and adc but i wasnt able to solve it. this is the part of my code i dont get any syntax mistakes from the building so i guess the problem is logical.if someone could help me find the mistakes. Thank you in advice.
For the main.c
#include "f2838x_device.h"
#include "f2838x_sysctrl.h"
#include "f2838x_piectrl.h"
#include "f2838x_pievect.h"
#include "f2838x_examples.h"
#include "pwm.h"
#include "adc.h"
float duty1_perc, duty2_perc, duty3_perc, duty4_perc;
float freq;
void main(void)
{
// Step 1: Initialize System Control
InitSysCtrl();
// Step 2: Initialize GPIO
InitGpio();
// Step 3: Clear all interrupts and initialize PIE
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
// Step 4: Map ISR functions
EALLOW;
//PieVectTable.EPWM1_INT = &epwm1_isr;
PieVectTable.ADCA1_INT = &adca1_isr;
//PieVectTable.ADCA2_INT = &adca2_isr;
EDIS;
// Step 5: Configure peripherals
ADC_Init();
PWM_Init();
// Step 6: Configure PWM
PWM_SetFrequency(10000);
PWM_SetDutyCycle(1, 0.5);
PWM_SetDutyCycle(2, 0.5);
PWM_SetDutyCycle(3, 0.5);
PWM_SetDutyCycle(4, 0.5);
PWM_SetDeadTime(800e-9);
// Step 7: Setup ADC trigger from ePWM
ADC_SetupEPWMTrigger(0);
// Step 8: Enable global interrupts
IER |= M_INT1; // ADC
IER |= M_INT3; // PWM
EINT;
ERTM;
// Step 9: Enable PIE interrupts
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // ADCA1
PieCtrlRegs.PIEIER1.bit.INTx2 = 1; // ADCA2
PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // EPWM1
// Step 10: Sync ePWM
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
do
{
// Step 11: Start peripherals
PWM_Start();
ADC_Start();
DELAY_US(500000); // 500 ms
// === READ PWM ===
freq = PWM_GetFrequency();
duty1_perc = PWM_GetDutyCycle(1) * 100.0f;
duty2_perc = PWM_GetDutyCycle(2) * 100.0f;
duty3_perc = PWM_GetDutyCycle(3) * 100.0f;
duty4_perc = PWM_GetDutyCycle(4) * 100.0f;
// === READ ADC ===
float v_zero = ADC_GetMeasurementZero();
float v_prd = ADC_GetMeasurementPRD();
// Breakpoint
asm(" NOP");
} while(1);
}
// PWM1
// =====================
static void PWM1_Configure(float duty, float deadtime_ns)
{
EALLOW;
EPwm1Regs.ETSEL.bit.SOCAEN = 0;
EPwm1Regs.ETSEL.bit.SOCASEL = 4;
EPwm1Regs.ETPS.bit.SOCAPRD = 1;
EPwm1Regs.TBPHS.bit.TBPHS = 0;
EPwm1Regs.TBCTR = 0;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1;
EPwm1Regs.TBCTL.bit.CLKDIV = 2;
clockDivider[0] = (1 << 1) * (1 << 2);
tbclk[0] = EPWM_CLK / clockDivider[0];
tbprd[0] = tbclk[0] / (2 * g_frequency);
EPwm1Regs.TBPRD = tbprd[0];
EPwm1Regs.TBCTL.bit.CTRMODE = 2;
EPwm1Regs.TBCTL.bit.PHSEN = 0;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;
EPwm1Regs.CMPCTL.bit.LOADAMODE = 0;
EPwm1Regs.CMPCTL.bit.LOADBMODE = 0;
uint16_t cmp = tbprd[0] * (1 - duty);
EPwm1Regs.CMPA.bit.CMPA = cmp;
EPwm1Regs.CMPB.bit.CMPB = cmp;
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBD = AQ_SET;
// Deadtime
period = 1.0f / tbclk[0];
deadtime_cycles = deadtime_ns / period;
EPwm1Regs.DBCTL.bit.OUT_MODE = 3;
EPwm1Regs.DBCTL.bit.POLSEL = 2;
EPwm1Regs.DBCTL.bit.IN_MODE = 0;
EPwm1Regs.DBRED.bit.DBRED = (uint16_t)deadtime_cycles;
EPwm1Regs.DBFED.bit.DBFED = (uint16_t)deadtime_cycles;
EDIS;
}
void ADC_SetupEPWMTrigger(Uint16 channel)
{
EALLOW;
// SOC0 - trigger on ePWM1 SOCA (CTR=0)
AdcaRegs.ADCSOC0CTL.bit.CHSEL = channel; // SOC0 will convert pin A0
AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; // sample window
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // trigger on ePWM1 SOCA
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
EDIS;
// SOC1 - trigger on ePWM1 SOCB (CTR=PRD) - aggiunto per secondo trigger
AdcaRegs.ADCSOC1CTL.bit.CHSEL = channel; // stesso canale o diverso
AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps;
AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 7; // trigger on ePWM1 SOCB (PRD)
AdcaRegs.ADCINTSEL1N2.bit.INT2SEL = 0; // end of SOC0 will set INT1 flag
AdcaRegs.ADCINTSEL1N2.bit.INT2E = 1; // enable INT1 flag
AdcaRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; // make sure INT1 flag is cleared
EDIS;
}
Antworten (1)
Mukul Choudhury
am 10 Apr. 2026
0 Stimmen
HI,
Can you please share the source of the code.
Is this code generated froma Simulink model? If it is a manually hand written code, you can connect with TI through their support forum. https://e2e.ti.com/.
Some issues which I could point out:
1) SOCB is not enabled in ADC_Start function.
2) There is no configuration for SOCB.
3) ADC SOC configurations in ADC_SetupEPWMTrigger() are not protected by EALLOW/EDIS.
4) ADC abd PWM start functions are inside the do while loop. it should be done one time and hence should be put outside the loop.
Hope this helps.
Thanks,
Mukul
Kategorien
Mehr zu Control Peripherals finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!