www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik XMega Compare Timer


Autor: Mathiable (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag

Ich arbeite gerade mit einem ATMEGA64A1 und möchte eine Interrupt 
gesteuerte zeit Verzögerung die durch einen Schalter ausgelöst wird. 
Funktioniert auch mehr oder weniger... zumindest als Zufallsgenerator. 
Die Zeitverzögerung ist nämlich nur etwa jedes 2. Mal korrekt. Die 
Zeitverzögerung sollte einer Periode vom Timer0 entsprechen. Ich habe 
mir das so überlegt:
ISR (PORTJ_INT0_vect)
{  
  if(PORTJ.IN & (1<<6))  //Zustand des Schalters abfragen
  {
    unsigned short x;        //buffer

    if(TCC0.CNT==0) x=0x7A10;  //den Buffer auf den aktuellen Zählerstand minus eins stellen
    else
    {
      x=TCC0.CNT;
      x--;
    }

    TC_SetCompareC( &TCC0, x );   //Eine Periode von Timer0 einstellen

    TCC0.INTFLAGS|=0x40;    //Interrupt Flag löschen

    TC0_EnableCCChannels( &TCC0, TC0_CCCEN_bm );    //Komparator C von Timer 0 aktivieren
  
    TC0_SetCCCIntLevel( &TCC0, TC_CCCINTLVL_LO_gc );  //Interrupt für den Komparator C erlauben
  
  }
  else PORTK.OUT|=0x01;   //bei ausgeschaltetem Schalter, Output setzen
}


ISR (TCC0_CCC_vect)
{
  PORTK.OUT&=0xFE;

  TC0_DisableCCChannels( &TCC0, TC0_CCCEN_bm );  //Komparator C von Timer 0 desaktivieren
  TC0_SetCCCIntLevel( &TCC0, TC_CCCINTLVL_OFF_gc ); //Interrupt für den Komparator C verbieten
}



Die Interrupts scheinen zu funktionieren, PK1 wird schön ein und 
ausgeschaltet, nur ist eben die Zeit nicht immer gleich einer Periode 
vom Timer0. Ich weiss nicht ob ich einen Logik Fehler darin habe oder 
etwas Wichtiges vergessen habe, ich hoffe ihr habt bessere Augen dafür 
als ich.

Vielen dank schon im voraus.

Autor: GG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Mathiable schrieb:


> ISR (PORTJ_INT0_vect)


Wie hast du deinen Port0 programmiert?

Man muss  den Port konfigurieren, dass er auf  gewisse Ereignisse 
reagiert!

z.B. eine Taster (steigende oder  fallende Flanke

PORTJ.DIR=0x00;
PORTJ.PIN0CTRL=PORT_OPC_PULLUP_gc | PORT_ISC_FALLING_gc;
oder

PORTJ.DIR=0x00;
PORTJ.PIN0CTRL=PORT_OPC_PULLDOWN_gc | PORT_ISC_RISING_gc;

Auszug aus CodeWizardAVR V2.04.8 Evaluation

Das sollte bei einem Schalter (dauernd ein oder aus) auch berücksichtigt 
werden.

Warum frägst du hier: ISR (PORTJ_INT0_vect) nochmals den Schalter ab,
wenn ganz klar der Schalter den Interrupt bereits ausgelöst hat?

Bei einen auglösten Interrupt kann das:

else PORTK.OUT|=0x01;   //bei ausgeschaltetem Schalter, Output setzen

nicht eintreten.

Gruß GG

Autor: Mathiable (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
GG schrieb:
> Man muss  den Port konfigurieren, dass er auf  gewisse Ereignisse
> reagiert!
>
> z.B. eine Taster (steigende oder  fallende Flanke)

Der Interrupt reagiert auf beide Flanken, deshalb die Abfrage. Wenn der 
Schalter eingeschaltet wird, soll es eine Zeitverzögerung geben, wenn 
der Schalter abgeschaltet wird soll es sofort abschalten. Die Schalter 
Abfrage und die Interrupts funktionieren auch, die Konfiguration sollte 
also stimmen.

Trotzdem hier noch die Initialisierung des Timers und der IO:
  PORTJ.DIRSET=0x38;
  PORTK.DIRSET=0xFF;


// -=Timer Initialisieren=- //
  TC_SetPeriod( &TCC0, 0x7A10 );               //Interrupt Periode definieren, annäherungsweise 1s
  
  TC0_SetOverflowIntLevel( &TCC0, TC_OVFINTLVL_LO_gc );  //Overflow Interrupt auf Low Level erlauben

  PMIC.CTRL |= PMIC_LOLVLEN_bm;   //low level Interrupt erlauben

  PORTJ.INTCTRL = 0x01;     //Interrupt Level an PORTJ festlegen
  PORTJ.INT0MASK = 0x40;    //Interrupt an PORTJ PIN6 freigeben
  PORTJ.PIN0CTRL = 0x00;    //Interrupt auf beide Flanke einstellen
  sei();                    //Interrupt einschalten

TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV1024_gc );    //Prescaler sowie Clock wählen und Timer starten

Kann man den einstieg in die Timer0 Periode überhaupt so machen wie ich 
es wollte (TCC0.CNT - 1) oder gibt es da eine „normalere“ Variante?

Autor: Mathiable (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir keiner helfen?

Autor: ala42 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn der Schalter prellt, wird sich die Logik sicherlich anders 
verhalten als Du das erwartest.

Autor: Mathiable (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ala42 schrieb:
> Wenn der Schalter prellt, wird sich die Logik sicherlich anders
> verhalten als Du das erwartest.

Danke für die Antwort.
Dann müsste der interrupt aber von vorne beginnen und die 
Zeitverzögerung würde sich in die länge ziehen, es wird aber kürzer. Im 
Oszilloskop lässt sich auch kein signifikantes Prellen beobachten, 
handelt sich um max. 200mV während ca. 1us. Aber auch eine delay von 
10us hat nichts verändert.
Sollte es so funktionieren oder wieso antworten so wenige?

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.