Forum: Mikrocontroller und Digitale Elektronik TMS320F28335 ADC - erste Schritte


von Chris E. (chec)


Lesenswert?

Hallo Community,
ich heiße Chris und bin ein E-Technikstudent der sich grade in seiner 
Bachelorarbeit befindet.
Als Thema habe ich die Programmierung eines Umrichters für einen BLDC 
Motor.Dieser Umrichter wird durch einen TMS320F28335 gesteuert.
Da ich mit Controllern von TI noch nie vorher etwas zutun hatte ( 
lediglich AVR ATMega's) ist das hier alles neu für mich. Ich sitze schon 
einige Zeit dran den ADC zum laufen zu bekommen,was mir aber nicht so 
recht gelingen will. Das Ziel ist es schließlich duch einen Poti eine 
ausgegebene PWM zu steuern.

Für erste Schritte, und nachdem ich mich durch den Reference Guide 
glesen habe, habe ich diesen eigentlich simplen Code geschrieben:







#include "DSP2833x_Device.h"

#include "DSP2833x_Examples.h"




Uint16 Wert;




// Prototype statements for functions found within this file.

void Gpio_example1(void);
void AD_conv(void);
void delay_loop(void);


void main(void)
{

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


   //Clock settings

      EALLOW;
      SysCtrlRegs.HISPCP.all = 0x4;
      EDIS;


// Step 2. Initalize GPIO:
// This example function is found in the DSP280x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
   // InitGpio();  // Skipped for this example

// For this example use the following configuration:
   // Gpio_select();

   EALLOW;

       GpioCtrlRegs.GPAPUD.bit.GPIO31 = 1;//disable pullup
       GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 0;//GPIO31 = GPIO31
       GpioCtrlRegs.GPADIR.bit.GPIO31 = 1;//OUTPUT


       EDIS;

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
   DINT;

// Initialize 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 DSP280x_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 DSP280x_DefaultIsr.c.
// This function is found in DSP280x_PieVect.c.
   InitPieVectTable();




// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP280x_InitPeripherals.c
// InitPeripherals(); // Not required for this example

 InitAdc();


   //ADC Konfigurieren

  AdcRegs.ADCMAXCONV.all = 0x0;    // Eine einzige Wandlung vornehmen
  AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x1;   // ADCINA0 als Eingang der 
Wandlung ausgewählt







// Step 5. User specific code:


Gpio_example1();
}

void AD_Conv(void)
{
  AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; //start SOC von SEQ1,anschließend 
Kontinuerlicher Modus

  while(AdcRegs.ADCST.bit.INT_SEQ1 == 0)     //Warte bis Wandlung 
vollzogen ist
  {     }

  Wert = AdcRegs.ADCRESULT0;    //Übergeben des AD-Wertes



  AdcRegs.ADCTRL2.bit.RST_SEQ1 =1; // Rücksetzen des Sequencer1




}
//---------------------------------------------------------------------- 
---
void delay_loop(void)
{
   long int a;

   AD_Conv();

  a =Wert*1500;

 for(;a<6144000;a++)
 {

 }

 }

//---------------------------------------------------------------------- 
------

void Gpio_example1(void)
{
   // Example 1:
   // Toggle I/Os using DATA registers

   for(;;)
   {


         GpioDataRegs.GPADAT.bit.GPIO31=1;  //LED2-ON
          delay_loop();

         GpioDataRegs.GPADAT.bit.GPIO31=0;  //LED2-OFF
          delay_loop();






    }
}



Es geht eigentlich nur darum die Blinkfrequenz einer LED zu steuern. 
Mein Problem ist das sich die Werte im ADCRESULT0 nichtmehr 
verändern,sondern es bleibt konstant bei einem Wert.

Hat hier vielleicht jemand Tipp's für mich woran das liegt? Nachdem die 
Wandlung vollzogen ist wird der Wert übergeben und der Sequencer 
zurückgesetzt.Demnach muss er bei der Wandlung den Wert wieder in das 
ADCRESULT0 Register schreiben. Ich bin hier noch am verzweifeln...
Als Hardware nutze ich die Dockingstation von TI.Diese stellt für das 
Poti 3,3V Spannung zur verfügung.

von Stefan W. (bier16v)


Lesenswert?

Ok, und stimmt der "Wert" auch mit dem Spannungswert am Poti überein?
Bist du dir sicher, dass der ADC im kontinuerlichen Modus arbeitet?
Was genau bewirt das Rücksetzen des Sequencer1? Ich vermute, dass 
AD_Conv(void) bei jedem ADC-Interrupt ausgeführt wird.
Wäre es nicht besser, die ganze Konfiguration (Sequenzer, ...) beim 
InitADC zu machen, du änderst ja im Betrieb nichts mehr.
Vielleicht hilft es "Wert" als valotile zu definieren.
Und die letzte Frage, wie schaut InitAdc() aus?

Von TI gibt es normalerweise sehr viel Beispiel-Code (z.B. CONTROLSUITE)

von Stefan W. (bier16v)


Lesenswert?

vielleicht liegt darin der Hund begraben.
>> AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x1;   // ADCINA0 als Eingang ...

Schau dir mal http://www.ti.com/lit/ug/spru812a/spru812a.pdf an (Seite 
18)
"// Setup conv from ADCINA1 &amp; ADCINB1"
Für ADCINA0 müsste bei der der Wert 0x0 stehen.

von Chris E. (chec)


Lesenswert?

Stefan W. schrieb:
> vielleicht liegt darin der Hund begraben.
>>> AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x1;   // ADCINA0 als Eingang ...

Danke! Das war tatsächlich der Fehler.Läuft jetzt einwandfrei!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.