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.
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
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"...
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
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
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...
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
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.
Hallo, hast Du EA auch auf 1 gesetzt ? Sonst sind alle Interrupts gesperrt Gruß BerndB
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
die Sprungmarken für die IRQ´s hast Du hoffe ich auch gesetzt ? 0Bh, 1Bh und 2Bh ?
nein da ich nicht weiss welche Register gemeint sind. weder TCON noch TMOD ... was sollen das für register sein?
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
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
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 :-)))
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.