Forum: Mikrocontroller und Digitale Elektronik 89c51rd2 Timer IRQ


von Joed ". (Firma: GSE) (joed_z)


Lesenswert?

Hallo Leute,

ich bin neuling im 89c51(rd2), ich versuche gerade timer0_irq auf 200us 
einzustellen, leider bekomme ich das nicht hin. 10 ms hingegen in 
timer2_irq läuft. meiner initialisierungsroutine sieht so aus:

void  timer_init(void)
{
//Timer 0 und Timer 1
  TMOD  = 0x22;
  TR0   = 0;
  TH0   = TIMER0;
  TL0  = TIMER0;
  TR0  = 1;

//Timer 2  10 msek IRQ

  CP_RL2=  0;
  C_T2  =  0;
  TR2  =  1;      //bit 2
   TF2  =  0;      //bit 3
  TCLK  =  0;      //bit 4
  RCLK  =  0;      //bit 5
  EXF2  =  0;      //bit 6
  TF2  =  0;      //bit 7
   T2    = 0xffff-(MSEK*KHZ/12/10)+1;
  RCAP2  =  0xffff-(MSEK*KHZ/12/10)+1;
}
die Irq_initialisierungsroutine:
void  irq_init(void)
{
//++++++++++++++++++++++++++++++++++++++++++++++
//externe irqs
  EX0  =  1;    //irq0 freigegeben
  EX1  =  0;    //irq1 gesperrt
   IT0  =  1;    //irq0 bei fallender Flanke
        IT1  =  1;    //irq1 bei fallender Flanke

//+++ Timerirq +++++++++++++++++++++++++++++++++++++++++++
  ET0  =  1;     //Timer 0 IRQ einschalten
  ET1  =  0;     //Timer 1 IRQ ausschalten
  ET2  =  1;     //Timer 2 IRQ einschalten

//+++ Serieller IRQ0 ++++++++++++++++++++++++++++++++++++++
  ES  =  0;
}
danke.

von Peter D. (peda)


Lesenswert?

Joed "Z" schrieb:
> leider bekomme ich das nicht hin.

Das ist natürlich ne super aussagekräftige Fehlerbeschreibung, mit der 
wirklich jeder was anfangen kann.

Findest Du nicht?

Zeig wenigstens einen compilierbaren Code (als Anhang!), der nur diesen 
Interrupt freigibt. Also natürlich mit Main und Handler.


Peter

von Joed ". (Firma: GSE) (joed_z)


Lesenswert?

ja wenn ich einen Fehler "merken" würde wäre ich ja schon weier.
Ich habe in der Main nur eine while(1) schleife zum testen.
Im HITOP debugger break ich mich auf dem 10ms interrupt und da komme ich 
jedes mal hin, im 200 us aber nicht. zugelassen sind sie beide. ich 
denke es liegt oder kann an der Initialisierung liegen. deswegen 
"bekomme ich das nicht hin"...

von Bernd B. (Firma: BB) (berndb)


Lesenswert?

Hallo Joed "Z"

Du initialisierst TL0 und TH0 mit TIMER0. Ist das so gewollt ? 
Eigentlich müsstest Du die unteren 8Bit in TL0 und die oberen in TH0 
schreiben. Aber nur wenn TIMER0 16Bit hat.
Außerdem fehlt die Timer0 Interrupt Routine, da der Timer 0 nicht 
automatisch nachgeladen wird. Der fängt beim Überlauf wieder bei 0 an.

Gruß BerndB

von Peter D. (peda)


Lesenswert?

Wie schon gesagt, Du mußt das Problem einkreisen.
Also alles unnütze raus und was compilierfähiges rein.
Deine bisherigen Schnipsel sind unbrauchbar.


Peter Dannegger schrieb:
> Zeig wenigstens einen compilierbaren Code (als Anhang!), der nur diesen
> Interrupt freigibt. Also natürlich mit Main und Handler.


Peter

von Joed ". (Firma: GSE) (joed_z)


Lesenswert?

ich bin im Modus 1 also 16 bit. mir ist auch bewussst das die high TH0 
und Low in TL0 hingehören. ist aber gewollt. TIMER0 steht auf 10.

void timer0_irq (void) interrupt 1
{
// alle 200 us muss noch eingestellt werden
  dreh();
}

die routine ist da, ich habe dort einen dreher eingebaut um auf dem 
Oszilloskop die zeit zu beobachten...

von Bernd B. (Firma: BB) (berndb)


Lesenswert?

Hallo Joed "Z"

Das heißt der Zähler läuft bei 0x1010 los. Wenn er 0xFFFF erreicht hat 
startet er von 0x0000. Damit er wieder von 0x1010 los läuft musst in der 
Interrupt Routine den Wert neu laden.

Gruß BerndB

von Joed ". (Firma: GSE) (joed_z)


Lesenswert?

ja verständlich, aber mein problem liegt bestimmt woanders, denn ich 
komme gar nicht rein ins IRQ. deswegen habe ich vermutet dass etwas mit 
der Initialisierung vergessen wurde.

von Bernd B. (Firma: BB) (berndb)


Lesenswert?

Hallo,

hast Du EA auch auf 1 gesetzt ? Sonst sind alle Interrupts gesperrt

Gruß BerndB

von Joed ". (Firma: GSE) (joed_z)


Lesenswert?

Danke Bernd aber soweit war ich schon ;)

von Bernd B. (Firma: BB) (berndb)


Lesenswert?

Hallo,

Sorry, aber das steht alles weder in deiner Fehlerbeschreibung noch in 
deinem Code.
Da kann man wirklich schlecht helfen.

Schöne Grüße aus Japan,
BerndB

von Joed ". (Firma: GSE) (joed_z)


Lesenswert?

:) trotzdem Danke.
Gruss aus Deutschland.

von Stephan H. (stephan-)


Lesenswert?

die Sprungmarken für die IRQ´s hast Du hoffe ich auch gesetzt ?
0Bh, 1Bh und 2Bh ?

von Joed ". (Firma: GSE) (joed_z)


Lesenswert?

nein da ich nicht weiss welche Register gemeint sind.
weder TCON noch TMOD ...
was sollen das für register sein?

von Stephan H. (stephan-)


Lesenswert?

jeder Interrupt löst einen Sprung aus. Die Vectoren dafür stehen im 
Datenblatt des 8051.
An diesem Vector steht dann wieder ein Sprung zu DEINER Interruptroutine 
und diese endet in nahezu 100% aller Fälle mit RETI

http://www.ne555.at/8051-mikrocontrollertechnik/318.html

von Bernhard S. (b_spitzer)


Lesenswert?

Joed "Z" schrieb:
> ich bin im Modus 1 also 16 bit. mir ist auch bewussst das die high TH0
> und Low in TL0 hingehören. ist aber gewollt. TIMER0 steht auf 10.
Nö. Mit TMOD=0x22 sind beide Timer im Modus 2, also 8Bit mit 
Auto-Reload.
Timer 1 läuft aber nicht und dessen Interrupt ist auch nicht enabled. 
Also nur Timer 0 mit Interrupt 1, soweit alles richtig. In TH0 müsste 
für 200us der entsprechende Wert für die Maschinenzyklen stehen. Wenn Du 
den Controller mit 12MHz betreiben solltest, dann muss TH0 = 256-200; 
sein. Für andere Quarzfrequenzen oder X2-Modus musst Du umrechnen.
>
> void timer0_irq (void) interrupt 1
> {
> // alle 200 us muss noch eingestellt werden
>   dreh();
> }
Was passiert denn in dreh(); ?? Wenn das länger als 200us dauert, dann 
hast Du ein Problem.

> ich habe dort einen dreher eingebaut
         Was soll das  ^^^^   sein?
Liefere mal den vollständigen Code (also auch die ISR für  EX0 und Timer 
2 (wieso stellst Du eigentlich IT1 ein??)

@Stephan: bei der Programmierung in C ist die Einprungadresse 
uninteressant. Das erledigt der Compiler anhand der IRQ-Nummer (die 
entspricht für die unteren IRQs dem Bit im Freigabregister IEN). Der 
Compiler fügt auch das RETI in den erzeugten Code ein. Die gezeigten 
ISRs sehen erstmal vernünftig aus. Der nicht gezeigte Teil ist noch 
fraglich.

tschuessle
Bernhard

von Stephan H. (stephan-)


Lesenswert?

Bernhard Spitzer schrieb:

> @Stephan: bei der Programmierung in C ist die Einprungadresse
> uninteressant. Das erledigt der Compiler anhand der IRQ-Nummer (die
> entspricht für die unteren IRQs dem Bit im Freigabregister IEN). Der
> Compiler fügt auch das RETI in den erzeugten Code ein. Die gezeigten
> ISRs sehen erstmal vernünftig aus. Der nicht gezeigte Teil ist noch
> fraglich.


verwöhnte Bengel :-)))

von Gert (Gast)


Lesenswert?

Zu den Interrupts der 8051er gibt es hier im 2. Teil einige Videos:
http://et-tutorials.de/mikrocontroller/

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.