Problem: AT90S2313 und der TimerCapture Pin (ICP - Interrupt)

OP (Firma: MicroForge) #1030455
Lesenswert?
• ▲
▼
Hallo,

ich versuche einen digitalen Drehzahlmesser zu programmieren.
Leider komme ich mit dem 16-Bit TimerCounter1 des AT90S2313 nicht klar.

Ich wollte gerne, dass der Timer bei 0 startet. Ich möchte Signale 
zwischen 50Hz und 400Hz messen können, daher habe ich bei 10Mhz einen 
Prescaler von 1024 gewählt. Wenn an ICP eine positive Flanke auftritt 
möchte ich einen Interrupt auslösen. Der Interrupt wird ausgelöst, 
allerdings steht dann nichts im Zähler drin! Ein OverFlow tritt 
entsprechend auch nie auf, was mich extrem verwirrt.

Ich habe meinen Code im Anhang. Meiner Meinung nach habe ich alle 
Register richtig gesetzt. Die Interruptroutine steht unten in main.c.

Wenn an PD6 (ICP) eine positive Flanke auftritt soll er in den IRQ 
hüpfen und über eine kleine Funktion ein 14-Bit Wort an die Ausgänge 
legen. Alle Funktionen funktionieren, bis auf dieser Counter. Der wird 
scheinbar nicht hochgezählt.

Habe ich irgendwas übersehen? Ich wäre euch wirklich dankbar, wenn 
jemand einen Fehler findet.... :(

Gruß
Timo
Angehängte Dateien:
OP (Firma: MicroForge) #1030469
Lesenswert?
• ▲
▼
Sorry... offenbar stand ich ganz ganz kurz vor der Selbsterkenntnis.

Im Code initialisiere ich den Counter wie folgt:
1
  TIMSK = (1<<TICIE1) | (1<<TOIE1);
2
  //TIFR = (1 << ICF1);
3
  TCNT1 = 0;
4
  //TCCR1A = 0x00;
5
  TCCR1B = (1 << ICNC1) | (1 << ICES1) | (1 << CTC1) | (1 << CS12);
6
  sei();

um dann mit folgendem Interrupt zu arbeiten:
1
ISR(TIMER1_CAPT1_vect){
2

3
  //unsigned int counterValue = 0;
4
  //counterValue = ICR1;
5
  short tableEntry = calc_RpmToArray(ICR1);
6
  ICR1 = 0;
7
  TCNT1 = 0;
8

9
  PORTB = ~(drehzahl[tableEntry] & 0xFF);
10
  PORTD = ~((drehzahl[tableEntry] >> 8) & 0xFF);
11

12
  //PORTB = ~((counterValue) & 0xFF);
13
  //PORTD = ~(((counterValue) >> 8) & 0xFF);
14

15
  //PORTB = 0x00;
16
  //PORTD = ~PORTD;
17
}

Das klappt nicht, weil ich den Counterstand durch setzen des CTC1 Flags 
automatisch löschen lasse!
1
TCCR1B = (1 << ICNC1) | (1 << ICES1) | (1 << CTC1) | (1 << CS12);

Ich dachte, dass das klug wäre, da ich ja den Counter neustarten möchte, 
wenn ich mit dem Auslesen des ICR1 Registers fertig bin. Es scheint aber 
so zu sein, dass das ICR1 Register geschrieben wird, nachdem der 
Counter zurückgesetzt wurde. Das ist natürlich Schwachsinn.

Aber
1
TCCR1B = (1 << ICNC1) | (1 << ICES1) | (1 << CS12);

so läuft es jetzt. Ich setze in der Interruptroutine den Counter selbst 
zurück.

Gruß
Timo

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.