Timer1 beim ATmega8 auch rückwärts?

Gast #1278494
Hallo Leute,
ich muss für ein Wegmesssystem einen Inkrementgeber auswerten, d.h. die 
Schritte Zählen und die Bewegungsrichtung feststellen und den aktuellen 
Messwert auf einem LCD anzeigen. Ich hatte die beiden Signale als 
externe Interrupts angebunden, in der entsprechenden Interruptroutine 
die Richtung ermittelt, eine Variable hoch- bzw. runtergezählt und dann 
den aktuellen Wert zum LCD gesendet. Prinzipiell funktioniert das Ganze, 
aber während des sendens zum LCD gehen Inkremente verloren. Jetzt hab 
ich mir überlegt das Zählen der Inkremente dem Timer1 zu überlassen weil 
der unabhängig vom Programm läuft. das funktioniert auch, aber bei 
Rückwärtsbewegung des Messsystems mus er auch rückwärts zählen.
Jetzt meine Frage: kennt jemand eine Möglichkeit wie ich den Timer1 
rückwärts zählen lassen kann (im PWM- Bertieb macht er das doch auch)?

Ich hab jedenfalls im Datenblatt nichts gefunden und wäre dankbar für 
einen Hinweis.

Grüße: Hermi
#1278520
Hermi schrieb:

> Messwert auf einem LCD anzeigen. Ich hatte die beiden Signale als
> externe Interrupts angebunden, in der entsprechenden Interruptroutine
> die Richtung ermittelt, eine Variable hoch- bzw. runtergezählt und dann
> den aktuellen Wert zum LCD gesendet.

Lass mich raten: du machst die Ausgabe aufs LCD auch innerhalb der ISR?

> Prinzipiell funktioniert das Ganze,
> aber während des sendens zum LCD gehen Inkremente verloren.

Das wundert mich nicht.
Verlagere die Ausgabe in die Hauptschleife und alles wird gut.
Alte Regel: In einer ISR nur das allernotwendigste machen. Alles was 
nicht zeitkritisch ist oder nicht unbedingt in der ISR gemacht werden 
muss, fliegt dort raus.

> Jetzt meine Frage: kennt jemand eine Möglichkeit wie ich den Timer1
> rückwärts zählen lassen kann (im PWM- Bertieb macht er das doch auch)?

Du zäumst das Pferd am falschen Ende auf.
Mach deine SW-Architektur richtig und alles wird gut.

1
...
2

3
volatile uint16_t counter;
4
volatile uint8_t updateLCD;
5

6
ISR( .... )
7
{
8
  // frage die notwendigen Eingänge ab
9
  // einfache und kurze Berechnungen können auch noch gemacht
10
  // werden, wenn die Zeit reicht
11
  counter++;
12

13

14
  // und teile der Hauptschleife mit, dass neue Werte aufs LCD müssen
15
  updateLCD = TRUE;
16
}
17

18
...
19

20
int main()
21
{
22
  ....
23

24
  while( 1 ) {
25
    ...
26

27
    if( updateLCD ) {
28
      updateLCD = FALSE;
29

30
      // mach die Ausgabe aufs LCD, beim Zugriff auf die globalen
31
      // Variablen auf atomaren Zugriff achten! Nicht dass die ISR
32
      // während der Ausgabe die globalen Variablen zwischendurch
33
      // verändert
34

35
      cli();
36
      tmp = counter;
37
      sei();
38

39
      itoa( buffer, tmp, 10 );
40
      lcd_string( buffer );
41
    }
42
  }
43
}
Gast #1278523
Übermittelst du die Daten in der Interruptroutine an das LCD? Wenn ja, 
dann ist das normal, dass Schritte verloren gehen.
Wenn nein, stimmt irgendwas nicht, da das Display-Update durch das 
Zählen kurz unterbrochen werden müsste...
Gast #1278847
Hallo Leute,
vielen dank für Eure ersten Tipps. Ich habe jetzt das Ganze so 
abgeändert, dass ich in der jeweiligen Interruptroutine die Variable mit 
dem Messwert hoch oder runterzähle, die Erkennung der Bewegungsrichtung 
im Hauptprogramm realisiere und das LCD nur etwa viermal pro Sekunde in 
einer Interruptroutine von timer1 aktualisiere. Jetzt läuft es 
jedenfalls erstmal stabil, aber ich denke Währenfd des sendens an das 
LCD können doch noch Inkremente verlorengehen- weil doch in dieser Zeit 
die Interrupts ausgeschaltet sind.
#1279006
Hermi schrieb:

> jedenfalls erstmal stabil, aber ich denke Währenfd des sendens an das
> LCD können doch noch Inkremente verlorengehen- weil doch in dieser Zeit
> die Interrupts ausgeschaltet sind.

Wenn du es so gemacht hast, wie ich es dir weiter oben gezeigt habe, 
dann müssen die Interrupts aber schon sehr schnell kommen. Konkret kann 
nur in der kurzen Zeitspanne hier
1
      cli();
2
      tmp = counter;
3
      sei();

ein Interrupt verloren gehen. Nur hier sind die Interrupts gesperrt. Und 
das auch nur, wenn 2 so knapp hintereinander kommen, dass sich das mit 
dem Timing nicht mehr anders ausgeht.

Nachdem du dir die aktuellen Werte geholt hast, hast du alle Zeit der 
Welt die Anzeige auf den neuesten Stand zu bringen. Und es gibt auch 
keinen Grund während der Aufbereitung bzw. des Sendens an das LCD die 
Interrupts zu sperren :-) Wenn das LCD ein paar µs später die neuen 
Werte anzeigt, so spielt das keine Rolle. So schnell kann ein Mensch 
sowieso nicht schaun.
#1279206
@  Hermi (Gast)


>Messwert auf einem LCD anzeigen. Ich hatte die beiden Signale als
>externe Interrupts angebunden, in der entsprechenden Interruptroutine
>die Richtung ermittelt, eine Variable hoch- bzw. runtergezählt und dann

Möööööp!!!

1.) Fehler: Drehgeber werden durch Abtastung per Timerinterrupt 
ausgewertet. Siehe Artikel.

>aber während des sendens zum LCD gehen Inkremente verloren. Jetzt hab

2.) Fehler. Interrupt-Routinen müssen kurz sein, längere Aufgaben 
werden, nein MÜSSEN, in der Hauptschleife ausgeführt werden, siehe 
Artikel.

>Rückwärtsbewegung des Messsystems mus er auch rückwärts zählen.

Macht eine richtige(tm) Auswertung problemlos.

>Jetzt meine Frage: kennt jemand eine Möglichkeit wie ich den Timer1
>rückwärts zählen lassen kann (im PWM- Bertieb macht er das doch auch)?

Käse.

MfG
Falk

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.