mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik P89LPC9351- Zählerstand des Timer 2 zurücksetzen


Autor: Djon Mayer (djon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe folgendes Problem bei der Programmierung des P89LPC9351 
(8051-Derivat) von NXP. Ich verwende die Capture/Compare-Unit (CCU). Der 
Timer 2 ist als freilaufender Timer (Basic Timer) konfiguriert und auf 
das Hochzählen eingestellt. Ich möchte, dass bei jedem Capture-Interrupt 
der aktuelle Zählstand des Timer 2 zurückgesetzt wird (0x00). Wenn ich 
das Programm im Simulator ausführe (µVision4 von Keil), dann wird der 
Zählstand brav zurückgesetzt, aber auf dem Mikrocontroller selbst ist es 
leider nicht der Fall und der Zähler läuft über.
In dem Datenblatt habe ich gelesen, dass man zuerst das Register TH2 und 
anschliessend TL2 setzen sollte, aber es hat auch nicht geholfen. Muss 
ich vielleicht bei der Rücksetzung noch was beachten?

Vielen Dank im Voraus!

Mfg Djon

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
code?


Gruß

Jobst

Autor: Djon Mayer (djon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Hier ist der Code. Ich hoffe, es wird bei der Lösungssuche helfen :-)

Mfg Djon
#include "reg9351.h"

static bit LED1 = 0;
static bit LED2 = 0;

#define SENSORA ((unsigned char)0)
#define SENSORB ((unsigned char)7)

main()
{
  // Die Led-Portpins auf Push/Pull Modus setzen
  P2M1 &= ~(0x30);
  P2M2 |= (0x30);

  // Die beiden Leds ausschalten
  P2 |= (1<<4);
  P2 |= (1<<5);

  // Der Timer2 muss so schnell zählen, dass er nach 500ms ueberlauft
  // Prescaler auf 0x3C setzen
  TPCR2L = 0x3C;

  // Den Timer als einen freilaufenden Timer deklarieren
  TMOD21 = 0;
  TMOD20 = 1;


  // Die Portpins P2.0 und P2.7 muessen als Eingaenge (Input Only) definiert werden
  P2M1 |= (1<<SENSORB);
  P2M2 &= ~(1<<SENSORB);

  P2M1 |= (1<<SENSORA);
  P2M2 &= ~(1<<SENSORA);

  //! NoDelay
  CCCRA &= (0x1F);
  CCCRB &= (0x1F);

  // Der Eingang soll auf steigende Flanke getriggert werden
  CCCRA |= (1<<4);
  CCCRB |= (1<<4);

  //! Noise Filter
  CCCRA |= (1<<3);
  CCCRB |= (1<<3);

  // Timer Input Capture A Enable bit setzen
  TICR2 |= (1<<0);

  // Timer Input Capture B Enable bit setzen
  TICR2 |= (1<<1);

  // Das Interrupt freigeben
  ECCU = 1;

  // Die Zaehlrichtung des Timers setzen
  // TDIR2 = 0: Count up
  // TDIR2 = 1: Count down
  TDIR2 = 0;

  // Der Watchdog-Zähler wird auf 1 Sek. gesetzt
  WDL = 0x62;

  // Interrupts global freigeben
  EA = 1;


  // Hauptschleife
  while(1)
  {
    //! Überprüfen, ob der Timer2 übergelaufen ist
    if((TIFR2 & 0x80) == 0x80)
    {
      //! Timer2-Überlaufflag löschen
      TIFR2 &= ~(0x80);

      //! LED1 toggeln
      SS = LED1;
      LED1 = !(LED1);
    }
  }
}


void wheelSensorInterrupt() interrupt 11
{
  // Interrupts sperren
  EA = 0;

  // Ueberpruefen, welcher Sensor aktiviert wurde
  if ((TIFR2 & 0x01) == 0x01)
  {
    //! LED2 toggeln
    SPICLK = LED2;
    LED2 = !(LED2);

    // Interruptflag clearen
    TIFR2 &= ~(0x01);
  }
  else if ((TIFR2 & 0x02) == 0x02)
  {
    // Interruptflag clearen
    TIFR2 &= ~(0x02);
  }

  //! Zählerstand zurücksetzen
  TH2 = 0x00;
  TL2 = 0x00;

  // Erster Schritt der Sequenz
  WFEED1 = 0xA5;

  // Zweiter Schritt der Sequenz
  WFEED2 = 0x5A;

  // Interrupts freigeben
  EA = 1;
}

Autor: R. W. (quakeman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bist du sicher, dass auch immer innerhalb von 1 Sekunde ein CCU 
Interrupt erzeugt wird?
Andernfalls läuft dein Watchdog ja über und versaut dir deinen gesamten 
Ablauf. Ich würde an deiner Stelle erst mal simpel anfangen und alles 
Überflüssige rauswerfen. Dazu gehört vor allem, den Watchdog zu 
deaktivieren bis alles läuft.

Und nachdem du scheinbar kein SPI benutzt, solltest du der 
Verständlichkeit halber lieber nicht die Bezeichnungen SS und SPICLK für 
die Pins benutzen.
Ebenfalls ist es zu empfehlen den Timer2 vor dem zurücksetzen zu stoppen 
und danach wieder zu starten. Denn ohne das kannst du im Worst Case ein 
Problem bekommen. Wenn du z.B. TH2 = 0 setzt und dabei TL2 = 0xFF war 
und du in der nächsten Zeile dann TL2 = 0 setzt, ist aber eventuell 
dazwischen schon ein Überlauf auf TH2 = 1 passiert.

Du kannst deine Konstanten auch direkt mit
#define SENSORA 0
#define SENSORB 7
definieren, da das (unsigned char) keine Auswirkung hat. Der Compiler 
benutzt automatisch die richtigen Typen je nach Verwendung.

Ciao,
     Rainer

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fox Mulder schrieb:
> Ebenfalls ist es zu empfehlen den Timer2 vor dem zurücksetzen zu stoppen
> und danach wieder zu starten. Denn ohne das kannst du im Worst Case ein
> Problem bekommen. Wenn du z.B. TH2 = 0 setzt und dabei TL2 = 0xFF war
> und du in der nächsten Zeile dann TL2 = 0 setzt, ist aber eventuell
> dazwischen schon ein Überlauf auf TH2 = 1 passiert.

Nein, das ist nicht nötig, aber zuerst sollte TL2 auf 0 gesetzt werden. 
Dann erst TH2. In der Zwischenzeit kommt TL2 nämlich nicht weit genug.


Gruß

Jobst

Autor: R. W. (quakeman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jobst M. schrieb:
> Nein, das ist nicht nötig, aber zuerst sollte TL2 auf 0 gesetzt werden.
> Dann erst TH2. In der Zwischenzeit kommt TL2 nämlich nicht weit genug.

Es ist aber auch dann nur nicht nötig, wenn man deine Reihenfolge 
einhält. Bei der von ihm benutzen Reihenfolge macht es schon Sinn. ;)

Ciao,
     Rainer

Autor: Djon Mayer (djon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich bin mir ziemlich sicher, dass innerhalb einer Sekunde mehrere 
CCU-Interrupts erzeugt werden. Die beiden Eingänge hängen an einem 
Funktionsgenerator und so kann ich nach Belieben CCU-Interrupts 
erzeugen.
Ich habe die Variante mit dem Anhalten des Timers bereits ausprobiert, 
doch leider ohne Erfolg.
Ich habe jetzt die Sache mit Hilfe des Timer 1 gelöst. Dieser Timer 
lässt sich problemlos zurücksetzen.

Mfg Djon

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.