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.

[参考译文] LAUNCHXL-F28379D:更改 ADC 模块时不生成 ADC 中断

Guru**** 2524460 points
Other Parts Discussed in Thread: TMS320F28379D

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/996361/launchxl-f28379d-adc-interrupt-not-generating-when-adc-module-is-changed

器件型号:LAUNCHXL-F28379D
主题中讨论的其他器件:TMS320F28379D

你(们)好

我正在尝试为 TMSF28379D 实现示例程序"ADC_SoC_ePWM_CPU1"。  

示例代码工作正常。 但是、如果我只在代码(附加的代码)中将 Adca 模块更改为 ADCB 模块、则 ADCINTFLG 会被置位、并且代码不会进入 ISR。

我正在尝试了解 ADCINT 之间的关系以及它如何触发 PIE 进入 ISR。

我还尝试使用不同的 ADCINT、即使对于 Adca 模块也是如此、但代码不会进入 ISR。

因此、如果我必须得出结论、对于 PIER1的 ADCINT1、代码工作正常、但如果其中任何一个发生更改或 ADC 模块发生更改、则不会进入 ISR。

有人可以提供帮助吗?

#include "F28x_Project.h"

//
// Function Prototypes
//
void ConfigureADC(void);
void ConfigureEPWM(void);
void SetupADCEpwm(Uint16 channel);
interrupt void adcb2_isr(void);
float V =0.0;

//
// Defines
//
#define RESULTS_BUFFER_SIZE 256

//
// Globals
//
Uint16 AdcbResults[RESULTS_BUFFER_SIZE];
Uint16 resultsIndex;
volatile Uint16 bufferFull;

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

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

//
// 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 F2837xD_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 F2837xD_DefaultIsr.c.
// This function is found in F2837xD_PieVect.c.
//
    InitPieVectTable();

//
// Map ISR functions
//
    EALLOW;
    PieVectTable.ADCB1_INT = &adcb2_isr; //function for ADCA interrupt 1
    EDIS;

//
// 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
    EINT;  // Enable Global interrupt INTM
    ERTM;  // Enable Global realtime interrupt DBGM

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

//
// enable PIE interrupt
//
    PieCtrlRegs.PIEIER1.bit.INTx1 = 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");
    }while(1);
}

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

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

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

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

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

    EDIS;
}

//
// ConfigureEPWM - Configure EPWM SOC and compare values
//
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;
}

//
// SetupADCEpwm - Setup ADC EPWM acquisition window
//
void SetupADCEpwm(Uint16 channel)
{
    Uint16 acqps;

    //
    //determine minimum acquisition window (in SYSCLKS) based on resolution
    //
    if(ADC_RESOLUTION_12BIT == AdcbRegs.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;
    AdcbRegs.ADCSOC0CTL.bit.CHSEL = channel;  //SOC0 will convert pin A0
    AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
    AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //trigger on ePWM1 SOCA/C
    AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
    AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
    AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
    EDIS;
}

//
// adca1_isr - Read ADC Buffer in ISR
//
interrupt void adcb2_isr(void)
{
    AdcbResults[resultsIndex++] = AdcbResultRegs.ADCRESULT0;
    V = 0.2*AdcbResultRegs.ADCRESULT0;
    if(RESULTS_BUFFER_SIZE <= resultsIndex)
    {
        resultsIndex = 0;
        bufferFull = 1;
    }

    AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Sneha、

    在 PIE 矢量表中、分类基于组和通道。 ADC A1属于组1通道1、而 ADC B1属于组1通道2。 您可以在 TMS320F28379D 参考手册的第3.4.5节 PIE 通道映射下找到此分类。

    您已正确启用中断组、但未启用通道。

      IER |= M_INT1;//启用组1中断--启用组

      PieCtrlRegs.PIEIER1.bit.INTx1 = 1;--启用通道(这用于 ADC A1)

    请将以上行更改为  

    PieCtrlRegs.PIEIER1.bit.INTx2 = 1;

     

    请告诉我此更改是否能解决您的问题。

    谢谢、

    Aditya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好

    感谢您的回答。 解决了我的问题。

    我现在还有一个与此相关的问题。 我正在使用 CPU 定时器0为 ePWM1生成 CMPA。 我还使用 ePWM1作为 SOC 的触发器。  一切正常工作精细的 ADC 结果寄存器也会显示所需的值、但 ADC 不会进入 ISR。

    根据我的理解、CPU timer0的优先级高于 ADC ISR、因此对于代码不进入 ADC ISR、这可能是个问题。

    您能否建议一种可以使用 CPU 定时器0和 ADC ISR 的解决方案?

    代码已附加。

    #include "F28x_Project.h"
    #include "math.h"

    #define EPWM1_MAX_DB 20 // PV/PFC 的最大死区为150ns
    #define EPWM1_MIN_DB 15 // PV/PFC 的最小死区
    #define EPWM3_MAX_DB 20 // PV/PFC 最大死区150ns
    #define EPWM3_MIN_DB 15 // PV/PFC 的最小死区
    #define PHASE_BRIDGE 20;//两个 DAB 桥之间的 PS
    #define PHASE_LEASE 0x0000//20;桥的两个桥臂之间的 PS

    //跟踪比较值的移动方式
    #define ePWM_CMP_UP 1.
    #define ePWM_CMP_DOWN 0
    #define DB_UP 1.
    #define DB_DOWN 0

    #define results_buffer_size 256

    float result_V =0.0;
    float result_Vx = 0.0;

    float mod = 0.9;//调制指数
    浮点 PI = 3.14285714;
    float f_clk = 100000000.0f;// DSP 时钟频率= SYSCLK/2 = 100MHz
    float FG = 60.0f;//网格频率
    float f_PFC = 300000.0f;// PFC、PV 频率
    float f_SW = 300000.0f;// DAB 频率
    float dt = 0.000005;// SPWm 生成的采样频率、PFC = 1/f_PFC

    浮点时间= 0.00000000000;
    float ref = 0.0;
    float ref_offset = 0.0;
    悬空 TBDAB = 0;
    浮点 TBPFC = 0;
    浮点 dutyA_DAB = 0;
    浮点 dutyB_DAB = 0;
    浮点 dutyA_pv = 0;
    浮点 dutyB_PV = 0;

    typedef 结构

    volatile struct ePWM_regs * EPwmRegHandle;
    uint16 EPwmDB_DIRECTION;
    uint16 EPwmTimerIntCount;//此处的定义是用于更新死区的 update_compare11例程所必需的
    uint16 EPWMMAX_DB;
    uint16 EPWMIN_DB;
    }ePWM_INFO;//只能在此处定义,否则会导致类型名称错误
    ePWM_info epwm1_info;
    ePWM_INFO epwm3/info;
    ePWM_info epwm4_info;
    ePWM_INFO epwm5_info;
    ePWM_INFO epwm6_info;


    uint16 AdcaResults[results_buffer_size];
    uint16结果索引;
    易失性 uint16 bufferFull;

    void ConfigureADC (void);
    void SetupADCepwm (uint16通道);

    void InitEPwm1Examples(void);

    void InitEPwm3Examples(void);
    void InitEPwm4Examples(void);

    void InitEPwm5Examples(void);
    void InitEPwm6Examples(void);

    void update_compare1 (ePWM_info*);

    _interrupt void epwm1_ISR (void);

    _interrupt void epwm3_ISR (void);
    _interrupt void epwm4_ISR (void);

    _interrupt void epwm5_ISR (void);
    _interrupt void epwm6_ISR (void);


    //函数原型
    //
    _interrupt void CPU_timer0_ISR (void);
    中断 void adca1_ISR (void);

    uint32 EPwm1TimerIntCount;


    uint32 EPwm3TimerIntCount;
    uint32 EPwm4TimerIntCount;

    uint32 EPwm5TimerIntCount;
    uint32 EPwm6TimerIntCount;


    uint16 EPwm1_DB_DIRECTION;


    uint16 EPwm3_DB_DIRECTION;
    uint16 EPwm4_DB_DIRECTION;

    uint16 EPwm5_DB_DIRECTION;
    uint16 EPwm6_DB_DIRECTION;

    void main(void)
    {
    //
        // rounding the prd register to highest value
        TBDAB = ceil(f_clk/(2*f_sw)); // ceil value for dab period register
        TBPFC = ceil(f_clk / (2 * f_pfc)); // ceil value for pv, tpfc period register
        dutyA_DAB = ceil(TBDAB / 2); // duty cycle/compare for DAB
        dutyB_DAB = ceil(TBDAB / 2); // duty cycle/compare for DAB
    
        //D =0.5 tbpfc/2, D<0.5 tbpfc/2
        dutyA_pv = ceil(TBPFC / 2); // duty cycle/compare for pv
        dutyB_pv = ceil(TBPFC / 2); // duty cycle/compare for pv
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
    //
        InitSysCtrl();
    
    //
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
        // Initialise this code for using GPIO2 and 3 for ePWM2 TPFC line frequency pulse generation
        InitGpio();
      
    
        CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM3 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM4 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM5 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM6 = 1;
     
        InitEPwm1Gpio();
        InitEPwm3Gpio();
        InitEPwm4Gpio();
        InitEPwm5Gpio();
        InitEPwm6Gpio();
      
    //
    // 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 F2837xD_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 F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_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.TIMER0_INT = &cpu_timer0_isr;
    
        PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1
    
        PieVectTable.EPWM1_INT = &epwm1_isr;
        PieVectTable.EPWM3_INT = &epwm3_isr;
        PieVectTable.EPWM4_INT = &epwm4_isr;
        PieVectTable.EPWM5_INT = &epwm5_isr;
        PieVectTable.EPWM6_INT = &epwm6_isr;
        EDIS;
    
    //
    // Step 4. Initialize the Device Peripheral. This function can be
    //         found in F2837xD_CpuTimers.c
    //
        InitCpuTimers();   // For this example, only initialize the Cpu Timers
    
    //
    // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
    // 200MHz CPU Freq, 1 second Period (in uSeconds)
    //
        ConfigCpuTimer(&CpuTimer0, 200, 5);
    
        // Step 4. Initialize all the Device Peripherals:
        // This function is found in DSP2833x_InitPeripherals.c
        // InitPeripherals(); // Not required for this example
    
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
    
        InitEPwm1Example();
        InitEPwm3Example();
        InitEPwm4Example();
        InitEPwm5Example();
        InitEPwm6Example();
      
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    
    //
    // To ensure precise timing, use write-only instructions to write to the
    // entire register. Therefore, if any of the configuration bits are changed in
    // ConfigCpuTimer and InitCpuTimers (in F2837xD_cputimervars.h), the below
    // settings must also be updated.
    //
        CpuTimer0Regs.TCR.all = 0x4000;
    
        // Configure the ADC and power it up
        //
        ConfigureADC();
    
    
        // Setup the ADC for ePWM triggered conversions on channel 0
        //
        SetupADCEpwm(0); //Input ADC channel here
      
        
    //
    // Step 5. User specific code, enable interrupts:
    //
    // Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
    // which is connected to CPU-Timer 1, and CPU int 14, which is connected
    // to CPU-Timer 2:
    //
        IER |= M_INT1;
        
        // Initialize results buffer
        //
        for (resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++)
        {
            AdcaResults[resultsIndex] = 0;
        }
        resultsIndex = 0;
        bufferFull = 0;
    
    //
    // Enable TINT0 in the PIE: Group 1 interrupt 7
    //
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    
        PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
        PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
        PieCtrlRegs.PIEIER3.bit.INTx4 = 1;
        PieCtrlRegs.PIEIER3.bit.INTx5 = 1;
        PieCtrlRegs.PIEIER3.bit.INTx6 = 1;
      
    //
        PieCtrlRegs.PIEIER1.bit.INTx1 = 1; //ADC A1 group1 channel 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):
    //
        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");
            }while(1);
    }
    
    //
    // ConfigureADC - 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); // ADC module selection
        //
        //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;
    }
    // cpu_timer0_isr - CPU Timer0 ISR with interrupt counter
    //
    __interrupt void cpu_timer0_isr(void)
    {
        if (time < 10)
        {
            time = time + dt;
        }
        else
        {
            time = 0;
        }
    
        ref = mod * sin(2 * 3.14 * fg * time);
        ref_offset = (TBPFC * ref) / 2 + TBPFC / 2;
    
        // Update the CMPA and CMPB values
    
        // Clear INT flag for this timer
        EPwm1Regs.ETCLR.bit.INT = 1;
        //EPwm2Regs.ETCLR.bit.INT = 1;
    
        //PWM1........
        EPwm1Regs.CMPA.bit.CMPA = ref_offset;    // Set c00ompare A value
        EPwm1Regs.CMPB.bit.CMPB = ref_offset; //EPWM1_MAX_CMPB;               // Set Compare B value
    
     
        CpuTimer0.InterruptCount++;
    
        
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge this interrupt to receive more interrupts from group 1
    
    }
    
    __interrupt void epwm1_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&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;
    }
    
    
    
    __interrupt void epwm3_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&epwm3_info);
    
        // Clear INT flag for this timer
        //
        EPwm3Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    __interrupt void epwm4_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&epwm4_info);
    
        // Clear INT flag for this timer
        //
        EPwm4Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    __interrupt void epwm5_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&epwm5_info);
    
        // Clear INT flag for this timer
        //
        EPwm5Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    __interrupt void epwm6_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&epwm6_info);
    
        // Clear INT flag for this timer
        //
        EPwm6Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    interrupt void adca1_isr(void)
    {
        result_V = AdcaResultRegs.ADCRESULT0;
        result_Vx = 0.0007324 * result_V;
    
        if(RESULTS_BUFFER_SIZE <= resultsIndex)
        {
            resultsIndex = 0;
            bufferFull = 1;
        }
    
        AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    
    }
    
    
    // PWM1
    void InitEPwm1Example()
    {
    
        // Setup TBCLK
        EPwm1Regs.TBPRD = TBPFC;          // Set timer period 801 TBCLKs
        EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
        EPwm1Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm1Regs.CMPA.bit.CMPA = ref_offset;    // Set c00ompare A value
        EPwm1Regs.CMPB.bit.CMPB = ref_offset;   // Set Compare B value
    
        // Setup counter mode
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
        EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
        //EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // required to disable this master and for independent pwm generation
    
        // 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;
    
        //Enable ADC SOC
        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
    
    
        // Set actions
        EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; //AQ_SET;         // When sine<triangle set lower switch 51
        EPwm1Regs.AQCTLA.bit.CAD = AQ_SET; //AQ_CLEAR;   // Clear PWM1A on event A, down count
    
        EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; //AQ_CLEAR;       // // When sine>triangle set upper switch 49
        EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR; //AQ_SET;     // Clear PWM1B on event B, down count
    
        //essentially first upper switch conducts with leg 2 lower
    
        // Active high complementary PWMs - Setup the deadband
        //
        EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm1Regs.DBRED.bit.DBRED = EPWM1_MIN_DB;
        EPwm1Regs.DBFED.bit.DBFED = EPWM1_MIN_DB;
        EPwm1_DB_Direction = DB_UP;
    
        //
        // Interrupt where we will change the deadband
        //
        EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;      // Select INT on Zero event
        EPwm1Regs.ETSEL.bit.INTEN = 1;                 // Enable INT
        EPwm1Regs.ETPS.bit.INTPRD = ET_3RD;            // Generate INT on 3rd 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.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm1_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm1_info.EPwmRegHandle = &EPwm1Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm1_info.EPWMMAX_DB = EPWM1_MAX_DB;      // Setup min/max
        epwm1_info.EPWMMIN_DB = EPWM1_MIN_DB;      // Setup min/max
    
    }
    
    // PWM3
    void InitEPwm3Example(void)
    {
    
        // Setup TBCLK
        EPwm3Regs.TBPRD = TBDAB;          // Set timer period 801 TBCLKs
        EPwm3Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
        EPwm3Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm3Regs.CMPA.bit.CMPA = dutyA_DAB;               // Set c00ompare A value
        EPwm3Regs.CMPB.bit.CMPB = dutyB_DAB;               // Set Compare B value
    
        // Setup counter mode
        EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up down
        EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;        // Disable phase loading
        EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
        // Setup shadow register load on ZERO
        EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
        EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        // Set Actions
        EPwm3Regs.AQCTLA.bit.CAU = AQ_SET;            // Set PWM3A on period
        EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;   // Clear PWM3A on event B, down count
    
        EPwm3Regs.AQCTLB.bit.CBU = AQ_CLEAR;          // Clear PWM3A on period
        EPwm3Regs.AQCTLB.bit.CBD = AQ_SET;         // Set PWM3A on event A, up count
    
        // Active high complementary PWMs - Setup the deadband
        EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm3Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm3Regs.DBRED.bit.DBRED = EPWM3_MIN_DB;
        EPwm3Regs.DBFED.bit.DBFED = EPWM3_MIN_DB;
        EPwm3_DB_Direction = DB_UP;
    
        // Interrupt where we will change the Compare Values
        EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
        EPwm3Regs.ETSEL.bit.INTEN = 1;                // Enable INT
        EPwm3Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd 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
        //
        epwm3_info.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm3_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm3_info.EPwmRegHandle = &EPwm3Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm3_info.EPWMMAX_DB = EPWM3_MAX_DB;      // Setup min/max
        epwm3_info.EPWMMIN_DB = EPWM3_MIN_DB;      // Setup min/max
    
    }
    // PWM4
    void InitEPwm4Example(void)
    {
    
        // Setup TBCLK
        EPwm4Regs.TBPRD = TBDAB;          // Set timer period 801 TBCLKs
        EPwm4Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
        EPwm4Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm4Regs.CMPA.bit.CMPA = dutyA_DAB;               // Set c00ompare A value
        EPwm4Regs.CMPB.bit.CMPB = dutyB_DAB;               // Set Compare B value
    
        // Setup counter mode
        EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up down
        EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE;        // Disable phase loading
        EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
        // Setup shadow register load on ZERO
        EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
        EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        // Set Actions
        EPwm4Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Set PWM3A on period
        EPwm4Regs.AQCTLA.bit.CAD = AQ_SET;    // Clear PWM3A on event B, down count
    
        EPwm4Regs.AQCTLB.bit.CBU = AQ_SET;            // Clear PWM3A on period
        EPwm4Regs.AQCTLB.bit.CBD = AQ_CLEAR;       // Set PWM3A on event A, up count
    
        // Active high complementary PWMs - Setup the deadband
        EPwm4Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm4Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm4Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm4Regs.DBRED.bit.DBRED = EPWM3_MIN_DB;
        EPwm4Regs.DBFED.bit.DBFED = EPWM3_MIN_DB;
        EPwm4_DB_Direction = DB_UP;
    
        // Interrupt where we will change the Compare Values
        EPwm4Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
        EPwm4Regs.ETSEL.bit.INTEN = 1;                // Enable INT
        EPwm4Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd 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
        //
        epwm4_info.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm4_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm4_info.EPwmRegHandle = &EPwm4Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm4_info.EPWMMAX_DB = EPWM3_MAX_DB;      // Setup min/max
        epwm4_info.EPWMMIN_DB = EPWM3_MIN_DB;      // Setup min/max
    
    }
    
    // PWM5
    void InitEPwm5Example(void)
    {
    
        // Setup TBCLK
        EPwm5Regs.TBPRD = TBDAB;          // Set timer period 801 TBCLKs
        EPwm5Regs.TBPHS.bit.TBPHS = phase_bridge;             // Phase is 0
        EPwm5Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm5Regs.CMPA.bit.CMPA = dutyA_DAB;               // Set c00ompare A value
        EPwm5Regs.CMPB.bit.CMPB = dutyB_DAB;               // Set Compare B value
    
        // Setup counter mode
        EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up down
        EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE;        // Disable phase loading
        EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm5Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
    
        // Setup shadow register load on ZERO
        EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm5Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
        EPwm5Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        // Set Actions
        EPwm5Regs.AQCTLA.bit.CAU = AQ_SET;            // Set PWM3A on period
        EPwm5Regs.AQCTLA.bit.CAD = AQ_CLEAR;   // Clear PWM3A on event B, down count
    
        EPwm5Regs.AQCTLB.bit.CBU = AQ_CLEAR;          // Clear PWM3A on period
        EPwm5Regs.AQCTLB.bit.CBD = AQ_SET;         // Set PWM3A on event A, up count
    
        // Active high complementary PWMs - Setup the deadband
        EPwm5Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm5Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm5Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm5Regs.DBRED.bit.DBRED = EPWM3_MIN_DB;
        EPwm5Regs.DBFED.bit.DBFED = EPWM3_MIN_DB;
        EPwm5_DB_Direction = DB_UP;
    
        // Interrupt where we will change the Compare Values
        EPwm5Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
        EPwm5Regs.ETSEL.bit.INTEN = 1;                // Enable INT
        EPwm5Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd 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
        //
        epwm5_info.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm5_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm5_info.EPwmRegHandle = &EPwm5Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm5_info.EPWMMAX_DB = EPWM3_MAX_DB;      // Setup min/max
        epwm5_info.EPWMMIN_DB = EPWM3_MIN_DB;      // Setup min/max
    
    }
    // PWM6
    void InitEPwm6Example(void)
    {
    
        // Setup TBCLK
        EPwm6Regs.TBPRD = TBDAB;          // Set timer period 801 TBCLKs
        EPwm6Regs.TBPHS.bit.TBPHS = phase_bridge;            // Phase is 0
        EPwm6Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm6Regs.CMPA.bit.CMPA = dutyA_DAB;               // Set c00ompare A value
        EPwm6Regs.CMPB.bit.CMPB = dutyB_DAB;               // Set Compare B value
    
        // Setup counter mode
        EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up down
        EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE;        // Disable phase loading
        EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
        // Setup shadow register load on ZERO
        EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
        EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        // Set Actions
        EPwm6Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Set PWM3A on period
        EPwm6Regs.AQCTLA.bit.CAD = AQ_SET;    // Clear PWM3A on event B, down count
    
        EPwm6Regs.AQCTLB.bit.CBU = AQ_SET;            // Clear PWM3A on period
        EPwm6Regs.AQCTLB.bit.CBD = AQ_CLEAR;       // Set PWM3A on event A, up count
    
        // Active high complementary PWMs - Setup the deadband
        EPwm6Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm6Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm6Regs.DBRED.bit.DBRED = EPWM3_MIN_DB;
        EPwm6Regs.DBFED.bit.DBFED = EPWM3_MIN_DB;
        EPwm6_DB_Direction = DB_UP;
    
        // Interrupt where we will change the Compare Values
        EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
        EPwm6Regs.ETSEL.bit.INTEN = 1;                // Enable INT
        EPwm6Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd 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
        //
        epwm6_info.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm6_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm6_info.EPwmRegHandle = &EPwm6Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm6_info.EPWMMAX_DB = EPWM3_MAX_DB;      // Setup min/max
        epwm6_info.EPWMMIN_DB = EPWM3_MIN_DB;      // Setup min/max
    
    }
    
    //
    void update_compare1(EPWM_INFO *epwm_info)
    {
        if (epwm_info->EPwmDB_Direction == DB_UP)
        {
            if (epwm_info->EPwmRegHandle->DBFED.bit.DBFED < epwm_info->EPWMMAX_DB)
            {
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED++;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED++;
            }
            else
            {
                epwm_info->EPwmDB_Direction = DB_DOWN;
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED--;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED--;
            }
        }
        else
        {
            if (epwm_info->EPwmRegHandle->DBFED.bit.DBFED == epwm_info->EPWMMIN_DB)
            {
                epwm_info->EPwmDB_Direction = DB_UP;
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED++;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED++;
            }
            else
            {
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED--;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED--;
            }
        }
    
        epwm_info->EPwmTimerIntCount++;
    
        //   return;
    }
    //
    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
        EDIS;
    
    }
    
    
    // End of file

    谢谢  

    Sneha

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Sneha、

    [引用 userid="329063" URL"~/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/996361/launchxl-f28379d-adc-interrupt-not-generating-when-adc-module-is-changed/3683659 #36859"]一切正常工作的 ADC 结果寄存器也会显示所需的值,但 ADC 不会进入 ISR。

    如果 CPU 未进入 ISR、如何检查 ADC 寄存器的结果? 我看到结果正在 ISR 中进行检查。

    [引用 userid="329063" URL"~/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/996361/launchxl-f28379d-adc-interrupt-not-generating-when-adc-module-is-changed/3683659 #363659"]根据我的理解,CPU timer0的优先级高于 ADC ISR,因此这可能是代码未进入 ADC ISR 的问题。

    它实际上是另一种方法。 ADC 的优先级高于定时器。 ADCA1是组1通道1中断、而 timer0是组1通道7。 首先为编号最小的组中编号最小的通道提供服务。 在本例中、ADCA1具有更高的优先级。 附加参考手册中的图像、以便更好地理解。

    谢谢、

    Aditya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好

    [引用 userid="462934" URL"~/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/996361/launchxl-f28379d-adc-interrupt-not-generating-when-adc-module-is-changed/3683958 #3683958">如果 CPU 不进入 ISR、如何检查 ADC 寄存器的结果? 我看到在 ISR 中检查结果。[/QUERP]

    我正在检查具有结果的 ADC 结果寄存器。 我已经在 ADC ISR 中定义了一个变量 RESULT_VX1和 RESULT_Vxd1来检查结果。 我观察的这些变量即使 ADC 结果寄存器显示转换、也不显示任何值、这向我确认代码未进入 ISR。

    [引用 userid="462934" URL"~/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/996361/launchxl-f28379d-adc-interrupt-not-generating-when-adc-module-is-changed/3683958 #3683958"] ADC 的优先级高于计时器。

    感谢您分享。 那么我想问题是其他问题。 现在我还观察到 ePWM1不会产生任何脉冲。 CPU 定时器0实际上正在为 ePWM1生成 CMPA。 因此、我将尝试研究这个问题、并将在今天晚上分享结果。

    谢谢

    Sneha

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的更新。 如果您需要任何其他支持、请告诉我。

    Aditya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好  

    有人能不能查看此代码并指出我的错误。 我想使用 ePWM1来触发 ADC_A 和 ePWM3来触发 ADC_D 并在 ePWM1和 ePWM3上生成相应的 PWM 脉冲。 我所面临的问题是:

    1.当 ePWM1被用来  触发 ADC_A 和 ADC_D 时、我可以在 ADCa 结果寄存器和  ADCd 结果寄存器中看到结果。 但是、代码不会进入 adcd_isr、因为我无法在变量 resumy_Vxd1中看到结果。 代码会输入 adca_ISR、因为我可以在变量 Result_Vx 中看到结果。 此外、如果 我在394/395行之后移动 adca_ISR 中的 RESULT_Vxd1的第414行和415行、我可以看到这些变量中的结果。 为什么代码不会进入 adcd_isr、即使我已经为这些代码初始化了正确的 PIE 组和通道?

    2.当我使用 ePWM3触发 ADC_A 和 ADC_D 的 ADC 转换时、不会发生转换。

    3、如果我对 ADC_A 使用 ePWM1、对 ADC_D 使用 ePWM3、那么 ADC_A 工作正常、而 ADC_D 则不进行转换

    感谢您抽出宝贵时间参加本次活动。

    谢谢  

    Sneha

    #include "F28x_Project.h"
    #include "math.h"

    #define EPWM1_MAX_DB 20 // PV/PFC 的最大死区为150ns
    #define EPWM1_MIN_DB 15 // PV/PFC 的最小死区
    #define EPWM3_MAX_DB 20 // PV/PFC 最大死区150ns
    #define EPWM3_MIN_DB 15 // PV/PFC 的最小死区
    #define PHASE_BRIDGE 20;//两个 DAB 桥之间的 PS
    #define PHASE_LEASE 0x0000//20;桥的两个桥臂之间的 PS

    //跟踪比较值的移动方式
    #define ePWM_CMP_UP 1.
    #define ePWM_CMP_DOWN 0
    #define DB_UP 1.
    #define DB_DOWN 0

    #define results_buffer_size 256
    #define results_buffer_sized 256

    float result_V =0.0;
    float result_Vx =0.0;
    float result_Vd =0.0;
    float result_Vxd =0.0;
    float result_Vxd1 =0.0;
    float gain_vdc2 = 215.28;
    float Vdc2 = 0.0;
    
    float mod  = 0.9; // modulation index
    float pi = 3.14285714;
    float f_clk =   100000000.0f;  // DSp clock frequency = SYSCLK/2 = 100MHz
    float fg   = 60.0f;  // grid frquency
    float f_pfc = 300000.0f;  // pfc, pv frquency
    float f_sw  = 300000.0f;  // dab  frquency
    float dt   = 0.000005;  // sampling frequency for SPWm generation, pfc = 1/f_pfc
    
    float time = 0.00000000000;
    float ref = 0.0;
    float ref_offset = 0.0;
    float TBDAB = 0;
    float TBPFC = 0;
    float dutyA_DAB = 0;
    float dutyB_DAB = 0;
    float dutyA_pv = 0;
    float dutyB_pv = 0;
    
    typedef struct
    {
        volatile struct EPWM_REGS *EPwmRegHandle;
        Uint16 EPwmDB_Direction;
        Uint16 EPwmTimerIntCount; //these definitions here are required for update_compare11 routine for updating the deadband
        Uint16 EPWMMAX_DB;
        Uint16 EPWMMIN_DB;
    }EPWM_INFO; // should only be defined here, otherwise causes type name error
    EPWM_INFO epwm1_info;
    EPWM_INFO epwm3_info;
    
    
    Uint16 AdcaResults[RESULTS_BUFFER_SIZE];
    Uint16 AdcdResults[RESULTS_BUFFER_SIZEd];
    Uint16 resultsIndex;
    volatile Uint16 bufferFull;
    Uint16 resultsIndexd;
    volatile Uint16 bufferFulld;
    
    
    void ConfigureADC(void);
    void SetupADCEpwm(Uint16 channel);
    void SetupADCEpwmd0(Uint16 channel);
    
    void InitEPwm1Example(void);
    
    void InitEPwm3Example(void);
    
    void update_compare1(EPWM_INFO*);
    
    __interrupt void epwm1_isr(void);
    
    __interrupt void epwm3_isr(void);
    
    
    // Function Prototypes
    //
    __interrupt void cpu_timer0_isr(void);
    interrupt void adca1_isr(void);
    interrupt void adcd1_isr(void);
    
    Uint32 EPwm1TimerIntCount;
    
    Uint32 EPwm3TimerIntCount;
    
    Uint16 EPwm1_DB_Direction;
    
    Uint16 EPwm3_DB_Direction;
    
    void main(void)
    {
    //
        // rounding the prd register to highest value
        TBDAB = ceil(f_clk/(2*f_sw)); // ceil value for dab period register
        TBPFC = ceil(f_clk / (2 * f_pfc)); // ceil value for pv, tpfc period register
        dutyA_DAB = ceil(TBDAB / 2); // duty cycle/compare for DAB
        dutyB_DAB = ceil(TBDAB / 2); // duty cycle/compare for DAB
    
        //D =0.5 tbpfc/2, D<0.5 tbpfc/2
        dutyA_pv = ceil(TBPFC / 2); // duty cycle/compare for pv
        dutyB_pv = ceil(TBPFC / 2); // duty cycle/compare for pv
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
    //
        InitSysCtrl();
    
    //
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
        // Initialise this code for using GPIO2 and 3 for ePWM2 TPFC line frequency pulse generation
        InitGpio();
        CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;
        CpuSysRegs.PCLKCR2.bit.EPWM3 = 1;
        
    
        InitEPwm1Gpio();
        InitEPwm3Gpio();
         //
    // 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 F2837xD_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 F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_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.TIMER0_INT = &cpu_timer0_isr;
    
        PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1
        PieVectTable.ADCD1_INT = &adcd1_isr;
    
        PieVectTable.EPWM1_INT = &epwm1_isr;
        PieVectTable.EPWM3_INT = &epwm3_isr;
        EDIS;
    
    //
    // Step 4. Initialize the Device Peripheral. This function can be
    //         found in F2837xD_CpuTimers.c
    //
        InitCpuTimers();   // For this example, only initialize the Cpu Timers
    
    //
    // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
    // 200MHz CPU Freq, 1 second Period (in uSeconds)
    //
        ConfigCpuTimer(&CpuTimer0, 200, 5);
    
        // Step 4. Initialize all the Device Peripherals:
        // This function is found in DSP2833x_InitPeripherals.c
        // InitPeripherals(); // Not required for this example
    
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
    
        InitEPwm1Example();
        InitEPwm3Example();
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    
    //
    // To ensure precise timing, use write-only instructions to write to the
    // entire register. Therefore, if any of the configuration bits are changed in
    // ConfigCpuTimer and InitCpuTimers (in F2837xD_cputimervars.h), the below
    // settings must also be updated.
    //
        CpuTimer0Regs.TCR.all = 0x4000;
    
        // Configure the ADC and power it up
        //
        ConfigureADC();
    
    
        // Setup the ADC for ePWM triggered conversions on channel 0
        //
        SetupADCEpwm(0); //Input ADC channel here
        /*SetupADCEpwm1(1);
        SetupADCEpwmb2(2); //V3 bat, pin 18, adcB2
        //SetupADCEpwmb14(14);//I3 bat, pin 25/27, adcB14
        //SetupADCEpwmb15(15);//I3 bat, pin 25/27, adcB15
        //SetupADCEpwmc(33);//I3 wdg bat, pin 33, adcC3*/
        SetupADCEpwmd0(0);        //V2 DC link, pin 28, adcD0
    //
    // Step 5. User specific code, enable interrupts:
    //
    // Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
    // which is connected to CPU-Timer 1, and CPU int 14, which is connected
    // to CPU-Timer 2:
    //
        IER |= M_INT1;
        /*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;
        for (resultsIndexd = 0; resultsIndexd < RESULTS_BUFFER_SIZEd;
                resultsIndexd++)
        {
            AdcdResults[resultsIndexd] = 0;
        }
        resultsIndexd = 0;
        bufferFulld = 0;
    
    //
    // Enable TINT0 in the PIE: Group 1 interrupt 7
    //
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    
        PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
        PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
        
    //
        PieCtrlRegs.PIEIER1.bit.INTx1 = 1; //ADC A1 group1 channel 1
     /*   PieCtrlRegs.PIEIER1.bit.INTx2 = 1; //ADC B1 group1 channel 2
        //PieCtrlRegs.PIEIER1.bit.INTx3 = 1; //ADC C1 group1 channel 3*/
        PieCtrlRegs.PIEIER1.bit.INTx6 = 1; //ADC D1 group1 channel 6
    
    // 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):
    //
        do
        {
            //
            //start ePWM
            //
            EPwm1Regs.ETSEL.bit.SOCAEN = 1;  //enable SOCA
            EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //unfreeze, and enter up count mode
            //required when ePWM3 is the trigger
            EPwm3Regs.ETSEL.bit.SOCAEN = 1;  //enable SOCA
            EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //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 = TB_COUNT_UPDOWN;
            //required when ePWM3 is the trigger
            EPwm3Regs.ETSEL.bit.SOCAEN = 0;  //disable SOCA
            EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    
            //at this point, AdcaResults[] contains a sequence of conversions
            //from the selected channel
            //
    
            //
            //software breakpoint, hit run again to get updated conversions
            //
            asm("   ESTOP0");
        }
        while (1);
    }
    
    //
    // ConfigureADC - 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); // ADC module selection
        //
        AdcdRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
        AdcSetMode(ADC_ADCD, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); // ADC module selection
        //Set pulse positions to late
        //
        AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
        AdcdRegs.ADCCTL1.bit.INTPULSEPOS = 1;
        //
        //power up the ADC
        //
        AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
        AdcdRegs.ADCCTL1.bit.ADCPWDNZ = 1;
        //
        //delay for 1ms to allow ADC time to power up
        //
        DELAY_US(1000);
    
        EDIS;
    }
    // cpu_timer0_isr - CPU Timer0 ISR with interrupt counter
    //
    __interrupt void cpu_timer0_isr(void)
    {
        if (time < 10)
        {
            time = time + dt;
        }
        else
        {
            time = 0;
        }
    
        ref = mod * sin(2 * 3.14 * fg * time);
        ref_offset = (TBPFC * ref) / 2 + TBPFC / 2;
    
        // Update the CMPA and CMPB values
    
        // Clear INT flag for this timer
        EPwm1Regs.ETCLR.bit.INT = 1;
    
        //PWM1........
        EPwm1Regs.CMPA.bit.CMPA = ref_offset;    // Set c00ompare A value
        EPwm1Regs.CMPB.bit.CMPB = ref_offset; //EPWM1_MAX_CMPB;               // Set Compare B value
    
         CpuTimer0.InterruptCount++;
    
         PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge this interrupt to receive more interrupts from group 1
    
    }
    
    __interrupt void epwm1_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&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;
    }
    
    __interrupt void epwm3_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare1(&epwm3_info);
    
        // Clear INT flag for this timer
        //
        EPwm3Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    
    interrupt void adca1_isr(void)
    {
        result_V = AdcaResultRegs.ADCRESULT0;
        result_Vx = 0.0007324 * result_V;
    
    
    
        /*result_V1 = AdcaResultRegs.ADCRESULT1;
        result_Vy = 0.0007324 *result_V1;*/
    
        if(RESULTS_BUFFER_SIZE <= resultsIndex)
        {
            resultsIndex = 0;
            bufferFull = 1;
        }
    
        AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    
    }
    interrupt void adcd1_isr(void)
    {
        result_Vd = AdcdResultRegs.ADCRESULT0;
        result_Vxd1 = 0.1 + (0.0007324 * result_Vd);
    
        if (result_Vxd1 >= 1.1)
        {
            result_Vxd = result_Vxd1 - 0.6;
    
        }
        if (result_Vxd1 >= 0.7 && result_Vxd1 < 1.1)
        {
            result_Vxd = result_Vxd1 - 0.3;
        }
        if (result_Vxd1 >= 0.15 && result_Vxd1 < 0.7)
        {
            result_Vxd = result_Vxd1 - 0.15;
        }
        if (result_Vxd1 < 0.15)
        {
            result_Vxd = result_Vxd1;
        }
        Vdc2 = result_Vxd * gain_vdc2;
    
        if (RESULTS_BUFFER_SIZEd <= resultsIndexd)
        {
            resultsIndexd = 0;
            bufferFulld = 1;
        }
    
        AdcdRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    }
    
    // PWM1
    void InitEPwm1Example()
    {
    
        // Setup TBCLK
        EPwm1Regs.TBPRD = TBPFC;          // Set timer period 801 TBCLKs
        EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
        EPwm1Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm1Regs.CMPA.bit.CMPA = ref_offset;    // Set c00ompare A value
        EPwm1Regs.CMPB.bit.CMPB = ref_offset;   // Set Compare B value
    
        // Setup counter mode
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
        EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
        //EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // required to disable this master and for independent pwm generation
    
        // 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;
    
        //Enable ADC SOC
        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
    
    
        // Set actions
        EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; //AQ_SET;         // When sine<triangle set lower switch 51
        EPwm1Regs.AQCTLA.bit.CAD = AQ_SET; //AQ_CLEAR;   // Clear PWM1A on event A, down count
    
        EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; //AQ_CLEAR;       // // When sine>triangle set upper switch 49
        EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR; //AQ_SET;     // Clear PWM1B on event B, down count
    
        //essentially first upper switch conducts with leg 2 lower
    
        // Active high complementary PWMs - Setup the deadband
        //
        EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm1Regs.DBRED.bit.DBRED = EPWM1_MIN_DB;
        EPwm1Regs.DBFED.bit.DBFED = EPWM1_MIN_DB;
        EPwm1_DB_Direction = DB_UP;
    
        //
        // Interrupt where we will change the deadband
        //
        EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;      // Select INT on Zero event
        EPwm1Regs.ETSEL.bit.INTEN = 1;                 // Enable INT
        EPwm1Regs.ETPS.bit.INTPRD = ET_3RD;            // Generate INT on 3rd 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.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm1_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm1_info.EPwmRegHandle = &EPwm1Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm1_info.EPWMMAX_DB = EPWM1_MAX_DB;      // Setup min/max
        epwm1_info.EPWMMIN_DB = EPWM1_MIN_DB;      // Setup min/max
    
    }
    // PWM3
    void InitEPwm3Example(void)
    {
    
        // Setup TBCLK
        EPwm3Regs.TBPRD = TBDAB;          // Set timer period 801 TBCLKs
        EPwm3Regs.TBPHS.bit.TBPHS = 0x0000;           // Phase is 0
        EPwm3Regs.TBCTR = 0x0000;                      // Clear counter
    
        // Set Compare values
        EPwm3Regs.CMPA.bit.CMPA = dutyA_DAB;               // Set c00ompare A value
        EPwm3Regs.CMPB.bit.CMPB = dutyB_DAB;               // Set Compare B value
    
        // Setup counter mode
        EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up down
        EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;        // Disable phase loading
        EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
        // Setup shadow register load on ZERO
        EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
        EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        //Enable ADC SOC
        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
    
        // Set Actions
        EPwm3Regs.AQCTLA.bit.CAU = AQ_SET;            // Set PWM3A on period
        EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;   // Clear PWM3A on event B, down count
    
        EPwm3Regs.AQCTLB.bit.CBU = AQ_CLEAR;          // Clear PWM3A on period
        EPwm3Regs.AQCTLB.bit.CBD = AQ_SET;         // Set PWM3A on event A, up count
    
        // Active high complementary PWMs - Setup the deadband
        EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
        EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
        EPwm3Regs.DBCTL.bit.IN_MODE = DBA_ALL;
        EPwm3Regs.DBRED.bit.DBRED = EPWM3_MIN_DB;
        EPwm3Regs.DBFED.bit.DBFED = EPWM3_MIN_DB;
        EPwm3_DB_Direction = DB_UP;
    
        // Interrupt where we will change the Compare Values
        EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
        EPwm3Regs.ETSEL.bit.INTEN = 1;                // Enable INT
        EPwm3Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd 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
        //
        epwm3_info.EPwmDB_Direction = DB_UP; // Start by increasing
                                             // CMPA & CMPB
        epwm3_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
        epwm3_info.EPwmRegHandle = &EPwm3Regs;        // Set the pointer to the
                                                      // ePWM module
        epwm3_info.EPWMMAX_DB = EPWM3_MAX_DB;      // Setup min/max
        epwm3_info.EPWMMIN_DB = EPWM3_MIN_DB;      // Setup min/max
    
    }
    // update_compare1 TPFC/PV -and  update_compare3 DAB Update the compare values for the specified EPWM
    //
    void update_compare1(EPWM_INFO *epwm_info)
    {
        if (epwm_info->EPwmDB_Direction == DB_UP)
        {
            if (epwm_info->EPwmRegHandle->DBFED.bit.DBFED < epwm_info->EPWMMAX_DB)
            {
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED++;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED++;
            }
            else
            {
                epwm_info->EPwmDB_Direction = DB_DOWN;
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED--;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED--;
            }
        }
        else
        {
            if (epwm_info->EPwmRegHandle->DBFED.bit.DBFED == epwm_info->EPWMMIN_DB)
            {
                epwm_info->EPwmDB_Direction = DB_UP;
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED++;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED++;
            }
            else
            {
                epwm_info->EPwmRegHandle->DBFED.bit.DBFED--;
                epwm_info->EPwmRegHandle->DBRED.bit.DBRED--;
            }
        }
    
        epwm_info->EPwmTimerIntCount++;
    
        //   return;
    }
    //
    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
        EDIS;
    
    }
    void SetupADCEpwmd0(Uint16 channel)
    {
        Uint16 acqps;
    
        //
        //determine minimum acquisition window (in SYSCLKS) based on resolution
        //
        if(ADC_RESOLUTION_12BIT == AdcdRegs.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;
        AdcdRegs.ADCSOC0CTL.bit.CHSEL = channel;  //SOC0 will convert pin D0
        AdcdRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
        AdcdRegs.ADCSOC0CTL.bit.TRIGSEL = 9; //trigger on ePWM3 SOCA/C
    
        AdcdRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
        AdcdRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
        AdcdRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
        EDIS;
    }
    
    // End of file
    //
    

    一  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Sneha、

    由于某些文件链接问题、我无法在我的末尾重新创建问题、但从主查看源代码、我发现了以下错误:

    ePWM INT 属于组3。 您刚刚使用 IER => M_INT1启用了组1中断。 请也启用组3中断。

    2.有些寄存器受写保护、必须在 EALLOW、EDIS 支架内更新。 一些受写保护的寄存器未经许可被写入。 例如、 ADCa 和 ADCd 中的 ADCCTL2、EPWM1和 EPWM3的 PCLKCR2。

    也请检查其他此类寄存器。 您可以浏览 TRM 寄存器摘要部分、了解有关其写保护的信息。 另外一种方法是、您可以通过任何方式为所有寄存器添加 EALLOW;EDIS、以避免任何混淆。

    如果这不能帮助解决问题、请发送压缩的项目文件夹、以便我可以在结尾重新创建问题

    谢谢、

    Aditya  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好的、谢谢 Aditya、

    今天晚上、我将按照这些步骤为您提供最新信息。

    谢谢

    Sneha

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好

    我在这里附加了 zip 文件夹、因为我无法解决上一篇文章中提到的问题。 我 现在甚至启用了 IER => M_INT3。 我使用的是 ADC_D0引脚28和 ADC_A0引脚09。

    [引用 userid="462934" URL"~/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/996361/launchxl-f28379d-adc-interrupt-not-generating-when-adc-module-is-changed/3686385 #3686385]2. 某些寄存器受写保护、必须在 EALLOW、EDIS 支架内更新。 一些受写保护的寄存器未经许可被写入。 例如、 ADCa 和 ADCd 中的 ADCCTL2、EPWM1和 EPWM3的 PCLKCR2。[/QUERP]

    请详细说明一下吗?

    谢谢

    Sneha Thakure2e.ti.com/.../2626.cpu01.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Sneha、

    [报价 userid="329063" URL"~/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/996361/launchxl-f28379d-adc-interrupt-not-generating-when-adc-module-is-changed/3688423 #3688423"]您能否详细说明这一点?

    有些关键寄存器、例如控制寄存器、无法直接写。 这些是受写保护的寄存器。 如果仔细查看代码、一些寄存器/位配置在写入 EALLOW 和 EDIS 之后完成。 要更新受写保护的寄存器、您需要在更新之前包含 EALLOW 并以 EDIS 结束。

    TRM 提到寄存器是否受写保护。 请参见下图。

    在源代码中、它如下所示:

        EALLOW;
        // This is needed to write to EALLOW protected registers
    
        PieVectTable.TIMER0_INT = &cpu_timer0_isr;
    
        PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1
    
        PieVectTable.EPWM1_INT = &epwm1_isr;
        PieVectTable.EPWM3_INT = &epwm3_isr;
        PieVectTable.EPWM4_INT = &epwm4_isr;
        PieVectTable.EPWM5_INT = &epwm5_isr;
        PieVectTable.EPWM6_INT = &epwm6_isr;
        EDIS;

    请告诉我这是否有助于解决您的问题。 除非和直至提到这些、否则不会更新寄存器。

    谢谢、

    Aditya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好

    我将对此进行检查。

    您是否能够使用我共享的文件在您的末尾重新创建问题?

    谢谢

    Sneha

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Sneha、

    是的、我在器件上运行了代码、代码很好地进入了 ISR。 我通过在 ISR 内保留一个断点来进行检查。 附加相同的图像。 我没有对您共享的代码进行任何更改。

    Aditya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好

    我将此问题标记为已错误解决。

    同一代码在我的末尾不起作用 您是否在 ADC_d ISR 中的 ADC_D 结果寄存器和变量 Result_Vd、Result_Vxd1中看到结果?

    谢谢

    Sneha

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Sneha、

    我能够正确地看到相应的值。 您能否通过在 D1 ISR 内放置断点进行检查?

    Aditya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Sneha、

    由于我们没有收到您的回复、我相信这个问题已经解决。 我现在将此主题标记为已解决。 如果您仍有任何问题、请随时将其标记为未解决并继续该主题。 如果此主题锁定、您可以提出新问题。

    谢谢、

    Aditya