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.

F28027PTA ADC Problem



I have an interesting problem using the ADC peripheral of the C2000 - F28027PTA, I'm using the controlCARD and Docking Station USB EMU. It's my understanding that the DSP2802x Example Code is already written for use on this MCU of the C2000 family, so there shouldn't be any clock or additional register setting changes to use the examples. With that in mind I took the example "Example_2802xAdcSoc" and modified it to use simultaneous sampling on channel pairs A0/B0 and A1/B1. It works just about as expected, results are stored like the ADC Reference guide describes with A0 results in ADCRESULT0, B0 in ADCRESULT1, and so on. The problem I am having is that channel B0 doesn't seem to actually be converting anything. I'm using CCSv4.1.2, so I set a breakpoint in the ADCINT1 ISR, run the program in the CCS debugger with nothing connected to any of the channels and check the values read in ADCRESULT0, ADCRESULT1, ADCRESULT2, and ADCRESULT3.

My Results;

 

I don't understand why ADCRESULT1 (what should be ADC Channel B0's data) always reads something in the range of 8-20 regardless of if it is grounded or connected to 3.3V (or anything else for that matter). I've included the main of my project below, any help would be appreciated. Is channel B0 possibly fried? Thanks in advance.

 

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

// Prototype statements for functions found within this file.
interrupt void adc_isr(void);
void Adc_Config(void);

// Global variables used in this example:
Uint16 LoopCount;
Uint16 ConversionCount;
Uint16 ChannelA0[10];
Uint16 ChannelB0[10];
Uint16 ChannelA1[10];
Uint16 ChannelB1[10];

main()
{

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
   InitSysCtrl();

// Step 2. 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.
   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.
   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 register
   PieVectTable.ADCINT1 = &adc_isr;
   EDIS;                                    // This is needed to disable write to EALLOW protected registers

// Step 3. Initialize all the Device ADC Peripheral:
   InitAdc();

// Step 4. User specific code, enable interrupts:
// Enable ADCINT1 in PIE
   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

// Set global variables to keep track of conversions and LoopControl while waiting for ADC Interrupts
   LoopCount = 0;
   ConversionCount = 0;

// Configure ADC
    EALLOW;                                    // This is needed to write to EALLOW protected registers
    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    = 3;    // setup EOC1 to trigger ADCINT1 to fire
   
    AdcRegs.ADCSAMPLEMODE.bit.SIMULEN0 = 1;    // Set SOC0/SOC1 to trigger simultaneous sampling
    AdcRegs.ADCSAMPLEMODE.bit.SIMULEN2 = 1;    // Set SOC2/SOC3 to trigger simultaneous sampling,
   
    AdcRegs.ADCSOC0CTL.bit.CHSEL     = 0;    // Set SOC0 channel select to ADCINA0/ADCINB0
    AdcRegs.ADCSOC2CTL.bit.CHSEL     = 1;    // Set SOC0 channel select to ADCINA0/ADCINB0
    AdcRegs.ADCSOC0CTL.bit.TRIGSEL     = 5;    // Set SOC0 start trigger on EPWM1A, due to round-robin SOC0/SOC1 converts first then SOC2/SOC3
    AdcRegs.ADCSOC2CTL.bit.TRIGSEL     = 5;    // Set SOC0 start trigger on EPWM1A, due to round-robin SOC0/SOC1 converts first then SOC2/SOC3
    AdcRegs.ADCSOC0CTL.bit.ACQPS     = 6;    // Set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
    AdcRegs.ADCSOC1CTL.bit.ACQPS     = 6;    // Set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
    AdcRegs.ADCSOC2CTL.bit.ACQPS     = 6;    // Set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
    AdcRegs.ADCSOC3CTL.bit.ACQPS     = 6;    // Set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
    EDIS;                                    // This is needed to disable write to EALLOW protected registers

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

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

}


interrupt void  adc_isr(void)
{

  ChannelA0[ConversionCount] = AdcResult.ADCRESULT0;
  ChannelB0[ConversionCount] = AdcResult.ADCRESULT1;
  ChannelA1[ConversionCount] = AdcResult.ADCRESULT2;
  ChannelB1[ConversionCount] = AdcResult.ADCRESULT3;

  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;
}