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.

TMS320F28035: TMS320F28035 ADC采样问题

Part Number: TMS320F28035
Other Parts Discussed in Thread: C2000WARE

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

#define SYSCLK 60E6 // 60MHz system clock
#define PWMFREQ 100E3 // 100kHz PWM frequency
#define DUTY_CYCLE 0.20// duty cycle
#define DEAD_BAND 0 // dead band

#define TB_PERIOD (SYSCLK / PWMFREQ) // Calculate period for up-down count mode to 100khz
//#define TB_PERIOD (SYSCLK / (2 * PWMFREQ)) // Calculate period for up-down count mode
//#define TB_PERIOD (SYSCLK / (4 * PWMFREQ)) // Calculate period for up-down count mode

#define DUTY_VALUE (TB_PERIOD * DUTY_CYCLE)
#define DB_VALUE (TB_PERIOD * DEAD_BAND)

//*********************************************************************

__interrupt void adc_isr(void);
void Adc_Config(void);

// Global variables used in this example:
Uint16 LoopCount;
Uint16 ConversionCount;
Uint16 Voltage1[10];
Uint16 Voltage2[10];
Uint16 Voltage3[10];
Uint16 Voltage4[10];
Uint16 Voltage5[10];

void SetGpio()
{
    EALLOW;

    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // Configure GPIO0 as EPWM1A
    GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; //Set as output

    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // Configure GPIO1 as EPWM1B
    GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; //Set as output

    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0; //Set as GPIO
    GpioCtrlRegs.GPADIR.bit.GPIO20 = 1;  //Set as output

    GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; //Set as GPIO
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;  //Set as output

    GpioDataRegs.GPADAT.bit.GPIO20 = 0;//Set GPIO20 to low,RED LIGHT
    GpioDataRegs.GPBDAT.bit.GPIO34 = 0;//Set GPIO34 to low,GREEN LIGHT

    EDIS;
}

void SetEPWM1(void)
{

        EPwm1Regs.TBPRD = TB_PERIOD; // Period = 15000 TBCLK counts
        EPwm1Regs.CMPA.half.CMPA = DUTY_VALUE; // Set 50% fixed duty for EPWM1A
        EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Asymmetrical mode
        EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module
        EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
        EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;

        EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
        EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero

        EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPWM1A
        EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;

        EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
        EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary

        EPwm1Regs.DBFED = DB_VALUE; // FED = 300 TBCLKs initially
        EPwm1Regs.DBRED = DB_VALUE; // RED = 300 TBCLKs initially

    //    EPwm1Regs.DBFED = FED1_NewValue; // Update ZVS transition interval
    //    EPwm1Regs.DBRED = RED1_NewValue; // Update ZVS transition interval

}

void SetEPWM2(void)
{

    // EPWM Module 2 config
    EPwm2Regs.TBPRD = TB_PERIOD; // Period = 15000 TBCLK counts
    EPwm2Regs.CMPA.half.CMPA = DUTY_VALUE; // Set 50% fixed duty EPWM2A
    EPwm2Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero initially
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
    EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Asymmetrical mode
    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module
    EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-through

    EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
    EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero

//    EPwm2Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // set actions for EPWM2A
//    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;
    EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPWM2A
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;

    EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
    EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary

    EPwm2Regs.DBFED = DB_VALUE; // FED = 30 TBCLKs initially
    EPwm2Regs.DBRED = DB_VALUE; // RED = 40 TBCLKs initially
    // Run Time (Note: Example execution of one run-time instant)
    //============================================================
    EPwm2Regs.TBPHS.half.TBPHS = TB_PERIOD / 2;
//    EPwm2Regs.TBPHS.half.TBPHS = 15000 - yixiangjiao; // Set Phase reg to 300/1200 * 360 = 90 deg
//    EPwm2Regs.DBFED = FED2_NewValue; // Update ZVS transition interval
//    EPwm2Regs.DBRED = RED2_NewValue; // Update ZVS transition interval

}

__interrupt void  adc_isr(void)
{

  Voltage1[ConversionCount] = AdcResult.ADCRESULT1; //discard ADCRESULT0 as part of the workaround to the 1st sample errata for rev0
  Voltage2[ConversionCount] = AdcResult.ADCRESULT2;
  Voltage3[ConversionCount] = AdcResult.ADCRESULT3;
  Voltage4[ConversionCount] = AdcResult.ADCRESULT4;
  Voltage5[ConversionCount] = AdcResult.ADCRESULT5;


  // If 20 conversions have been logged, start over
  if(ConversionCount == 9)
  {
     ConversionCount = 0;
  }
  else ConversionCount++;

  AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;     //Clear ADCINT1 flag reinitialize for next SOC
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE

  return;
}


void main(void)
{
    InitSysCtrl();  // 初始化系统时钟和PLL

    SetGpio(); // Initialize GPIO

    DINT;   // 禁止所有中断

    InitPieCtrl();  // 初始化和启用CPU PIE

    IER = 0x0000;
    IFR = 0x0000;

    InitPieVectTable();  // 初始化PIE向量表

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;  // 停止所有ePWM时钟
    EDIS;

    SetEPWM1();  // 初始化ePWM1
    SetEPWM2();  // 初始化ePWM2

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;  // 启动所有ePWM时钟
    EDIS;

    EALLOW;             // This is needed to write to EALLOW protected register
    PieVectTable.ADCINT1 = &adc_isr;
    EDIS;    // This is needed to disable write to EALLOW protected registers

    //
    // Step 4. Initialize all the Device Peripherals:
    //
    InitAdc();  // For this example, init the ADC
    AdcOffsetSelfCal();

    PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable INT 1.1 in the PIE
    IER |= M_INT1;                     // Enable CPU Interrupt 1
    EINT;                              // Enable Global interrupt INTM
    ERTM;                              // Enable Global realtime interrupt DBGM

    LoopCount = 0;
    ConversionCount = 0;


    EALLOW;
    AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; //ADCINT1 trips after AdcResults latch
    AdcRegs.INTSEL1N2.bit.INT1E     = 1; // Enabled ADCINT1
    AdcRegs.INTSEL1N2.bit.INT1CONT  = 0; // Disable ADCINT1 Continuous mode
    AdcRegs.INTSEL1N2.bit.INT1SEL   = 2;  // setup EOC2 to trigger ADCINT1 to fire
    AdcRegs.ADCSOC0CTL.bit.CHSEL    = 1;    //set SOC0 channel select to ADCINA1(dummy sample for rev0 errata workaround)
    AdcRegs.ADCSOC1CTL.bit.CHSEL    = 1;    //set SOC1 channel select to ADCINA1
    AdcRegs.ADCSOC2CTL.bit.CHSEL    = 2;    //set SOC2 channel select to ADCINA2
    AdcRegs.ADCSOC3CTL.bit.CHSEL    = 3;    //set SOC3 channel select to ADCINA3
    AdcRegs.ADCSOC4CTL.bit.CHSEL    = 4;    //set SOC4 channel select to ADCINA4
    AdcRegs.ADCSOC5CTL.bit.CHSEL    = 6;    //set SOC5 channel select to ADCINA6

    AdcRegs.ADCSOC0CTL.bit.TRIGSEL  = 9;    //set SOC0 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
    AdcRegs.ADCSOC1CTL.bit.TRIGSEL  = 9;    //set SOC1 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
    AdcRegs.ADCSOC2CTL.bit.TRIGSEL  = 9;    //set SOC2 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
    AdcRegs.ADCSOC3CTL.bit.TRIGSEL  = 9;    //set SOC3 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
    AdcRegs.ADCSOC4CTL.bit.TRIGSEL  = 9;    //set SOC4 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
    AdcRegs.ADCSOC5CTL.bit.TRIGSEL  = 9;    //set SOC5 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2

    AdcRegs.ADCSOC0CTL.bit.ACQPS    = 6;    //set SOC0 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
    AdcRegs.ADCSOC1CTL.bit.ACQPS    = 6;    //set SOC1 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
    AdcRegs.ADCSOC2CTL.bit.ACQPS    = 6;    //set SOC2 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
    AdcRegs.ADCSOC3CTL.bit.ACQPS    = 6;    //set SOC3 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
    AdcRegs.ADCSOC4CTL.bit.ACQPS    = 6;    //set SOC4 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
    AdcRegs.ADCSOC5CTL.bit.ACQPS    = 6;    //set SOC5 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)

    EDIS;

    //
    // Assumes ePWM1 clock is already enabled in InitSysCtrl();
    //
    EPwm3Regs.ETSEL.bit.SOCAEN  = 1;    // Enable SOC on A group
    EPwm3Regs.ETSEL.bit.SOCASEL = 4;    // Select SOC from from CPMA on upcount
    EPwm3Regs.ETPS.bit.SOCAPRD  = 1;    // Generate pulse on 1st event
    EPwm3Regs.CMPA.half.CMPA    = 0x0080;       // Set compare A value
    EPwm3Regs.TBPRD                 = 0xFFFF;   // Set period for ePWM1
    EPwm3Regs.TBCTL.bit.CTRMODE     = 0;        // count up and start

    //
    // Wait for ADC interrupt
    //
    for(;;)
    {
        LoopCount++;
    }

}

代码在生成pwm波形的基础上,加入了基于官方例程Example_2803xAdcSoc修改而来的代码。

代码的目的是通过输入电压来改变pwm的占空比,所以需要先将pwm的代码和adc采样代码合并在一起。

adc和pwm代码作为两个独立的程序运行时是没问题的。但是两个程序合并之后adc代码就不正常了,采样值高达几万。pwm程序是正常的。

我感觉是主程序的问题:

void main(void)
{
InitSysCtrl(); // 初始化系统时钟和PLL

SetGpio(); // Initialize GPIO

DINT; // 禁止所有中断

InitPieCtrl(); // 初始化和启用CPU PIE

IER = 0x0000;
IFR = 0x0000;

InitPieVectTable(); // 初始化PIE向量表

EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // 停止所有ePWM时钟
EDIS;

SetEPWM1(); // 初始化ePWM1
SetEPWM2(); // 初始化ePWM2

EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // 启动所有ePWM时钟
EDIS;

EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT1 = &adc_isr;
EDIS; // This is needed to disable write to EALLOW protected registers

//
// Step 4. Initialize all the Device Peripherals:
//
InitAdc(); // For this example, init the ADC
AdcOffsetSelfCal();

PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable INT 1.1 in the PIE
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

LoopCount = 0;
ConversionCount = 0;


EALLOW;
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; //ADCINT1 trips after AdcResults latch
AdcRegs.INTSEL1N2.bit.INT1E = 1; // Enabled ADCINT1
AdcRegs.INTSEL1N2.bit.INT1CONT = 0; // Disable ADCINT1 Continuous mode
AdcRegs.INTSEL1N2.bit.INT1SEL = 2; // setup EOC2 to trigger ADCINT1 to fire
AdcRegs.ADCSOC0CTL.bit.CHSEL = 1; //set SOC0 channel select to ADCINA1(dummy sample for rev0 errata workaround)
AdcRegs.ADCSOC1CTL.bit.CHSEL = 1; //set SOC1 channel select to ADCINA1
AdcRegs.ADCSOC2CTL.bit.CHSEL = 2; //set SOC2 channel select to ADCINA2
AdcRegs.ADCSOC3CTL.bit.CHSEL = 3; //set SOC3 channel select to ADCINA3
AdcRegs.ADCSOC4CTL.bit.CHSEL = 4; //set SOC4 channel select to ADCINA4
AdcRegs.ADCSOC5CTL.bit.CHSEL = 6; //set SOC5 channel select to ADCINA6

AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 9; //set SOC0 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 9; //set SOC1 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 9; //set SOC2 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 9; //set SOC3 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 9; //set SOC4 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 9; //set SOC5 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2

AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; //set SOC0 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; //set SOC1 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
AdcRegs.ADCSOC2CTL.bit.ACQPS = 6; //set SOC2 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
AdcRegs.ADCSOC3CTL.bit.ACQPS = 6; //set SOC3 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
AdcRegs.ADCSOC4CTL.bit.ACQPS = 6; //set SOC4 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
AdcRegs.ADCSOC5CTL.bit.ACQPS = 6; //set SOC5 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)

EDIS;

//
// Assumes ePWM1 clock is already enabled in InitSysCtrl();
//
EPwm3Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
EPwm3Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount
EPwm3Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
EPwm3Regs.CMPA.half.CMPA = 0x0080; // Set compare A value
EPwm3Regs.TBPRD = 0xFFFF; // Set period for ePWM1
EPwm3Regs.TBCTL.bit.CTRMODE = 0; // count up and start

//
// Wait for ADC interrupt
//
for(;;)
{
LoopCount++;
}

}

不知道是不是配置的步骤有问题还是怎么的,求大神帮忙看一下。