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


von Hans Meier (Gast)


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

von Tobi (Gast)


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..

von Tobi (Gast)


Lesenswert?

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

von Hans Meier (Gast)


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).

von Tobi (Gast)


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

von Hans Meier (Gast)


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

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.