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.

epwm无法进入中断

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

typedef struct
{
volatile struct EPWM_REGS *EPwmRegHandle;
}EPWM_INFO;

// Prototype statements for functions found within this file.
__interrupt void ecap1_isr(void);
__interrupt void epwm1_isr(void);

void InitEPwm1Example(void);
void InitECapture(void);

void update_compare(EPWM_INFO*);
void Fail(void);


// Global variables used in this example
EPWM_INFO epwm1_info;

Uint32 Period;
Uint32 T;
Uint32 TEMP=0;

Uint16 a[100]={593,580,567,554,541,528,516,503,490,477,465,453,441,429,417,405,394,382,371,360,350,339,329,320,310,301,292,283,275,267,259,252,245,238,232,226,220,215,210,206,202,198,195,192,190,188,186,185,184,183,183,184,185,186,188,190,192,195,198,202,206,210,215,220,226,232,238,245,252,259,267,275,283,292,301,310,320,329,339,350,360,371,382,394,405,417,429,441,453,465,477,490,503,516,528,541,554,567,580,593};
Uint16 b[100];
Uint16 Counter=0;

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

// Step 2. Initialize GPIO:
// This example function is found in the DSP2833x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example

InitEPwm1Gpio();
InitECap1Gpio();

// 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 DSP2833x_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 DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_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.ECAP1_INT = &ecap1_isr;
PieVectTable.EPWM1_INT = &epwm1_isr;
EDIS; // This is needed to disable write to EALLOW protected registers

// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2833x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
InitECapture();

EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;

InitEPwm1Example();

EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
// Step 5. User specific code, enable interrupts:

// Initialize counters:
// Enable CPU INT4 which is connected to ECAP1-4 INT:
IER |= (M_INT3|M_INT4);

// Enable eCAP INTn in the PIE: Group 3 interrupt 1-6
PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
// Step 6. IDLE loop. Just sit and loop forever (optional):
for(;;)
{
__asm(" NOP");
}
}

__interrupt void epwm1_isr(void)
{
// Update the CMPA and CMPB values
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 InitEPwm1Example()
{
// Setup TBCLK
EPwm1Regs.TBPRD = 0x256; // Set timer period 801 TBCLKs
EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
EPwm1Regs.TBCTR = 0x0000; // Clear counter

// Set Compare values
EPwm1Regs.CMPA.half.CMPA = a[Counter]; // Set compare A value
EPwm1Regs.CMPB = a[Counter] ; // Set Compare B value

// Setup counter mode
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count updown
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x5; // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

// Setup shadowing
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;


// Set actions
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on event A, up count
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on event A, down count

EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; // Set PWM1B on event B, up count
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR; // Clear PWM1B on event B, down count

// 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_1ST; // Generate INT on 1rd 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.EPwmRegHandle = &EPwm1Regs; // Set the pointer to the ePWM module

}
void InitECapture()
{
ECap1Regs.ECEINT.all = 0x0000; // Disable all capture interrupts
ECap1Regs.ECCLR.all = 0xFFFF; // Clear all CAP interrupt flags
ECap1Regs.ECCTL1.bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped

// Configure peripheral registers
ECap1Regs.ECCTL2.bit.CAP_APWM = 0;
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0; // continuous mode 运行于连续模式
ECap1Regs.ECCTL2.bit.STOP_WRAP = 0; // Stop at 1 events 在单次模式下,捕捉事件1之后停止
ECap1Regs.ECCTL1.bit.CAP1POL = 1; // Falling edge 在下降沿触发捕捉事件1
ECap1Regs.ECCTL1.bit.CTRRST1 = 0; // absolute time sample 捕捉事件1的时间标签已被捕捉之后复位计数器
// ECap1Regs.ECCTL1.bit.CAP2POL = 1; // Falling edge 在下降沿触发捕捉事件1
// ECap1Regs.ECCTL1.bit.CTRRST2 = 0; // absolute time sample 捕捉事件1的时间标签已被捕捉之后复位计数器
ECap1Regs.ECCTL2.bit.SYNCI_EN = 1; // Enable sync in 计数器内部同步选择模式
ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; // Pass through 选择内部同步信号为外部同步信号
ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable capture units 在捕捉事件中使能寄存器1-4的装载
ECap1Regs.ECCTL1.bit.PRESCALE = 0;

ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; // Start Counter TSCTR计数器运行
// ECap1Regs.ECCTL2.bit.REARM = 1; // arm one-shot 单次强制控制
ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable CAP1-CAP4 register loads 使能寄存器1-4的装载
ECap1Regs.ECEINT.bit.CEVT1 = 1; // 2 events = interrupt 捕捉事件2作为中断源
}
void update_compare(EPWM_INFO *epwm_info)
{
// Every 10'th interrupt, change the CMPA/CMPB values
if(Counter == 100)
{
Counter = 0;
}
else
{
Counter++;
}
epwm_info->EPwmRegHandle->CMPA.half.CMPA = a[Counter];
epwm_info->EPwmRegHandle->CMPB = a[Counter];

return;
}

__interrupt void ecap1_isr(void)
{
// Cap input is syc'ed to SYSCLKOUT so there may be
// a +/- 1 cycle variation
T=ECap1Regs.CAP1;
Period=T-TEMP;
TEMP=T;


ECap1Regs.ECCLR.bit.CEVT1 = 1; //
ECap1Regs.ECCLR.bit.INT = 1;

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

void Fail()
{
__asm(" ESTOP0");
}


//===========================================================================
// No more.
//===========================================================================

  • 检查一下PWM有没有输出,没有的话可能是PWM的clock没开。其他中断设置都没问题

  • /*
     * main.c
     */
    #include "DSP2833x_Device.h"
    #include "DSP2833x_Examples.h"
    #include "math.h"
    #include "ePWMs.h"
    #include "SVPWM2L.h"

    interrupt void epwm1_timer_isr(void);

    #define  Vdcgive  650 //直流电压期望输出值
    #define  Periodmax 7500//PWM模块最大计数值
    #define PI 3.1415926
    #define N 100
    #define delta 2*PI/N

    EPWMS Epwm_modules=EPWMSdefaults;
    SVPWM2L Svpwm=SVPWM2Ldefaults;

     int i=0;

    int main(void)
    {
        InitSysCtrl();
         DINT;// Disable CPU interrupts
         InitPieCtrl();//初始化中断控制寄存器
         IER = 0x0000;//关闭CPU中断
         IFR = 0x0000;//清除CPU中断标志位
         InitPieVectTable();//初始化中断向量表
         EALLOW;
         PieVectTable.EPWM1_INT = &epwm1_timer_isr;  //配置中断向量地址
         EDIS;
         //DELAY_US(50000);//延时50ms//延时50ms,等待控制板上其他模块完成初始化
         EALLOW;
         SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;  //在配置ePWM模块前先禁止TBCLK时钟
         EDIS;
            EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // 选择计数器值=0启动ADC转换
            EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; //每次中断事件发生时都产生一次中断请求
            EPwm1Regs.ETCLR.bit.INT = 1; //清中断信号状态标志位
         //************************配置软件强制寄存器******************************
            //EPwm1Regs.AQSFRC.bit.RLDCSF=0x3;//软件连续强制寄存器工作在立即模式下
            //EPwm2Regs.AQSFRC.bit.RLDCSF=0x3;//软件连续强制寄存器工作在立即模式下
            //EPwm3Regs.AQSFRC.bit.RLDCSF=0x3;//软件连续强制寄存器工作在立即模式下
        //************************************************************************
            IER |= M_INT3;// 使能CPU INT3模块的中断功能
            PieCtrlRegs.PIEIER3.bit.INTx1= 1; //使能PIE模块中EPWM INT1

            EALLOW;
            PieVectTable.EPWM1_INT = &epwm1_timer_isr;  //配置中断向量地址
            EDIS;

            Epwm_modules.PeriodMax = Periodmax;  //设定计数器的最大计数值
            ePWMs_Init(&Epwm_modules); //调用ePWM模块的初始化函数,开始初始化

            EALLOW;
            SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0x1; //配置完成后,重新使能TBCLK时钟信号
           EDIS;

           EINT;   //开全局中断
           ERTM;   //开实时中断

         while(1);
    }

    interrupt void epwm1_timer_isr(void)
    {
        Svpwm.Ualpha=0.6*cos(i*delta);
        Svpwm.Ubeta=0.6*sin(i*delta);
        Svpwm.Vdcref=Vdcgive;
        svpwm2l_calc(&Svpwm);//运行时间为6.7us
        Epwm_modules.Tcmpa=Svpwm.Tcmpa;
        Epwm_modules.Tcmpb=Svpwm.Tcmpb;
        Epwm_modules.Tcmpc=Svpwm.Tcmpc;
        ePWMs_Update(&Epwm_modules);
        i++;
            if(i>100)
             i=0;
        EPwm1Regs.ETCLR.bit.INT = 1; //清除中断EPWM1_INT标志位
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;//允许本PIE组再次向CPU发送中断请求

    }

    请问这个程序哪里有问题 不能进入中断

  • 我和题主遇到了相同的问题,ADC中断可以进,就是ECAP中断进不去,ECAP的初始化函数、配置为CAP模式都没问题,但是为什么ECAP无法进入,还有就是pwm的clock具体是在哪里开呢,谢谢