Hallo Leute, Kann mir jemand helfen? Ich lerne gerade die Interruptfunktion bei dem MCU: ATMEL AT89S8252 Benutze den READS-51 Compiler. Jedoch gelingt es mir nicht, die ISR anzusprechen. Findet jemand den Fehler in meinem Code? Vielen Dank für die Hilfe
1. Es heisst IRQ, nicht IQR (will vermeiden, dass du dich als Anfänger an falsche Begriffe gewöhnst, die gewöhnt man sich nur sehr schwer wieder ab) 2. TF0 braucht meines Wissens nicht in der ISR gelöscht werden, das macht die Hardware automatisch. Genauso brauchst du es nicht nach dem Beschreiben von TCON löschen, da es dort schon durch Beschreiben von TCON gelöscht wurde. 3. Auch die Zählregister TH0 bzw. TL0 brauchen nicht gelöscht zu werden, der Zähler löst einen Interrupt aus, wenn ein Überlauf von FFFF nach 0000 erfolgt, somit sind die Zählregister beide 00. Du musst sie nur dann beschreiben, wenn du eine andere Zeit benötigst, sind beide 00, so läuft der Zähler mit der maximalen Zeit. 4. Ich könnte mir vorstellen, dass dein Programm eigentlich richtig ist (so sieht es auf den ersten kurzen Blick aus), und dass das Problem darin liegt, dass du alles in einer C-Main-Funktion machst, vielleicht kommt da dein Compiler durcheinander. Trenn das mal ordentlich auf: void main(void) { TH0 = TL0 = 0; TMOD = 1; TR0 = 1; Timer 0 Run Flag ET0 = 1; EA = 1; while(1); } void T0_ISR(void) interrupt 1 { P1++; } Alternativ geht auch komplett ASM, also ohne C-Code. Ralf
Zunächst mal Danke für die div. Infos. Die haben mir einige Unklarheiten in meinem bisherigen Wissen über Timerregister genommen. Ich habe Deinen Code in C ausprobiert, READS-51 motzt immer, ich glaube ich muss mal einen anderen Compiler ausprobieren. IQR... da hab ich wirklich einen Müll in meinem Gedächtniss natürlich IRQ. Danke für den Hinweis, das hätte ich mir sonst wirklich noch angewöhnt! Ich probiere weiter, gebe nicht auf!!!
...Hehe, juphiiheii! ...Nur nicht aufgeben und es geht! Ich hab Dein Rat befolgt und das ohne asm. probiert. Würde mich aber denoch interessieren warum READS-51 meinen alten Code anstandslos übersetzt, aber nicht funktioniert auf meiner Hardware?! Denoch; Danke!!! Hier noch mein kurzer, aber funktionierender Code: //****************************************************** #include <sfr52.h> // Register ATMEL AT89S8252 void interrupt (0x000B) square(void) { P1++; // Port1 inkrementieren } main() { TMOD=1; // Timer0-Mode1(16Bit) TR0=1; // Timer0 starten ET0=1; // Timer0-IRQ freigeben EA=1; // Alle IRQ's freigeben while(1); // Enlosschleife für IRQ-Test } //******************************************************
Hmm? Joe hast Du Lösung für mein Assembler-Problem? Ich mach mich mal schlau über "prototype" Hab da irgendwie schon mal was darüber gelesen, aber keine Verwendung dafür gefunden. Als nächstes will ich dann sowieso die IRQ-Prioritäten erforschen, also sollte ich das auch in asm beherrschen.
Nein, will dich nicht verwirren, Prototype bezog sich auf deinen C Code. In deiner Version hast du die ISR vor der MAIN Schleife, somit ist die ISR Funktion bekannt und der Compiler meckert nicht. Wenn du das Beispiel von Ralf verwendest dann mußt du die Funktion vor der MAIN Schleife deklarieren, dass nennt man Prototype.
@Joe: Was hat es mit "prototype" auf sich? Ich habe nachgeforscht, habe das aber immer nur als Kommentar gefunden. zB zwischen "include-Anweisungen: include <sfr51.h> // prototypes include <Sio51.h> ... ...
...Ach so, und ich dachte das ist ein Befehl, wie dämlich! Danke euch für die Hilfe, mir ist ein Licht aufgegangen.
Also, wenn die Funktion void funktion (void) heißt dann deklarierst du vor der MAIN // Prototypes void funktion (void); alles klar ?
ja, ich glaub was Du meinst; hab das jetzt geändert //************** main() { TMOD=1; // Timer0-Mode1(16Bit) TR0=1; // Timer0 starten ET0=1; // Timer0-IRQ freigeben EA=1; // Alle IRQ's freigeben while(1); // Enlosschleife für IRQ-Test } void interrupt (0x000B) square() { P1++; // Port1 inkrementieren } //**************
Hallo, Da ist der Interruptbengel schon wieder! Ich bin nun bei den Prioritäten angelangt, finde aber in dem Datenblatt für ATMEL AT89S8252 keine Angaben über Prioritätshandling. Ich weiss das sie nach den Vectoradressen gegliedert sind, würde jetzt aber gerne mal #INT1(0x0013h) als 1. Priorität definieren. Das Register heisst IP(0x0B8h). Leider nur dieses Eine! Meine Frage: - Beim 80C535er sind es zB. IP0 und IP2, wodurch ich 4 Stufen Binär definieren kann. - Mein AT89S8252 enthält aber nur IP0. - Gehe ich richtig in der Annahme das mein 8051 nur 2 definierbare Prioritätsstufen hat(Low, High)?
Ja, der Standard-8051 hatte nur 2 Prioritäten. Die Priorität ist auch nicht mit der Auflösungsreihenfolge zu verwechseln. Sie bedeutet wirklich, daß ein Interrupt den anderen mittendrin unterbrechen darf, wenn er die höhere Priorität hat. Das ist z.B. sinnvoll, wenn man nen schnellen jitterarmen Timer haben will und aber im UART-Handler Befehle geparst werden sollen, was durchaus länger dauern kann. Dann einfach dem Timer die hohe Priorität geben und schon stört ihn der lange UART-Interrupt nicht mehr. Peter
Die Atmel-Datenblätter zu den 8051ern bauen mittlerweile alle auf dem "Hardware-Manual" von Atmel auf, dort ist der grundlegende Aufbau beschrieben. Gibts als PDF auf der Atmel Website: http://www.atmel.com/dyn/products/other_docs.asp?family_id=604 Ganz unten, unter "User Guide" findest du den Befehlssatz und das angesprochene Hardware-Manual, ich empfehle, beide runter zu laden, und dann natürlich fleißiges Studieren der Unterlagen ;-) Ralf
juppii, jemand hat sich gemeldet! @PeDa und Ralf: Ich danke euch beiden sehr für eure Hilfe. Werde mich morgen fleissig hinter die neuen Infos machen. Mein Kopf raucht langsam, muss erst die Batterien aufladen (1.Priorität ;-o)
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.