Entendiendo ADC - TMS32F28027

2

Soy nuevo en microcontroladores. Modifiqué el ejemplo de Adc_Soc, de modo que el temporizador 0 de la CPU dispara ADCINA7. El CPU Timer 0 está configurado con 60MHz y el período es de 2 segundos. También incrementé una variable (LoopCount) dentro de adc_isr.

Mi duda es que si estoy activando el SOC8 con CPU Timer 0 por cada 2 segundos, entonces la variable (LoopCount) debería incrementarse cada dos segundos. Pero aquí aumenta rápidamente en miles en un segundo. ¿Por que es esto entonces? Y por favor corríjame si me equivoco.

Edición 1: en lugar de declarar y definir la Interrupción _isr en main.c, usé f2802x_defaultisr.c y ahora el valor del registro ADC se actualiza cada 2 segundos. Pero aún no sé dónde me equivoqué con el código anterior (interrupt_isr en main.c). Por favor, ayúdame.

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
// Prototype statements for functions found within this file.
interrupt void adc_isr(void);
//interrupt void cputimer0_isr(void);
void Adc_Config(void);

// Global variables used in this example:
volatile uint16_t Voltage;
uint16_t LoopCount;


main()
{

    // WARNING: Always ensure you call memcpy before running any functions from RAM
// InitSysCtrl includes a call to a RAM based function and without a call to
// memcpy first, the processor will go "into the weeds"
#ifdef _FLASH
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif

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 f2802x_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 f2802x_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 f2802x_DefaultIsr.c.
// This function is found in f2802x_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.ADCINT1 = &adc_isr;
//   PieVectTable.TINT0 = &cputimer0_isr;
   EDIS;    // This is needed to disable write to EALLOW protected registers

// Step 4. Initialize all the Device Peripherals:
// This function is found in f2802x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
   ConfigCpuTimer(&CpuTimer0, 60, 2000000);
   CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
   InitAdc();  // For this example, init the ADC

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

// Enable ADCINT1 & CPUTIMER0 in PIE
   PieCtrlRegs.PIEIER1.bit.INTx1 = 1;   // Enable INT 1.1 in the PIE
   PieCtrlRegs.PIEIER1.bit.INTx7 = 1;   // PIE Group 1 Vector INT1.7 --> CPU Timer 0

   IER |= M_INT1;                       // Enable CPU         Interrupt 1
   EINT;                                // Enable Global     interrupt INTM
   ERTM;                                // Enable Global     realtime interrupt DBGM

   LoopCount = 0;

// Configure ADC

//Note: Channel ADCINA4  will be double sampled to workaround the ADC 1st sample issue for rev0 silicon errata  

EALLOW;
AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 0;  // SOC Priority is handled in round robin mode
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   = 8;    //setup EOC8 to trigger ADCINT1 to fire
AdcRegs.ADCSOC8CTL.bit.CHSEL    = 7;    //set SOC8 channel select to ADCINA7
AdcRegs.ADCSOC8CTL.bit.TRIGSEL  = 1;    //set SOC8 start trigger on CPUTIMER0
AdcRegs.ADCSOC8CTL.bit.ACQPS    = 6;    //set SOC8 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;

EDIS;

// Wait for ADC interrupt
    while(1)
    {}

}
interrupt void  adc_isr(void)
{

  Voltage = AdcResult.ADCRESULT8;  //discard ADCRESULT0 as part of the workaround to the 1st sample errata for rev0
  GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;
  AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;     //Clear ADCINT1 flag reinitialize for next SOC
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE

  LoopCount++;
  if(LoopCount == 38000)
  {
      LoopCount = 0;
  }
  return;
}
    
pregunta ikarp66

1 respuesta

1

1) Su código (tal como lo presentó aquí ahora) no funciona. Inicializó y habilitó la interrupción de CpuTimer0, pero no la asignó a ningún ISR, por lo tanto, caerá en el ISR predeterminado que se puede encontrar en el archivo fuente f2802_defaultisr.c y se quedará allí para siempre hay infinito para bucle).

Has habilitado la interrupción de CpuTimer en esta línea:

CpuTimer0Regs.TCR.all = 0x4001;

Al utilizar CpuTimer, junto con ADC, eso significa que también debe leer el manual que trata del temporizador de CPU y los registros apropiados. Aquí está el enlace (página 62, solo un par de páginas).

2) Tienes tantas interrupciones de ADC porque no has configurado el temporizador ( el problema principal ). Esta línea de código en realidad no hace nada:

ConfigCpuTimer(&CpuTimer0, 60, 2000000);

¡Y no has inicializado CpuTimer0 ! En este momento es un puntero simple que apunta a una ubicación aleatoria. Lo que significa que también estás escribiendo 2000000 en una ubicación aleatoria. Para inicializarlo, debe ejecutar la siguiente función antes de llamar a ConfigCpuTimer :

InitCpuTimers();        // initialize Cpu Timers

Luego, CpuTimer0 apuntará al registro periférico real. Para obtener más información, puede consultar el ejemplo de Cpu_Timer . O también puede escribir su propio procedimiento de inicialización. Eso es un pedazo de pastel.

3) Realice todos los pasos de inicialización de sus periféricos antes de ( !!! ) habilitar las interrupciones:

  EINT;  // Enable Global     interrupt INTM

De lo contrario, puede ser una gran fuente de errores.

4) Para preguntas específicas, con respecto a la familia MCU C2000, es mucho mejor preguntarles en foro de TI directamente. Hay muchos expertos en TI que están listos para ayudarlo con cualquier pregunta específica.

    
respondido por el GAttuso

Lea otras preguntas en las etiquetas