SAM3U (Cortex M3) und Atmel Studio, IRQ Problem

OP #4470567
Lesenswert?
• ▲
▼
Moin,

ich bin gerade dabei, ein Cortex-M3 Projekt eines 
"manuell-installierten" GCC-Compilers auf Atmel Studio 7.0 zu ändern.
Stück für Stück geht es voran, jetzt bleibe ich an einer Sache hängen, 
und zwar wenn ich im ADC_Handler (s.u.) die letzte Zeile nicht drin habe 
(LED wird per Makro ausgeschaltet), macht der Controller gar nichts 
mehr, der startet nicht mal mehr die externe Clock.
Bleibt diese Zeile drin, läuft alles. Ich hatte ein LED an/aus in den 
Handler gepackt, um zu testen, ob er überhaupt reinspringt.
Ideen?
1
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
2
/* IRQ 10bit ADC */
3
void ADC_Handler(void)
4
{
5
    u32_t status;
6
    static u8_t adc_channel = 0;
7
    static u16_t vbat_ovsmpl_sum = 0;
8
    static u8_t vbat_ovsmpl_cnt = 0;
9

10
  status = ADC->ADC_SR;
11

12
  if( status & ((u32_t)1 << adc_channel) )
13
  {
14
    if( adc_channel == ADC_CH3_VBAT )
15
    {
16
      vbat_ovsmpl_sum += (u16_t)(ADC->ADC_LCDR & 0x000003FF);
17
      vbat_ovsmpl_cnt++;
18
      if( vbat_ovsmpl_cnt == ADC_OVERSAMPLING_RATE )
19
      {
20
        adc10b_ch[ADC_CH3_VBAT] = vbat_ovsmpl_sum >> ADC_OVERSAMPLING_SHIFT;
21
        vbat_ovsmpl_cnt = 0;
22
        vbat_ovsmpl_sum = 0;
23
      }
24
    }
25
    else
26
    {
27
      adc10b_ch[adc_channel] = (u16_t)(ADC->ADC_LCDR & 0x000003FF);
28
    }
29

30
    /* switch to next channel, dis-/enable interrupts */
31
    ADC->ADC_IDR = ((u32_t)1 << adc_channel);
32
    if( adc_channel == 3 ) adc_channel = 0;
33
    else adc_channel++;
34
    ADC->ADC_IER = ((u32_t)1 << adc_channel);
35
  }
36

37
  if( status & 0x0000000F )  /* mask for adc channels 0-3 */
38
  {
39
    /* ADC control register: re-start conversion */
40
    ADC->ADC_CR = ADC_CR_START;
41
  }
42

43
PIN_LED_RED_OFF;
44
}
#4471039
Lesenswert?
• ▲
▼
Klingt komisch. Versuche mal als letzte Zeile:
1
NVIC_ClearPendingIRQ(ADC_IRQn);

Das Tail-Chaining Feature in Zusammenhang mit dem Schreibpuffer ergibt 
bei Interrupts gelegentlich doppelte Auslösungen, was einiges 
durcheinander bringen kann. Kommt insbesondere dann vor wenn das 
auslösende Flag in der letzten Zeile des Handlers erst gelöscht wird.

Bei Taktumschaltung müsste man auch aufpassen dass man den ADC nicht 
überfährt, der verträgt ja nur eine bestimmte maximale Frequenz.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.