- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 1 von 1

Thema: ATXMega DMA Transaction Complete Interrupt kommt zu oft

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578

    ATXMega DMA Transaction Complete Interrupt kommt zu oft

    Anzeige

    E-Bike
    Hi,

    ich möchte mit einem ATXMega192A3U die Werte eines ADC-Channels (ADCA.CH0) in ein Array ablegen, getriggert durch einen Timer (TCC1).
    Der ADC ansich funktioniert, der Timer auch (wenn ich den OVF des Timers nutze).
    Der Timer Period Wert ist auf 1000 gesetzt, das ergibt bei einem Prescaler = 1 einen (virtuellen) Timer-OVF alle 31.25us (bei 32MHz). TRFCNT ist auf 64 gesetzt, das sollte dann einen Transaction Complete Interrupt alle 2ms geben.
    Leider hab ich wohl irgendwo einen Fehler drin, kann ihn aber nicht finden. Vielleicht fällt euch ja was auf:
    Code:
    void InitDmaCh3(void)
    {
        DMA.CH3.REPCNT = 0; //unlimited repeat
        DMA.CH3.CTRLA = 0xA5; //CH enable, repeat enabled, singleshot enabled, 2byte burst
        DMA.CH3.CTRLB = 0x01; //Channel Transaction Complete Lvl = Low
        DMA.CH3.ADDRCTRL = 0x9D; //SAR=Burst,SAM=INC,DAR=Transaction,DAM=INC
        DMA.CH3.TRIGSRC = 0x46; //TCC1 OVF
        DMA.CH3.TRFCNT = 64; //******************************
        DMA.CH3.SRCADDR0 = (((uint32_t)(&ADCA.CH0.RES))>>0*8) & 0xFF;
        DMA.CH3.SRCADDR1 = (((uint32_t)(&ADCA.CH0.RES))>>1*8) & 0xFF;
        DMA.CH3.SRCADDR2 = (((uint32_t)(&ADCA.CH0.RES))>>2*8) & 0xFF;
        DMA.CH3.DESTADDR0 = (((uint32_t)(&AdcArray[0]))>>0*8) & 0xFF;
        DMA.CH3.DESTADDR1 = (((uint32_t)(&AdcArray[0]))>>1*8) & 0xFF;
        DMA.CH3.DESTADDR2 = (((uint32_t)(&AdcArray[0]))>>2*8) & 0xFF;
    }
    
    void InitAdcReglerTimer(void)
    {
        TCC1.CTRLA = 0x01; //Prescaler = 1
        TCC1.CTRLB = 0x00; //Normal Mode
        TCC1.INTCTRLA = 0x00; //No Interrupt
        TCC1.PER = 1000; //31.25us (x 64 = 0.002)
    }
    
    ISR(DMA_CH3_vect)
    {
        DMA.CH3.CTRLB |= 0x10; //clear Interrupt flag
        
        ReglerTimerCnt++;
        if(ReglerTimerCnt>=250)
        {
            ReglerTimerCnt = 0;
            SendPCUart("a",1);
        }
        
        TimeElapsed += 1;
        TimerFlag = 1;
    
        AdcValue= 0;
        for(uint8_t i=0;i<64;i++)
        {
            AdcValue+= AdcArray[i];
        }
    
    }
    Die SendPCUart-Routine schreibt ein "a" über die USART, das sollte eigentlich alle 0.002s * 250 (ReglerTimerCnt) = 0.5s erfolgen, kommt aber wesentlich öfter (wie oft genau kann ich nicht sagen, geschätzt wohl 500-5000 mal pro sekunde (ich weiß, ist keine wirkliche Angabe, aber es reicht, um sagen zu können, dass was falsch läuft).

    Vielen Dank & Gruß
    Chris

    EDIT:
    Hab jetzt den "Fehler" gefunden: Wenn der Interrupt des Timers nicht ausgeführt wird, triggert er andauernd den DMA, weil anscheinand das OVF-Bit nicht zurückgesetzt wird.
    Gibts eventuell eine Möglichkeit, das zu umgehen? Ansonsten bringt mir der DMA in diesem Fall garnichts, mir gehts ja darum, den Interrupt des Timers zu umgehen.

    EDIT2:
    Hab jetzt die Lösung (eine sehr gute sogar):
    Ich verwende das EventSystem als Trigger, dieses kann man mit einem Prescaler konfigurieren. Hab jetzt 1024 gewählt, damit stimmt das Timing zwar nicht 100%, aber die paar us sind nicht so schlimm. Außerdem hab ich jetzt wieder einen Timer frei.
    Geändert von Che Guevara (15.05.2014 um 16:04 Uhr)

Ähnliche Themen

  1. UTXC Interrupt hängt bzw. kommt nur einmal
    Von demmy im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 0
    Letzter Beitrag: 12.01.2014, 20:51
  2. DMA und ADC auf ATXMega64A3
    Von Che Guevara im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 21.05.2012, 18:03
  3. Platinenfräsen: Gravierstichel bricht oft ab
    Von Jacob2 im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 26
    Letzter Beitrag: 18.02.2011, 19:13
  4. Interrupt Transmit Complete UART
    Von pacer_one im Forum Assembler-Programmierung
    Antworten: 3
    Letzter Beitrag: 23.01.2008, 17:15
  5. Anfängerfrage? - Serieller Interrupt kommt nicht!!!
    Von Zentauro im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 01.10.2007, 11:36

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test