Forum: Mikrocontroller und Digitale Elektronik XMega Compare Timer


von Mathiable (Gast)


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:
1
ISR (PORTJ_INT0_vect)
2
{  
3
  if(PORTJ.IN & (1<<6))  //Zustand des Schalters abfragen
4
  {
5
    unsigned short x;        //buffer
6
7
    if(TCC0.CNT==0) x=0x7A10;  //den Buffer auf den aktuellen Zählerstand minus eins stellen
8
    else
9
    {
10
      x=TCC0.CNT;
11
      x--;
12
    }
13
14
    TC_SetCompareC( &TCC0, x );   //Eine Periode von Timer0 einstellen
15
16
    TCC0.INTFLAGS|=0x40;    //Interrupt Flag löschen
17
18
    TC0_EnableCCChannels( &TCC0, TC0_CCCEN_bm );    //Komparator C von Timer 0 aktivieren
19
  
20
    TC0_SetCCCIntLevel( &TCC0, TC_CCCINTLVL_LO_gc );  //Interrupt für den Komparator C erlauben
21
  
22
  }
23
  else PORTK.OUT|=0x01;   //bei ausgeschaltetem Schalter, Output setzen
24
}
25
26
27
ISR (TCC0_CCC_vect)
28
{
29
  PORTK.OUT&=0xFE;
30
31
  TC0_DisableCCChannels( &TCC0, TC0_CCCEN_bm );  //Komparator C von Timer 0 desaktivieren
32
  TC0_SetCCCIntLevel( &TCC0, TC_CCCINTLVL_OFF_gc ); //Interrupt für den Komparator C verbieten
33
}


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.

von GG (Gast)


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

von Mathiable (Gast)


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:
1
  PORTJ.DIRSET=0x38;
2
  PORTK.DIRSET=0xFF;
3
4
5
// -=Timer Initialisieren=- //
6
  TC_SetPeriod( &TCC0, 0x7A10 );               //Interrupt Periode definieren, annäherungsweise 1s
7
  
8
  TC0_SetOverflowIntLevel( &TCC0, TC_OVFINTLVL_LO_gc );  //Overflow Interrupt auf Low Level erlauben
9
10
  PMIC.CTRL |= PMIC_LOLVLEN_bm;   //low level Interrupt erlauben
11
12
  PORTJ.INTCTRL = 0x01;     //Interrupt Level an PORTJ festlegen
13
  PORTJ.INT0MASK = 0x40;    //Interrupt an PORTJ PIN6 freigeben
14
  PORTJ.PIN0CTRL = 0x00;    //Interrupt auf beide Flanke einstellen
15
  sei();                    //Interrupt einschalten
16
17
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?

von Mathiable (Gast)


Lesenswert?

Kann mir keiner helfen?

von ala42 (Gast)


Lesenswert?

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

von Mathiable (Gast)


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?

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.