mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 8051: Timer im Capture Modus verwenden


Autor: Chris H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Verehrtes µC Forum,

ich verwende ein Mikrocontroller Board von SiLabs: den 8051F580
Damit und mit einer Reflexlichtschranke möchte ich die Drehzahl eines 
Motors messen. Das testen mit einem Oszi hat auch funktioniert und an 
Hand der Frequenz konnte ich die Drehzahl per Hand errechnen.

Für den weiteren Verlauf ist wichtig zu sagen, dass der Motor mit einem 
Bit-Muster beklebt wurde, um mit der Software die Drehzahl berechnen zu 
können (4 Flanken = 1 Umdrehung). Bei einer Frequenz von 500 Hz komme 
ich auf eine Drehzahl von 7500 1/min.

Den Timer 4 habe ich so konfiguriert (im Capture Modus), dass bei jeder 
High-to-Low Transition ein Interrupt ausgelöst wird. Bei jedem Interrupt 
wird in der ISR der Null-Wert und der Wert nach 4 Interrupts des Timers 
in jeweils eine Variable geschrieben. Mit der Differenz beider Variablen 
komme ich an die Zeit zwischen zwei Flanken und somit an die Drehzahl 
(Theoretisch).

Die Drehzahl soll später mit dem UART an einen seriellen Monitor 
gesendet werden. Zum testen hab ich zunächst geschaut ob die ISR 
überhaupt aufgerufen wird. Was aber nicht der Fall ist.

Hier ist der Programmabschnitt für die Initialisierung des Timers:
#include "compiler_defs.h"
#include <C8051F580.h>

int counterR_motor1 = 0;
int RPM1;

static unsigned int first_capture_motor1, second_capture_motor1;
int capture_periode_motor1;


void Timer4_Init (void){
 TMR4H = 0x00;  // 65,535 ms Timer Overflow (65535/(24 MHz/ 2 /12)
 TMR4L = 0x00;

 TMR4CN = 0x09;                   // T4EX enabled: Überwachung des Ports fuer die High-to-Low Transitionen
                                          // Timer4 is in Capture mode
 TMR4CF = 0x00;                    // Timer4 uses SYSCLK / 12
                                  // Increment only
 EIE2 = 0x40;                      // Enable Timer 4 interrupts
 TR4 = 1;                    // Timer 4 run enabled
}

Und Hier der Programmabschnitt der ISR:
INTERRUPT (TIMER4_ISR, INTERRUPT_TIMER4){
// Wenn eine High to Low Transition registriert wird
 if(EXF4 == 1){
  EXF4 = 0;// Timer 4 Interrupt für External Flag muss Software-Seitig reset gesetzt werden

  // Testweise ein '$' übertragen um zu schauen ob die ISR überhaupt getriggert wird                                  
  SBUF0 = '$';              
  while (TI0==0);
  TI0 = 0;
  while (THRE0==0);
  
  // Aufnahme des Nullpunktes
  if(counterR_motor1 == 0){
   first_capture_motor1 = TMR4CAPH <<8 | TMR4CAPL; // Capture Register in Variable schreiben
  }
    
  counterR_motor1 ++; // Counter starten wenn der Nullpunkt aufgenommen wurde

  // Wenn 4 Takte erreicht wurden, dann die Timer Zeit festhalten    
  if(counterR_motor1 == 4){
   second_capture_motor1 = TMR4CAPH <<8 | TMR4CAPL;
   capture_periode_motor1 = second_capture_motor1 - first_capture_motor1;
 
   // RPM1-Wert berechnen
   RPM1 = 60000000/(4 * capture_periode_motor1);  // RPM Motor1
      
   // Timer Reset und wieder auf null
   EIE2 = 0x40;
   TR4 = 0;
   TMR4H = 0x00;
   TMR4L = 0x00;
  }
 }
}

Ich schätze das Problem liegt an der Initialisierung des Timers. Die 
gezeigten Programmabschnitte sind nur ein Teil meines Codes. Wenn ich
Timer4_Init();
in meinem Programm auskommentiere, dann funktioniert der Rest des 
Programms ohne Probleme, sobald aber diese Funktion zugeschaltet wird, 
hängt es in der Initialisierung des Timers. Ob die Berechnung der 
Drehzahl welche in der ISR getätigt wird auch stimmt, kann ich im Moment 
noch nicht sagen, da ich zu diesem Punkt nicht komme.

Ich hoffe ich habe mich einigermaßen deutlich ausgedrückt, ansonsten bin 
ich natürlich offen für Anmerkungen/Fragen und entschuldige mich für 
eventuelle Unklarheiten =)

Danke und Grüße

Autor: Lothar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Chris H. schrieb:
> hängt es in der Initialisierung des Timers

Bist Du für das Beschreiben der TMR4 Register in der richtigen SFR Page? 
Ist der Watchdog aus? Ist der globale Interrupt enabled?

http://community.silabs.com/t5/8-bit-MCU/How-to-ma...

Ansonsten, da ich keinen 8051F580 da habe zum Testen, am besten hier 
fragen, da kommt recht schnell Antwort:

http://community.silabs.com/t5/8-bit-MCU/bd-p/1

Oder falls möglich TMR0 dafür verwenden, da muss deutlich weniger 
konfiguriert werden.

Autor: Chris H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar schrieb:
> Bist Du für das Beschreiben der TMR4 Register in der richtigen SFR Page?
> Ist der Watchdog aus? Ist der globale Interrupt enabled?
>http://community.silabs.com/t5/8-bit-MCU/How-to-ma...

- Das mit der SFR Page hatte ich hier vergessen einzufügen, in meinem 
Programm stehen sie aber wie folgt:
U8 SFRPAGE_save = SFRPAGE;          // Save Current SFR page
SFRPAGE = ACTIVE2_PAGE;             // Set SFR Page
// ...
SFRPAGE = SFRPAGE_save;             // Restore SFR Page
Die sind auch so in einem Bespiel mit dem TMR4 im Capture Modus 
beschrieben. Das habe ich so übernommen. Mit dem Configuration Wizard 2 
kann man sich das ganze ja auch ansehen und vergleichen. Den TMR4 habe 
ich von "Hand" geschrieben, weil ich nicht will, dass die gesamte 
Peripherie zum selben Zeitpunkt initialisiert wird.

- Globale Interrupts sind enabled

- Watchdog bei TMR4? Für die Generierung der PWM für die Motoren habe 
ich den PCA0 im Gebrauch und da ist der Watchdog aus, aber das hängt ja 
nicht zusammen, oder?

> Ansonsten, da ich keinen 8051F580 da habe zum Testen, am besten hier
> fragen, da kommt recht schnell Antwort:
> http://community.silabs.com/t5/8-bit-MCU/bd-p/1
  Danke werde ich machen

> Oder falls möglich TMR0 dafür verwenden, da muss deutlich weniger
> konfiguriert werden.
TMR0 habe ich schon für einen anderen Zweck verwendet. Könnte ich den 
hier trotzdem ebenfalls verwenden? Würde mir einiges vereinfachen.

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.