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-F28027F:I2C 编程完成后、ePWM 模块出现毛刺。

Guru**** 661510 points
Other Parts Discussed in Thread: LAUNCHXL-F28027, C2000WARE
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1308102/launchxl-f28027f-epwm-module-glitching-after-i2c-programming-is-complete

器件型号:LAUNCHXL-F28027F
主题中讨论的其他器件:LAUNCHXL-F28027C2000WARE

可从 此处访问问题声明。 此外、还提供了代码(CCS)  

#include "F2802x_Device.h"
#include "f2802x_examples.h"
#include "f2802x_epwm_defines.h"
#include "f2802x_GlobalPrototypes.h"
#include "IQmathLib.h"
#include "pi_reg4.h"
#include "DSP28x_Project.h"

// external function prototypes
extern void InitSysCtrl(void);
extern void InitPieCtrl(void);
extern void InitPieVectTable(void);

// external function prototypes for I2C Slave (i.e.Gate driver)
bool_t Address_Config;
bool_t Parameter_Config;
bool_t Sec_Ready;
bool_t Read_Gate_Driver;
bool_t Read_Gate_Driver_Fault;
int run = 0;

// Prototype statements for functions found within this file.
void Gpio_select(void);
void Setup_ePWM1A(void);
interrupt void ePWM1A_compare_isr(void);
void I2CA_Init(void);
interrupt void I2CA_WriteData();

extern unsigned int RamfuncsLoadStart;
extern unsigned int RamfuncsLoadSize;
extern unsigned int RamfuncsRunStart;

//###########################################################################
//                      main code
//###########################################################################
//
//I2C slave (Gate Driver) Register Addresses
//
#define REG_CONFIG_LOCK         0x1C
#define READY_STATE             0x26
#define UV_THRESHOLD_LEVEL      0x06
#define DRIVER_OFF_TYPE         0x15
//
//I2C slave (Gate Driver) Register's Data Values
//
#define VEE_THRESHOLD_LEVEL_0V  0x0
#define CONFIGURED              0x1
#define NOT_CONFIGURED          0x0
#define CLEAR_EVENT_REG         0x1D
//
#define slave     0x0D // I2C slave (Gate Driver) address

_iq24 delay1   = _IQ24(0);
int count    = 0;
int count_isr    = 0;
_iq24 countnew    = _IQ24(0);
_iq24 I2Ccount = _IQ24(0);
_iq24 b = _IQ24(0);
_iq24 I2C_NUM_BYTES = _IQ24(0);
int j= 0;
bool_t Address_Config   = true;
bool_t Parameter_Config = true;
bool_t Read_Gate_Driver = true;
_iq24 i = _IQ24(0);
uint8_t sendData[] = {0x00,0x20,0x21,0x01};
uint8_t sendData2[] = {0x1C,0x00};
uint8_t sendData5[] = {0x03,//Input pin filter times register for IN, RDYC, FLT_N, and I2C
                       0x00,//100ns for all but for I2C-SCA, SDA pins 50ns

                      // 0x04,//FLT_N clear register using RDYC or self clear timer
                       0x00,//RDY to low cycle method with 1us clearance time

                       //0x05,//Restore_Recover register
                       0x03,//Restore from input side, Recover from output side

                       //0x06,//UVLO register
                       0x05,//VCC (UVLO) = 10V, and VEE (UVLO) = -3.5V

                      // 0x07,//VCC2 soft UVLO register
                       0x00,//Presently disabled. If enabled then ADC must be configured to measure internal supply voltage
                            // i.e. VINT.EN= 1, else RDY pin is pulled low

                       //0x08,//VEE2 soft UVLO register
                       0x00,//Presently disabled. If enabled then ADC must be configured to measure internal supply voltage
                       // i.e. VINT.EN= 1, else RDY pin is pulled low

                      //0x09,//ADC config register to measure internal voltage OR External voltage measured w.r.t CLAMP pin.
                              //Trigger events can be set based on external V measurements and threshold value. If external
                              //voltage measurement function is used, then Miller clamp must be disabled (CLCFG .CL_DIS = 1)
                       0x07,//Presently enabled- internal supply voltage measurements (VCC2, VEE2, GND2)

                      //0x0A,//Register to configure threshold value used for comparison in register 0x09.
                       0x00,//Presently, it is in reset state.

                      //0x0B,//Register to configure threshold value for over temperature warning.
                       0x00,// Limit: 140 degree C, no fault triggered if limit breached. Note: ADC to measure temp always active

                      //0x0C,//Register to configure DESAT and adjust voltage threshold level of DESAT1.
                       0x1F,//Presently DESAT disabled: means DESAT1 and DESAT2 disabled. Also, DESAT pin in tristate.
                            //Hence, no fault event will be triggered

                      //0x0D,//Register to set DESAT1 filter time (Deglitch)
                       0x08,//DESAT1 filter time: 475ns

                       //0x0E,//Register to configure DESAT2. DESAT2 is used during 2 level turn-off event.
                       0x10,//DESAT2 disabled. Threshold: 2.01V. No fault triggered during two level turn-off.

                       //0x0F,//Register to configure DESAT2 filter time (Deglitch).
                       0x19,//Presently at 675ns.

                       //0x10,//Register to set the value of the comparator limit. If the number of DESAT2 events above
                             //threshold reaches the set limit, the status register-D2ECNT will give a fault signal.
                       0x00,//00 disables the DESAT2 function.

                       //0x11,//Register defines the number of PWM cycles at IN pin after the last DESAT2 event
                              //which are necessary to decrement DESAT2 event counter by one.
                       0x00,//decrement function deactivated

                       //0x12,//Register to set time after which the auxiliary DESAT switch turns off, after the turn-on
                              //of the main power switch and the voltage at the blanking cap node starts to rise.
                       0x00,// Value= 0.1us

                       //0x13,//Register to configure the delay in signal for gate turn-off from a fault event
                       0x00,//0us delay

                       //0x14,//Register to configure the adjustment in DESAT1 and DESAT2 threshold value based on
                              //junction temperature (Tj) of the Gate driver.
                       0x00,//No adjustment

                       //0x15,//Register to configure type of turn-off of power device, i.e. hard turn-off, 2 level turn-off
                              //or soft turn-off in the event of a fault
                       0x00,//soft turn-off enabled

                       //0x16,//Register to configure type of turn-off of power device, i.e. hard turn-off, 2 level turn-off
                              //under normal operation.
                       0x00,//hard turn-off enabled

                       //0x17,//Register to configure the mid-level and ramp rate in 2 level turn-off
                       0x4E,//9V mid-level Vgs. Ramp rate between fully turn-on to mid level Vgs = 30V/us

                       //0x18,//Register to configure the mid-level plateau time and ramp rate in 2 level turn-off
                       0xE2,//Plateau time of the mid level Vgs=0.5us, Ramp rate from mid-level to fully off = 60V/us

                       //0x19,//Register to configure the value of current for soft turn-off
                       0x09,//7.3% of nominal current value

                       //0x1A,//Register for setting up CLAMP pin as Miller Clamp
                       0x20,//Enabled with Tdelay in activation after Vgs<Vee+2= 0.15u

                       //0x1B,//Register for setting up switch-off time-out time
                       0x0C,//Disabled. No fault on time-out

                       //0x1C,//Register to configure the CFGOK register. Put the value 0x01 if parameter config complete
                       0x00,//Since the parameter configuration incomplete till now

                       //0x1D,//Register to Clear event counter registers for DESAT2, VCC1 UVLO, VCC2 UVLO, event flags,
                              //and soft-reset
                       0x00,//No change
                       };//Locking and entering Parameter transfer state from parameter configuration state

uint8_t sendData3[] = {0x1C,0x01};//Entering normal state with Sec_RDY = 1: 0x04
uint8_t sendData4[] = {0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,0x36};//Entering normal state with Sec_RDY = 1: 0x04

int dataSize = sizeof(sendData);
int dataSize2 = sizeof(sendData2);
int dataSize3 = sizeof(sendData3);
int dataSize4 = sizeof(sendData4);
int dataSize5 = sizeof(sendData5);


void main(void)
{
    InitSysCtrl();      // Basic Core Init from DSP2833x_SysCtrl.c
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (Uint32)&RamfuncsLoadSize);
    InitFlash();

    DINT;               // Disable all interrupts

    Gpio_select();      // GPIO initialization
    Setup_ePWM1A();     // initialization of ePWM1A
    I2CA_Init();        // I2C-A initialize

    InitPieCtrl();      // basic setup of PIE table; from DSP2833x_PieCtrl.c
    InitPieVectTable(); // default ISR's in PIE


    Address_Config = true;
    Parameter_Config= true;
    Sec_Ready       =true;
    Read_Gate_Driver = true;
    Read_Gate_Driver_Fault = false;

    I2CA_WriteData();

    while(1){}
}

void Gpio_select(void)
{
    EALLOW;
            GpioCtrlRegs.GPAMUX1.all = 0;         // GPIO0 ... GPIO15 = General Purpose I/O
            GpioCtrlRegs.GPAMUX2.all = 0;         // GPIO15 ... GPIO31 = General Purpose I/O
            GpioCtrlRegs.GPBMUX1.all = 0;         // GPIO32 ... GPIO38 = General Purpose I/O

            GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   // ePWM1A active // for driving relay
            EPwm1Regs.CMPA.half.CMPA = 0;

            GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0;   // GPIO2 as input pin for RDY
            GpioCtrlRegs.GPADIR.bit.GPIO2 = 0;    // GPIO2 as input pin

            GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 0;   // GPIO3 as input pin for FLT
            GpioCtrlRegs.GPADIR.bit.GPIO3 = 0;    // GPIO3 as input

            GpioCtrlRegs.GPBDIR.all = 0;          // GPIO32-GPI38 as inputs
            // Configure GPIO pins for I2C-A
            GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;   // Enable pull-up on GPIO32 (SDAA); GPBPUD: pull-up disable
            GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;   // Enable pull-up on GPIO33 (SCLA)
            GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3; // Asynch input GPIO32 (SDAA)
            GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3; // Asynch input GPIO33 (SCLA)
            GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1;  // Configure GPIO32 as SDAA
            GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1;  // Configure GPIO33 as SCLA

//            GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0;    // Enable pull-up for GPIO28 (SDAA)
//            GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0;    // Enable pull-up for GPIO29 (SCLA)
//            GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3;  // Asynch input GPIO28 (SDAA)
//            GpioCtrlRegs.GPAQSEL2.bit.GPIO29 = 3;  // Asynch input GPIO29 (SCLA)
//            GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 2;   // Configure GPIO28 for SDAA operation
//            GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 2;   // Configure GPIO29 for SCLA operation

    EDIS;
}

void Setup_ePWM1A(void)
{
    EPwm1Regs.TBPRD = 750;                           // 6000 for 5KHz or 200us - PWM signal 1500 for 50khz
    EPwm1Regs.CMPA.half.CMPA = 800;
    EPwm1Regs.TBPHS.half.TBPHS = 0;
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;        // up - down mode
    EPwm1Regs.TBCTL.bit.SYNCOSEL =  TB_SYNC_DISABLE;  //
    EPwm1Regs.TBCTL.bit.PHSEN =  TB_DISABLE;         // Master module
    EPwm1Regs.TBCTL.bit.PRDLD =  TB_SHADOW;

    //EPwm1Regs.TBCTL.bit.CLKDIV =  0;                 // CLKDIV = 1
    //EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;               // HSPCLKDIV = 2

    EPwm1Regs.CMPB = 0;

    EPwm1Regs.ETSEL.bit.INTSEL = 1;
    EPwm1Regs.ETSEL.bit.INTEN = 1;
    EPwm1Regs.ETPS.bit.INTPRD = 1;

    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    EPwm1Regs.AQCTLB.bit.ZRO= AQ_SET;
    EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR;
}

void I2CA_Init(void)
{
  //Initialize I2C; Pre-scaler must be set when I2C in reset state
    I2caRegs.I2CMDR.bit.IRS = 0;     // keep I2C in reset mode
    I2caRegs.I2CMDR.bit.XA  = 0;     // I2C configured for 7bit address communication


    I2caRegs.I2CPSC.all = 5;         // I2C Clock = SYSCLK/(I2CPSC+1) (60MHz/(5+1) = 10MHz); clock must be between 7-12 MHz
    I2caRegs.I2CCLKL = 45;           // I2C SCL low-time period = I2CCLKL*(I2CPSC+1) (15*(5+1) = 96 ns)
    I2caRegs.I2CCLKH = 45;           // I2C SCL high-time period = I2CCLKH*(I2CPSC+1) (15*(5+1) = 96 ns)

    I2caRegs.I2CMDR.bit.IRS = 1;     // Take I2C out of reset mode
                                     // Stop I2C when suspended
}

void I2CA_WriteData(void)
{
    // Wait until the STP (stop) bit is cleared from any previous master communication.
    // Clearing of this bit by the module is delayed until after the SCD (stop condition detected) bit is set.
    // If this bit is not checked prior to initiating a new message, the I2C could get confused.
    for (delay1= _IQ24(0.0); delay1< _IQ24(20); delay1+= _IQ24(0.0000005)) // 13 second delay
       {}

    I2caRegs.I2COAR = 0x0F;//master address

    if (I2caRegs.I2CMDR.bit.STP == 1)             // I2CMDR: Mode register
        {
           return;
        }

//  GpioCtrlRegs.GPADIR.bit.GPIO16  = 1;   // Input Pin for RDY
//  GpioDataRegs.GPACLEAR.bit.GPIO16 = 1;


 //   EPwm1Regs.CMPA.half.CMPA = 800;

    for (delay1= _IQ24(0.0); delay1< _IQ24(100); delay1+= _IQ24(0.5)) // 100us
        {}
    for (delay1= _IQ24(0.0); delay1< _IQ24(100); delay1+= _IQ24(0.5)) // 100us
        {}
    for (delay1= _IQ24(0.0); delay1< _IQ24(100); delay1+= _IQ24(0.5)) // 100us
        {}

    if (count == _IQ24(0))
        {
           I2caRegs.I2CSAR = 0x0D;                   // Set slave address
           while (I2caRegs.I2CSTR.bit.NACK == 1);    // Wait for acknowledgment after accessing the slave
         }

    if (Address_Config)
         {
           I2caRegs.I2CCNT = dataSize;
           for (j= 0; j< dataSize; j += 1)
            {
           I2caRegs.I2CDXR = sendData[j];

            if (j==(dataSize-1))
            {
                I2caRegs.I2CMDR.all = 0x4E20;             // Start I2C, Master, Transmit
                while (I2caRegs.I2CSTR.bit.XRDY == 0);
                GpioCtrlRegs.GPADIR.bit.GPIO16 = 0;   // Release RDY pin to Tri-state for both GD
            }
            else
            {
                I2caRegs.I2CMDR.all = 0x6620;             // Start I2C, Master, Transmit
                while (I2caRegs.I2CSTR.bit.NACK == 1);
                while (I2caRegs.I2CSTR.bit.XRDY == 0);    // Wait for transmission from I2CXDR to I2CXSR to complete
            }
            }
          }

    for (delay1= _IQ24(0.0); delay1< _IQ24(100); delay1+= _IQ24(0.5)) // 13 second delay
     {}
    for (delay1= _IQ24(0.0); delay1< _IQ24(100); delay1+= _IQ24(0.5)) // 13 second delay
     {}

//    EPwm1Regs.CMPA.half.CMPA = 0;

    if (Parameter_Config)
          {
          I2caRegs.I2CSAR = 0x20;
          I2caRegs.I2CCNT = dataSize2;
          for (j= 0; j< dataSize2; j += 1)
           {
           I2caRegs.I2CDXR = sendData2[j];

           if (j==(dataSize2-1))
           {
               I2caRegs.I2CMDR.all = 0x4E20;             // Start I2C, Master, Transmit
               while (I2caRegs.I2CSTR.bit.XRDY == 0);
              // GpioCtrlRegs.GPADIR.bit.GPIO16 = 0;     // Release RDY pin to Tri-state for both GD
           }
           else
           {
               I2caRegs.I2CMDR.all = 0x6620;             // Start I2C, Master, Transmit
               while (I2caRegs.I2CSTR.bit.NACK == 1);
               while (I2caRegs.I2CSTR.bit.XRDY == 0);    // Wait for transmission from I2CXDR to I2CXSR to complete
           }
           }
          }

    if (Sec_Ready)
              {
         I2caRegs.I2CSAR = 0x20;
                   I2caRegs.I2CCNT = dataSize3;
                   for (j= 0; j< dataSize3; j += 1)
                    {
                    I2caRegs.I2CDXR = sendData3[j];

                    if (j==(dataSize3-1))
                    {
                        I2caRegs.I2CMDR.all = 0x4E20;             // Start I2C, Master, Transmit
                        while (I2caRegs.I2CSTR.bit.XRDY == 0);
                       // GpioCtrlRegs.GPADIR.bit.GPIO16 = 0;   // Release RDY pin to Tri-state for both GD
                    }
                    else
                    {
                        I2caRegs.I2CMDR.all = 0x6620;             // Start I2C, Master, Transmit
                        while (I2caRegs.I2CSTR.bit.NACK == 1);
                        while (I2caRegs.I2CSTR.bit.XRDY == 0);    // Wait for transmission from I2CXDR to I2CXSR to complete
                    }
                    }
              }

    for (delay1= _IQ24(0.0); delay1< _IQ24(100); delay1+= _IQ24(0.5)) // 13 second delay
     {}
    for (delay1= _IQ24(0.0); delay1< _IQ24(100); delay1+= _IQ24(0.5)) // 13 second delay
     {}
    for (delay1= _IQ24(0.0); delay1< _IQ24(100); delay1+= _IQ24(0.5)) // 13 second delay
     {}

   run = 1;

return;
}


//interrupt void ePWM1A_compare_isr(void)
//{
//
//    if(run==0 && count_isr==0)
//    {
//        EPwm1Regs.CMPA.half.CMPA = 800;
//        count_isr= count_isr+1;
//        I2CA_WriteData();
//    }
//    else if (run==0 && count_isr==1)
//    {
//        EPwm1Regs.CMPA.half.CMPA = 800;
//    }
//    else
//    {
//        EPwm1Regs.CMPA.half.CMPA = 300;
//    }
//
//    EPwm1Regs.ETCLR.bit.INT = 1;        // Clear ePWM1 Interrupt flag
//    // Acknowledge this interrupt to receive more interrupts from group 3
//    PieCtrlRegs.PIEACK.all = 4;
//}

简短问题: I2C 编程完成后 ePWM 模块出现毛刺。 使用的 DSP 是 LAUNCHXL-F28027。  

请您帮我解决这个问题。 现在很长时间都在这里!

谢谢。

A·阿迪亚

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

    尊敬的 Aditya:

    感谢您随附的文档和代码。  当 ePWM 出现干扰时、您或许能够提供更接近/放大的示波器图像(我想看看 PWM 是否仍在运行、但图形不正确? 或者根本没有图形、并且信号是随机/不稳定的?)。

    通过一些后续问题来帮助进行调试:您是否已尝试隔离 EPWM 配置、以确保 PWM 信号在 独立于 I2C 编程时正常运行并按预期运行? 还没有参考过 ePWM 的任何 C2000Ware 示例。 此外、您能否确认您正在尝试使用向上计数(代码中的注释显示为向上向下、以便我确定)、以及您的 CMPA 值为何大于 TBPRD?

    此致、

    艾里森

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

    您好、Allison:  

    感谢您的答复。  

    我想提一下、 我在1月1日解决了这个问题。 出现此问题是由于"中断"声明不正确(见第27行)。 出于某种原因、我忘记在平台上提及它了。  

    感谢您浏览了我的查询并花了很多时间。 到目前为止、查询已解决!

    感谢您、

    阿迪亚