mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AT91SAM7 ADC mit Interrupt


Autor: Nobbie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin gerade dabei, das ADC Modul mit Multichannel, Softwaretriggerung 
und Interrupt zu programmieren.
Nachfolgend mal der Quellcode:
unsigned int adc_Init(void)
{
  // reset
  AT91F_ADC_SoftReset(AT91C_BASE_ADC);

  // enable peripheral clock ADC
  AT91F_ADC_CfgPMC();

  // config timing of ADC 55Mhz mainclock, ADC clock 5MHz
  AT91F_ADC_CfgTimings(AT91C_BASE_ADC, 
                       55     /*MHz   MCK*/, 
                       5      /*MHz   ADCCK*/,
           20     /*uSec  startup time*/, 
                       700    /*nSec  sample and hold*/);

  // enable channels to measure
  // channel 0
  // channel 1
  // channel 2
  // channel 3
  AT91F_ADC_EnableChannel(AT91C_BASE_ADC,
                          (AT91C_ADC_CH0 | AT91C_ADC_CH1 | AT91C_ADC_CH2 | AT91C_ADC_CH3));
        
  
  // enable interrupt of the last ADC channel 3
  AT91F_ADC_EnableIt(AT91C_BASE_ADC, (AT91C_ADC_CH3));
  
  // configure AIC
  AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, 
                        AT91C_ID_ADC,
                        AT91C_AIC_PRIOR_HIGHEST,
      AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, 
                        adc_ISR);
  
  // enable AIC
  AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_ADC);

  return 0;
}

static void adc_ISR(void)
{
  unsigned int uiStatus   = 0;
  

  // read status register
  uiStatus = AT91C_BASE_ADC->ADC_SR;
  uiStatus = uiStatus;

  if(uiStatus & AT91C_ADC_CH3)
  {
    // read ADC value
    ui_ValueCH0 = AT91F_ADC_GetConvertedDataCH0(AT91C_BASE_ADC);
    ui_ValueCH1 = AT91F_ADC_GetConvertedDataCH1(AT91C_BASE_ADC);
    ui_ValueCH2 = AT91F_ADC_GetConvertedDataCH2(AT91C_BASE_ADC);
    ui_ValueCH3 = AT91F_ADC_GetConvertedDataCH3(AT91C_BASE_ADC);
    
    // set valid
    adc_bool_Conversation_Valid = TRUE;

  }
 
  // clear interrupt
  AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_ADC);
}

unsigned int adc_StartConversation(void)
{
  adc_bool_Conversation_Valid = FALSE;
  AT91F_ADC_StartConversion(AT91C_BASE_ADC);
  return 0;
}

Der Anstoss für die ADC erfolgt asynchron durch einen Softwaretrigger.
Mein Problem ist jetzt, dass die ADC genau einmal sauber funktioniert. 
Bei allen weiteren 
Softwaretriggers(AT91F_ADC_StartConversion(AT91C_BASE_ADC)) wird die ISR 
nicht mehr ausgeführt.

Hat jemand eine Idee woran das liegen kann?

Danke Nobbie

Autor: Carsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weiß dass ich zu spät dran bin, aber was solls :-)

Damit schaltest du den Interrrupt wieder aus:
AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_ADC);

Du musst ihn wieder einschalten
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_ADC);

oder den Interrrupt eingeschaltet lassen ...

Bitte,

Carsten

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.