mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik "Division" der Timerregister (high + low) zur Auswertung


Autor: Hans Meier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

in meinem Programm "muss" ich eine bestimmte Zeit in kleine,
gleichgroße  "Zeitscheiben" zerlegen. Die Gesamtzeit (= zu zerlegende
Zeitspanne) messe ich mit einem 16-Bit Timer durch starten/stoppen und
auslesen von TCNT1L und anschließend TCNT1H. Das klappt auch alles
soweit.
Aber dann fangen die Probleme auch schon an: wie bekomme ich die beiden
8-bit Werte in einen 16-Bit Wert und wie wandle ich diesen in eine
Dezimalzahl (zum Weiterrechnen) um? Und wie teile ich diese Zeit
(meinetwegen 50 Stücke) in gleichgroße Teile auf, so dass ich sie z.B.
in einer for Schleife (s.u.) abfragen kann?

void pause (void)
{
  long schleife;
  for (schleife = 0; schleife < timerwert; schleife++)
  {
    __no_operation ();
  }
}

Habt ihr da Tipps (bestenfalls Codebeispiele in C zum zusammenfügen
zweier 8-Bit Werte mit Umwandlung in Dezimal) für mich?

Gruß,

Hans

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich versteh zwar nicht alles so ganz aber zwi 8bit werte zusammenfügen
ist kein problem:

uint16_t ui16;
uint8_t ui8h, ui8l;

ui16 = (ui8h << 8) || ui8l;

was meinst du in dezimal umwandeln? dezimal ist nur eine
darstellungsweise für eine zahl, beim rechnen ist sowieso alles binär,
nicht dezimal, hex oder sonstwas. da musst du so weit ich das
verstanden hab nix umwandeln.

das problem mit dem zeit aufteilen versteh ich leider nicht so ganz..

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mein fehler, muss heissen
ui16 = (ui8h << 8) | ui8l;
                  ^^^

Autor: Hans Meier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Tobi,

danke für den Wink mit dem Zaunpfahl, ist einfach zu spät ;=)
In dem Programm ist einfach der Wurm drin, merke jetzt, dass meine
ausgelesenen TCNT1H und TCNT1L gar nicht hinhauen (können).
Erst mal eine Runde schlafen,

Danke für die schnelle Hilfe,

Hans

P.S. Noch ein Wort zur Anwendung: Ich messe mit dem Timer eine
Zeitspanne. An mehreren Ausgängen habe ich LEDs. Nun soll nach
Gesamt-Zeitspanne/Anzahl der LEDs jeweils eine weitere LED angehen.
Wenn ich z.B. 1sec messe und 10 LEDs habe, soll alle 100msec eine
weitere LED angehen (nur als Beispiel).

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dann solltest du nicht die gesamtzeitspanne mit dem timer messen sondern
immer nur die bis zum nächsten ereignis (led anschalten). wenns variabel
sein soll kannst du ja den wert bis zum nächsten timer interrupt immer
neu berechnen und in der isr setzten

Autor: Hans Meier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Tobi,

solange noch konzentriert wach und mit hilfreichen Tipps zur Stelle?
Respekt.
Erst noch mal was zur Funktion: eine Strecke von 100m wird in X
Sekunden von einem RC-Auto abgefahren (dies ist die Gesamtzeitspanne
die gemessen wird). Nun steht alle 10m eine Leuchte (LED), die nach
X/10 Sekunden angemacht wird. So kann man sich an seiner letzten Zeit
orientieren und sieht schon vor Rundenende, ob man "hinter" den LEDs
liegt, oder ob man "riskanter" fahren sollte ;=)

Aber ich bekomme immer nur "Müll" in mein Timerregister. Anbei dafür
mal der Code:

static U16 timerwert

void interrupt_schalter (void)
{
   U8 highbyte;
   U8 lowbyte;
   // Interrupts deaktivieren
   interrupt_aus ();
   // Timer anhalten
   timer1_stop ();
   // zuerst das LOw-Byte, dann das High-Byte auslesen
   lowbyte = ICR1L;
   highbyte = ICR1H;
   // Zeit "zusammenfügen"
   timerwert = (highbyte << 8) | lowbyte;
   // es gibt 52 Leuchten/LEDs, also Gesamtzeit durch 52 teilen
   timerwert = timerwert / 52;
   // Timer 1 "nullen" und erneut loslaufen lassen
   timer1_start ();
   // Variable die die LEDs steuert
   go = 1;
   // Interrupts wieder aktivieren
   interrupt_an ();
}

void main (void)
{
   // Register des uCs initialiseren
   MCUCR = 0x00;
   GIMSK = 0x00;
   // Register der Ausgänge initialiseren
   PORTB = 0x7F;
   DDRB = 0x7F;
   PORTD = 0x40;
   DDRD = 0x00;
   // Register der Timer initialiseren
   TCCR0 = 0x01;
   TCCR1A = 0x00;
   TCCR1B = 0x85;
   OCR1 = 0x0000;
   TIMSK = 0x08;
   [...]
   while (1)
   {
      while (go == 1)
      {
         PORTB = 0x01;
         pause ();
         PORTB = 0x02;
         [...]
         go = 0;
      }
   }
}

Warum steht in den Timerregistern nichts vernünftiges?

Gruß,

Hans

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.