Forum: Mikrocontroller und Digitale Elektronik Reihenfolge der Befehle für den Timer 8051


von marten (Gast)


Lesenswert?

uC: AT89S8253
Sprache: C mit microC

Hallo.
Ich will bzw. muss den Timer0 als 16 Bit Counter verwenden und Pulse am 
externen Interrupt 0 zählen.
Ich frage mich hier schon allerdings wieso über den INT0 an dem Timer 
hängt. Eröffnet das spezielle möglichkeiten? Der Timer hat doch seber 
einen Pin...
Ich habe mal ein kleines Programm geschrieben in dem ich den Timer0 
initialisiere und starte. Bin mir aber überhaupt nicht sicher ob die 
Reihenfolge so stimmt oder ob sie schlecht gewählt ist.
Was passiert den wenn ich den INT0 noch für etwas anderes verwenden 
will? Muss ich dann priorisieren?
IE0 und IT0 hängen auch irgendwie zusammen, kann mir aber nicht genau 
erklären wie.
Vielleicht hat mir jemand einfache Programmierbeispiele (Basics) wie und 
für was man den Timer verwendet.

Hier die Aufgabe und mein Programm:

Assume a clock frequency of 12 MHz unless otherwise specified.
1. Detail all the Special Function Registers within the 8051 
microcontroller which are involved with controlling the timers. 
Detail all the values which must be loaded in the appropriate registers 
to enable the operation of Timer 0 as a 16 – bit counter, which counts 
clock pulses that are externally gated to the counter by INT0.

void Timer0_ISR() org 0x000B ilevel 0{

  EA_bit = 0;        // Clear global interrupt enable flag
  TR0_bit = 0;       // Stop Timer0

  TH0 = 0x00;        // Set Timer0 high byte
  TL0 = 0x00;        // Set Timer0 low byte

  TR0_bit = 1;       // Start Timer0
  EA_bit = 1;        // Set global interrupt enable flag
}


void main() {

  P0  = 0x00;           // Initialize PORT0
  P1  = 0x00;
  P2  = 0x00;

  ET0_bit = 1;       // Enable Timer0 interrupt -> IE Register (A8h)
  EA_bit  = 1;       // Set global interrupt enable -> IE Register (A8h)

  EX0_bit = 1;       // External interrupt 0 enable

  //TMOD = 0x09;
  GATE0_bit = 1;     // Set to enable timer/counter 0 only while the 
INT0# pin is high and the TR0 bit is set. -> TMOD Register (89h)
  C_T0_bit  = 0;     // Set for counter operation: timer 0 counts 
negative transitions on external pin T0. -> TMOD Register (89h)
                     // Clear for timer operation: timer 0 counts the 
divided-down system clock.
  M10_bit   = 0;     // M11_M01 = 01    =>   Mode 1(16-bit 
Timer/Counter) -> TMOD Register (89h)
  M00_bit   = 1;     // 
-> TMOD Register (89h)

  //TCON =0x00;
  TF0_bit = 0;       // Ensure that Timer0 interrupt flag is cleared -> 
TCON Register (88h)
  TR0_bit = 0;       // Turn off Timer0 -> TCON Register (88h)
  IE0_bit = 0;       // Cleared by hardware when interrupt is processed 
if edge-triggered (see IT0).
           // Set by hardware when external interrupt is detectedon 
INT0# pin.
  IT0_bit = 0;     // Clear to select low level active (level triggered) 
for external interrupt 0 (INT0#).
           // Set to select falling edge active (edge triggered) for 
external interrupt 0.


  TH0 = 0x00;        // Set Timer0 high byte
  TL0 = 0x00;        // Set Timer0 low byte


  TR0_bit = 1;       // Run Timer0

  while(1){
  ;
  }


}

von Ralf (Gast)


Lesenswert?

Hallo,

> Ich frage mich hier schon allerdings wieso über den INT0 an dem Timer
> hängt. Eröffnet das spezielle möglichkeiten? Der Timer hat doch seber
> einen Pin...
Du musst die jeweilige Betriebsart beachten: in der Timerbetriebsart 
inkrementiert der Timer in jedem Taktzyklus. Als Counter wird bei jedem 
Puls am Timer-Pin inkrementiert.
Über den INT-Pin kannst du bei gesetztem GATE-Bit das Inkrementieren 
steuern.

Wenn du also Pulse zählen willst, brauchst du die Counterbetriebsart, 
und über einen zweiten Timer definierst du die Messzeit, musst also den 
Ausgang vom zweiten Timer mit dem INT-Pin verbinden.
Alternativ deaktivierst du die GATE-Funktion und überlässt dem zweiten 
Timer-Interrupt die Steuerung des ersten Interrupts, d.h. der zweite 
Timer macht die Messzeit und bei jedem Interrupt wird der erste Timer 
ausgelesen und gelöscht.

> void Timer0_ISR() org 0x000B ilevel 0{...}
Was du da drin stehen hast ist murks - das ist der Interrupt, aber du 
machst da die Initialisierung.

Und die Konfiguration des externen Interrupts brauchst du m.E. gar 
nicht, der Timer nimmt sich einfach den INT-Pin.

Ralf

von Anon A. (anon1234)


Lesenswert?

Ich kenne den µC nicht, ich benutze meist den AT89S52.
Insgesamt wirds aber wohl ähnlich sein.

Ich hab gerade mal ein bisschen gesucht u bin hierauf gestoßen:
http://www.mikroe.com/products/view/267/architecture-and-programming-of-8051-mcu-s/

ist ein ganz nettes Tutorial mit dem AT89s8253.
In Chapter6 (http://www.mikroe.com/chapters/view/69/chapter-6-examples/) 
gibt es ein paar Beispiele unter anderem zu Timer und Interrupt 
Steuerung.

marten schrieb:
> Ich habe mal ein kleines Programm geschrieben in dem ich den Timer0
> initialisiere und starte. Bin mir aber überhaupt nicht sicher ob die
> Reihenfolge so stimmt oder ob sie schlecht gewählt ist.

Ich mutmaße jetzt einfach mal, so lange dein Timer nicht gestartet ist, 
müsste doch die Reihenfolge wie du die Register setzt egal sein oder?

von Ralf (Gast)


Lesenswert?

> die Steuerung des ersten Interrupts
Sorry, sollte "Timer" sein, nicht Interrupt

Ralf

von Peter D. (peda)


Lesenswert?

marten schrieb:
> Ich will bzw. muss den Timer0 als 16 Bit Counter verwenden und Pulse am
> externen Interrupt 0 zählen.

Dann mußt Du die Pulse an P3.4 einspeisen, das ist der T0 Eingang.

von marten (Gast)


Lesenswert?

Danke für die Antworten.

@Peter: Warum muss ich die Pulse an T0 einspeisen? Aufgabe ist es die 
Pulse am INT0 (Externer Interrupt) zu zählen. Das müsste doch auch gehen 
wenn man das GATE richtig einstellt, oder?

von Karl H. (kbuchegg)


Lesenswert?

marten schrieb:
> Danke für die Antworten.
>
> @Peter: Warum muss ich die Pulse an T0 einspeisen? Aufgabe ist es die
> Pulse am INT0 (Externer Interrupt) zu zählen.


Das kommt drauf an, wie man diesen Satz interpretiert
1
 which counts clock pulses that are externally gated to the counter by INT0.

"to gate" bedeutet auch 'versperren'.

D.h. das kann durchaus so gemeint sein, dass der Timer zählt und über 
den INT0-Eingang soll seine Gate Funktionalität angesprochen werden, mit 
der geregelt wird, ob er überhaupt zählen soll oder nicht.

Wenn ich eine Aufgabe ausgebe, dass der Timer Pulse an einem Pin zählen 
soll, würde ich nicht das englische "to gate" für diesen Vorgang 
benutzen, sondern ich würde in der Aufgabe verlangen, dass der Counter 
Pulse 'counten' (engl. to count) soll.

Im speziellen lese ich den Satz der Aufgabe so
1
which counts clock pulses
er zäählt also Pulse. Nämlich die ganz normalen clock Pulse. Nämlich die 
hier ...
1
Assume a clock frequency of 12 MHz

und diese clock Pulse werden nur dann gezählt, wenn das Gate durchlässig 
ist
1
 that are externally gated to the counter by INT0

: Bearbeitet durch User
von marten (Gast)


Lesenswert?

Aha, okay. Vielen Dank.
Hab grad nochmal ins Datenblatt gesehen. Der Clock ist 12Mhz, der 
Peripheral Clock ist 6Mhz und dieser wird nochmal durch 6 geteilt.
Heisst 12Mhz/12 ist 1Mhz. 1/1Mhz entspricht 1us pro state, richtig?

Mein INT0 (External Interrupt) wirkt dann wie eine Torschaltung?
Wie ist das dann? Läuft denn der Zähler immer bzw. wird das Zählregister 
dann immer hochgezählt wenn das Flag vom INT0 gesetzt ist oder wenn ich 
in der Routine bin, oder...
Sorry, dass verstehe ich noch nicht ganz

Grüsse

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.