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.

28035的CLA ADC调试

大侠们,请问一下,我在运行TI的 ADC-CLA教程时,将原来的读取一路AD采样值改为两路,然后运行之后为什么程序一直停留在  Cla1ForceTask8andWait();                 // Force CLA task 8. ??

原来的意图是想用CLA进行AD转换,主程序直接读取:

代码如下:

//###########################################################################
// Description:
//!  \addtogroup f2803x_example_list
//!  <h1>CLA ADC (cla_adc)</h1>
//!
//! In this example ePWM1 is setup to generate a periodic ADC SOC.
//! Channel ADCINA2 is converted. When the ADC begins conversion,
//! it will assert ADCINT2 which will start CLA task 2.
//!
//! Cla Task2 logs 20 ADCRESULT1 values in a circular buffer.
//! When Task2 completes an interrupt to the CPU clears the ADCINT2 flag.
//!
//! \b Watch \b Variables \n
//! - VoltageCLA       - Last 20 ADCRESULT1 values
//! - ConversionCount  - Current result number
//! - LoopCount        - Idle loop counter
//
//
//###########################################################################
// $TI Release: F2803x C/C++ Header Files and Peripheral Examples V126 $
// $Release Date: November 30, 2011 $
//###########################################################################

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include "CLAShared.h"
#include <string.h>
#include <stdint.h>

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

// Global variables used in this example:
#pragma DATA_SECTION(ConversionCount0, "Cla1ToCpuMsgRAM");
#pragma DATA_SECTION(ConversionCount1, "Cla1ToCpuMsgRAM");
#pragma DATA_SECTION(VoltageCLA,      "Cla1ToCpuMsgRAM");
#pragma DATA_SECTION(CurrentCLA,      "Cla1ToCpuMsgRAM");//

Uint16 ConversionCount0;
Uint16 ConversionCount1;
Uint16 LoopCount;
Uint16 VoltageCLA[NUM_DATA_POINTS];
Uint16 CurrentCLA[NUM_DATA_POINTS];//
Uint16 x,y,a,b;
int i;
// These are defined by the linker file
extern Uint16 Cla1funcsLoadStart;
extern Uint16 Cla1funcsLoadEnd;
extern Uint16 Cla1funcsRunStart;

main()
{

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

// Step 2. Initialize GPIO:
// This example function is found in the DSP2803x_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 DSP2803x_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 DSP2803x_DefaultIsr.c.
// This function is found in DSP2803x_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 register
   PieVectTable.CLA1_INT2 = &cla1_isr2;   
   EDIS;    // This is needed to disable write to EALLOW protected registers

// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2803x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
   InitAdc();         // For this example, init the ADC

// Step 5. User specific code, enable interrupts:

// Enable ADCINT1 in PIE
   PieCtrlRegs.PIEIER11.bit.INTx2 = 1;      // Enable INT 11.2 in the PIE (CLA Task2)
   IER |= M_INT11;                          // Enable CPU Interrupt 11
   EINT;                                      // Enable Global interrupt INTM
   ERTM;                                      // Enable Global realtime interrupt DBGM

// Copy CLA code from its load address to CLA program RAM
//
// Note: during debug the load and run addresses can be
// the same as Code Composer Studio can load the CLA program
// RAM directly.
//
// The ClafuncsLoadStart, ClafuncsLoadEnd, and ClafuncsRunStart
// symbols are created by the linker.
    memcpy((uint16_t *)&Cla1funcsLoadStart,(uint16_t *)&Cla1funcsRunStart, (unsigned long)&Cla1funcsLoadEnd);

// Initialize the CLA registers
   EALLOW;
   Cla1Regs.MVECT3 = (Uint16) (&Cla1Task3 - &Cla1Prog_Start)*sizeof(Uint32); //
   Cla1Regs.MVECT2 = (Uint16) (&Cla1Task2 - &Cla1Prog_Start)*sizeof(Uint32);
   Cla1Regs.MVECT8 = (Uint16) (&Cla1Task8 - &Cla1Prog_Start)*sizeof(Uint32);
   Cla1Regs.MPISRCSEL1.bit.PERINT2SEL = CLA_INT2_ADCINT2; // ADCINT2 starts Task 2
   Cla1Regs.MMEMCFG.bit.PROGE = 1;          // Map CLA program memory to the CLA
   Cla1Regs.MCTL.bit.IACKE = 1;             // Enable IACK to start tasks via software
   Cla1Regs.MIER.all = (M_INT8 | M_INT2 | M_INT3);   // Enable Task 8 and Task 2
   Cla1ForceTask8andWait();                 // Force CLA task 8.
                                            // This will initialize ConversionCount to zero

   AdcRegs.ADCCTL1.bit.INTPULSEPOS = 0;        // ADCINT trips when ADC begins conversion

   AdcRegs.INTSEL1N2.bit.INT2E     = 1;        // Enable ADCINT2
   AdcRegs.INTSEL1N2.bit.INT2CONT  = 0;        // Disable ADCINT2 Continuous mode
   AdcRegs.INTSEL1N2.bit.INT2SEL   = 1;        // setup EOC1 to trigger ADCINT2 to fire

   AdcRegs.ADCSOC1CTL.bit.CHSEL    = 1;        // set SOC1 channel select to ADCINA2
   AdcRegs.ADCSOC1CTL.bit.TRIGSEL  = 5;     // set SOC1 start trigger on EPWM1A
   AdcRegs.ADCSOC1CTL.bit.ACQPS    = 6;        // set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

   AdcRegs.ADCSOC2CTL.bit.CHSEL    = 2;        // set SOC1 channel select to ADCINA2
   AdcRegs.ADCSOC2CTL.bit.TRIGSEL  = 5;     // set SOC1 start trigger on EPWM1A
   AdcRegs.ADCSOC2CTL.bit.ACQPS    = 6;        // set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
   EDIS;

// Assumes ePWM1 clock is already enabled in InitSysCtrl();
   EALLOW;
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
   EDIS;
   EPwm1Regs.ETSEL.bit.SOCAEN    = 1;        // Enable SOC on A group
   EPwm1Regs.ETSEL.bit.SOCASEL    = 4;        // Select SOC from from CPMA on upcount
   EPwm1Regs.ETPS.bit.SOCAPRD     = 1;        // Generate pulse on 1st event
   EPwm1Regs.CMPA.half.CMPA     = 0x2EE;    // Set compare A value
   EPwm1Regs.TBPRD                 = 0x5DC;    // Set period for ePWM1 - this will determine the sampling frequency(20KHz)
   
   EPwm1Regs.TBCTL.bit.CTRMODE     = 0;        // count up and start
   EALLOW;
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
   EDIS;
   
   
// Wait for ADC interrupt
   for(;;)
   {
      LoopCount++;
      x = VoltageCLA[0];
      y = CurrentCLA[0];
   }

}

// This interrupt occurs when CLA Task 2 completes
__interrupt void cla1_isr2()
{
    AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;    // Clear ADCINT2 flag reinitialize for next SOC
    PieCtrlRegs.PIEACK.all = 0xFFFF;
}

CLA.ASM:

;// TI File $Revision: /main/8 $
;// Checkin $Date: October 7, 2010   11:41:29 $
;//###########################################################################
;//
;// FILE:  DSP2803x_Cla.asm
;//
;// TITLE: CLA Assembly Code.
;//
;// This file contains the CLA assembly code.  When building the project
;// containing this file, use C28x codegen V5.2.0 or later with the switch
;// --cla_support=cla0
;//
;//###########################################################################
;// $TI Release: F2803x C/C++ Header Files and Peripheral Examples V126 $
;// $Release Date: November 30, 2011 $
;//###########################################################################

;// Include variables and constants that will be shared in the
;// C28x C-code and CLA assembly code.  This is accomplished by
;// using .cdecls to include a C-code header file that contains
;// these variables and constants

      .cdecls   C,LIST,"CLAShared.h"

;// To include an MDEBUGSTOP (CLA breakpoint) as the first instruction
;// of each task, set CLA_DEBUG to 1.  Use any other value to leave out
;// the MDEBUGSTOP instruction.

CLA_DEBUG .set  1

;// CLA code must be within its own assembly section and must be
;// even aligned.  Note: since all CLA instructions are 32-bit
;// this alignment naturally occurs and the .align 2 is most likely
;// redundant

      .sect    "Cla1Prog"
      .align  2


_Cla1Prog_Start:

_Cla1Task1:
    MSTOP
    MNOP
    MNOP
    MNOP
_Cla1T1End:


_Cla1Task2:
    .if CLA_DEBUG == 1
        MDEBUGSTOP
    .endif
;==============================================
; This task logs the last NUM_DATA_POINTS
; ADCRESULT1 values in the array VoltageCLA
;
; When the last element in the array has been
; filled, the task will go back to the
; the first element.
;
; Before starting the ADC conversions, force
; Task 8 to initialize the ConversionCount to zero
;
;==============================================
    MMOVZ16    MR0,  @_ConversionCount0        ;1 Current Conversion
    MMOV16     MAR1, MR0, #_VoltageCLA        ;2 Point to VoltageCLA[ConversionCount]
    MUI16TOF32 MR0,  MR0                      ;3 Convert count to float32
    MADDF32    MR0,  MR0, #1.0                ;4 Add 1 to conversion count
    MCMPF32    MR0,  #NUM_DATA_POINTS.0       ;5 Compare count to max
    MF32TOUI16 MR0,  MR0                      ;6 Convert count to Uint16
    MNOP                                      ;7 Wait till I8 to read result
    MMOVZ16    MR2,  @_AdcResult.ADCRESULT1   ;8 Read ADCRESULT1
    MMOV16     *MAR1, MR2                     ;  Store ADCRESULT1
    MBCNDD     _RestartCount0, GEQ             ;  If count >= NUM_DATA_POINTS
    MMOVIZ     MR1,  #0.0                     ;  Always executed: load MR1 with 0
    MNOP
    MNOP
    MMOV16      @_ConversionCount0, MR0        ;  If branch not taken, store current count
    MSTOP
_RestartCount0
    MMOV16      @_ConversionCount0, MR1        ;  If branch taken, restart count
    MSTOP
    MNOP
    MNOP
    MNOP
_Cla1T2End:


_Cla1Task3:
    .if CLA_DEBUG == 1
        MDEBUGSTOP
    .endif
;==============================================
; This task logs the last NUM_DATA_POINTS
; ADCRESULT1 values in the array VoltageCLA
;
; When the last element in the array has been
; filled, the task will go back to the
; the first element.
;
; Before starting the ADC conversions, force
; Task 8 to initialize the ConversionCount to zero
;
;==============================================
    MMOVZ16    MR0,  @_ConversionCount1        ;1 Current Conversion
    MMOV16     MAR1, MR0, #_CurrentCLA        ;2 Point to VoltageCLA[ConversionCount]
    MUI16TOF32 MR0,  MR0                      ;3 Convert count to float32
    MADDF32    MR0,  MR0, #1.0                ;4 Add 1 to conversion count
    MCMPF32    MR0,  #NUM_DATA_POINTS.0       ;5 Compare count to max
    MF32TOUI16 MR0,  MR0                      ;6 Convert count to Uint16
    MNOP                                      ;7 Wait till I8 to read result
    MMOVZ16    MR2,  @_AdcResult.ADCRESULT2   ;8 Read ADCRESULT1
    MMOV16     *MAR1, MR2                     ;  Store ADCRESULT1
    MBCNDD     _RestartCount1, GEQ             ;  If count >= NUM_DATA_POINTS
    MMOVIZ     MR1,  #0.0                     ;  Always executed: load MR1 with 0
    MNOP
    MNOP
    MMOV16      @_ConversionCount1, MR0        ;  If branch not taken, store current count
    MSTOP
_RestartCount1
    MMOV16      @_ConversionCount1, MR1        ;  If branch taken, restart count
    MSTOP
    MNOP
    MNOP
    MNOP
_Cla1T3End:


_Cla1Task4:
    MSTOP
    MNOP
    MNOP
    MNOP
_Cla1T4End:


_Cla1Task5:
    MSTOP
    MNOP
    MNOP
    MNOP
_Cla1T5End:

_Cla1Task6:
    MSTOP
    MNOP
    MNOP
    MNOP
_Cla1T6End:

_Cla1Task7:
    MSTOP
    MNOP
    MNOP
    MNOP
_Cla1T7End:

_Cla1Task8:
;==============================================
; This task initializes the ConversionCount
; to zero
;==============================================
    MMOVIZ  MR0,  #0.0
    MMOV16  @_ConversionCount0, MR0
    MMOVIZ  MR0,  #0.0
    MMOV16  @_ConversionCount1, MR0
    MSTOP
_Cla1T8End:



_Cla1Prog_End:


    .end
    .include "CLAShared.h"




不清楚哪里出了问题,实际运行中没办法读取到AD的值。

  • Sam,

    把memcpy代码修改一下,原代码有误,改成下面。

    // The ClafuncsLoadStart, ClafuncsLoadEnd, and ClafuncsRunStart
    // symbols are created by the linker.
        memcpy((uint16_t *)&Cla1funcsRunStart,(uint16_t *)&Cla1funcsLoadStart, (unsigned long)&Cla1funcsLoadSize);

    另外,应该让EOC2触发ADCINT2,这样你读才能够读到最新的ADC SOC2的值

    AdcRegs.INTSEL1N2.bit.INT2SEL   = 2;     // setup EOC2 to trigger ADCINT2 to fire

    Eric