Hallo Leute, ich sehe hier ab und zu mal rein und finde diese Forum manchmal gute Ideen und Lösungsansätze. Nun, ich hab da auch ein Problem mit einem 80C537 der mit 24Mhz Takt arbeitet. Ich benutze die zweite serielle Schnittstelle des Kontrollers in halb Duplex bei 9k6. Ziel meiner Anstrengung ist es eine eigentlich recht simple Fernbedienung an einem seriellen Bus (CIV) angeschlossen ist. Die Entwicklungsumgebung ist der KEIL Compiler und ich benutze C als Programmiersprache. Leider schmiert mir das Programm des Kontrollers immer mal wieder unter Last ab oder ich verliere Zeichen. Eigentlich müsste ich noch viel mehr in der ISR machen aber wegen der Probleme habe ich mir das schon mal gekniffen und erledige die Vorauswertung der reinkommenden Telegramme beim Lesen des Rinpuffers im Programm. Leider ist die Serielle nicht gut designed. Es fehlt natürlich wieder ein adäquater Empfangspuffer. Ich dachte auch schon mal daran die ISR in Assembler zu formulieren, jedoch so groß ist der generierte Kode des C-Compilers nicht. Den Gewinn schätze ich nicht so hoch ein. Wenn euch was dazu einfällt, bitte immer raus damit. Eine Bitte noch vorweg. Ob der von mir benutzte Browser ok ist oder nicht ist und soll nicht Gegenstand der Diskussion sein oder werden. Das Projekt ist nur Hobby daher hat es auch keine wirklich hohe Priorität. Gruß aus Dortmund, Gerd, DD4DA
"Ob der von mir benutzte Browser ok ist oder nicht ist und soll nicht Gegenstand der Diskussion sein oder werden." Ich weiß jetzt nicht, was das mit Deiner Frage zu tun hat, aber gemault wird nur bei sehr groben Fouls (Quelltexte als Word, PDF usw., Main ohne Hauptschleife usw.). Dein Programm ist leider nicht vollständig, daher sind Seiteneffekte nicht zu erkennen. Aber laß mal das "using 0" weg, das müßte tödlich sein. "using" ist wirklich nur in absoluten Ausnahmefällen sinnvoll, besonders als Einsteiger fährt man viel besser, wenn man die Bankzuweisung dem Compiler selber überläßt. In der Regel klaut man sich dadurch außerdem 8 Byte wertvollen SRAM. Irgendein Idiot muß wohl bei 80C537 Beispielen "using" verwendet haben und nun machen es alle nach und fliegen auf die Schnauze. Peter
ich weiss nicht ob es Sinn macht, den Int während der Routine auszuschalten, es ist ja kein Taster oder sowas, das undefiniert prellen oder zwischendurch noch mal ausgelöst werden kann. Bei 24 MHz macht Dein Prozessor ca 25000 Befehle, bevor das nächste Byte vorliegt. Da könntest Du schon fast auf die ISR verzichten und die Daten durch polling abfragen.
Wooh, das war jetzt schnell und auch noch erfolgreich. Ich habe die IRQs zur Ausführungzeit der ISR unberührt gelassen und ebenfalls die "USING 0" - Anweisung radiert. Das Ergebnis ist überraschend positiv. Zum einen fehlen jetzt keine Zeichen / Telegramme mehr und zuum anderen kann ich mit 9k6 nun richtig Speed machen ohne das mir der Kontroller die Löffel hängen lässt. Noch ergänzend will ich erwähnen das dass Problem tatsächlich an dem "USING 0" lag, warum auch immer. Ich benutze kein Bankswitching da mein Programm eh in 2K Adressraum passen sollte. Mehr kann ich mit dem Keil auch nicht linken da es die EVal-Version ist. Bequem ist die Umgebung schon -mir kommt aber dann und wann schon mal der Verdacht dass die Libraries nicht so ganz sauber sind. Zumindest sind die Routinen der Lib manchmal etwas umständlich - verglichen mit dem ASM Code den ivch von Hand schreiben würde und den den der Compiler/Linker später dafür einsetzt. Lesbar ist er jedoch noch - wenn auch mit Mühe. Das Gerät dass ich baue / programmiere soll mal meine Funkgeräte (CIV-Schnittstelle ) steuern. Die Funkgeräte sind in Japan konstruiert und so manch nützliche Funktion wurde gegen weniger nützliche Funktionen auf dem Bedienpanel eingetauscht. Der PC löst dass Prblem schon recht hübsch, jedoch wäre mir ein diskretes kleines Gerät lieber. Ist transportabler und es ist kein Windows drauf. Das Gerät soll via CIV-BUS die DSP-basierte implementation eines quasi-variables Bandfilters in der ZF des Empfängers mit Hilfe eines Poti und dem Kontroller die Bandbreite von aussen einstellbar machen. Dazu benutze ich den ADC und ein paar Poti, errechne die Parameter und forme das CIV-Telegramm und sende es an das Funkgerät. Da alle Stellgrößen auf dem Panel digital sind lassen die sich gut von aussen anfassen. Das muss aber schnell gehen. Der zweite Schritt ist dann ein 25iger Tastenfeld mit hilfe dessen ich Frequenz und andere Betriebmode Parameter schnell verstellen will ohne dass ich mich wieder in die Menü's der Funkgeräte vergraben muss. Die sind umfangreich und deren sachliche Zusammenstellung öffnet sich einem Westeuropäer auch nicht auf Anhieb. Nochmals meinen Dank für die schnelle und erfolgreiche Hilfe. So komme ich doch schon weiter. In der Keil-beschreibung finde ich nicht viel über das Verhalten von "Using" in einer Non-Bankswitching Umgebung. Die gebes es in ihren Beispielen immer brav an. Ich unterstelle das zahlende Kunden (3500 Euro) diese Info nicht vorenthalten wird. Gerd, aus Dortmund DD4DA
"das dass Problem tatsächlich an dem "USING 0" lag, warum auch immer." Dann war wohl meine Vermutung richtig, daß das tödlich ist. "using" sagt dem Compiler: Kümmere Dich nicht mehr um die Registersicherung, denn ich mache das jetzt. Blöd nur, wenn man dann ausgerechnet die Bank 0 nimmt, die ja auch das Main benutzt. Der Interrupt zerhackt Dir also die Register und Dein Main schmiert ab. Die Registerbank hat auch nichts mit Codebanking zu tun, jeder 8051 hat 4 Registerbänke a 8 Register. Und das mit den Interrupts abschalten stört zwar nicht, bringt aber auch nichts. Der 8051 hat nämlich eine besonders clevere Interruptlogik, die Prioritäten unterstützt und dadurch die doppelte Ausführung der gleichen Prioritätsstufe unmöglich macht. Ein Interrupt könnte nur dann sich selbst unterbrechen, wenn man innerhalb des Handlers die eigene Priorität hochsetzt. Peter
Ich glaube eigendlich nicht dass using 0 das Problem ist (war). Meiner Meinung nach ist using 0 und weglassen das gleiche. using 0 heist dass im Interrupt alle benutzten register auf dem stack gespeichert werden. Die 0 gibt dabei die verwendete Registerbank an. Mit using 1 kann der Compiler manchmal die PUSH POP der Rn Register sparen. Du hast keinen Ringbuffer programmiert! Hier ein Beispiel wie ich das mache: //Groesse des Rxbuffers #define BUFFSIZE 0x20 //muss 2er Potenz sein void Serial2IRQ(void) interrupt 16 { if (RI1) // RI1; RX IRQ-Handler { InBuffer[InBufCounter] = S1BUF; // Zeichen in buffer InBufCounter++; // Lesezeiger weiterstellen InBufCounter&=BUFFSIZE-1; // Buffer begrenzen RI1=0; // lösche RI1 FLAG } if (TI1) // Transmiter { TI1=0; // lösche TI1 Flag } } Achtung: im Hauptprogramm muss immer wenn irgendwas mit InBufCounter gemacht wird, der ser Int kurz gesperrt werden Noch ein paar Bemerkungen zu den Libs: Die sind wirklich sehr gut optimiert. Wenn du glaubst das in ASM besser machen zu können dann solltest du den Programierstil überprüfen Mann kann mit Keil so programmieren, dass so gut wie keine Libmodule eingebunden werden. Nochmal: USING hat nichts mit Bankswitching zu tun! Thomas
Ich möchte anmerken dass ich kein professioneller Programmierer bin - ich glaube ich würde verhungern, gemessen an der Zeit die ich für meine Bastelprogramme brauche. :-) Was nun wirklich die Ursache für die ABstürze war, werde ich mal am Wochenende untersuchen. Ob es einen Unterschied gibt ob USING 0 oder "nichts" das glkeiche ist offenbart das Assemblerlisting des Compilerlaufs. Die Keil Umgebung ist sehr bequem und ich benutze sie gern. Leider kann ich mangels der 3500.- für das ProfDevKit, nur kleine Programme schreiben und muss den Speicherbedarf etwas im Auge behalten. Was mir ganz besonders gut gefällt ist der MON51. Wenn ich mal im Lotto gewinne... Ich hab nochmal die Ringpuffer-Nummer angehangen. So isses einer. Nochmals vielen Dank für eure Hilfe. Gerd aus Dortmund DD4DA
Ich habe mal die erzeugten ASM-Quellen des Compilers mit und ohne den Einsatz von "USING 0" verglichen und als Anhang beigefügt. Thomas, der Unterschied ist recht deutlich zu erkennen. Es ist wie Peter schon vermutet hat, das ohne "Using 0" im Aufruf, mehr gesichert wird bevor der eigentliche ISR-Handler ausgeführt wird und, selbstverständlich im Anschluß wieder zurückgeholt werden. Ich habe derweilen einige experimente mit dem Abschalten des IRQ wärend der Ausführungzeit des ISR gemacht. Es macht derzeit keinen Unterschied ob abgeschaltet wird oder nicht. Da die ISR eh mit Priorität von 3 (höchste) läuft und sonst kein weitere IRQ definiert ist, erwarte ich auch keine Nebeneffekte. Das wird sich ändern wenn andere IRQ-Quellen behandelt werden müssen. Ich hab da noch einen ADC-Wandler auszuwerten. Evtl. kommt auch noch ein 25er Tastenfeld dazu. Gruß Gerd
Du benutzt meiner Meinung nach eine alte Version des Compilers. Der Code bei using 0 ist schlicht falsch da der DPTR nicht gesichert wird. Das ist (war) ein Bug im Compiler. Wenn du die DPTR Features des 517 ausschaltest sollte der Code identisch sein. Da der DPTR bei dir auf den Stack kommt vermute ich mal dass du den Large Mode verwendest oder? Den IRQ speren solange die Interruptroutine läuft ist nicht notwendig. Thomas
Hallo Thomas, der Compiler ist aktuell und bei Keil als eval zu saugen. Ich benutze den Large Mode. Ob es ein Bug ist kann ich nicht sagen. Ich habe "mein Problem mit dem USING 0" auch mal auf einer älteren Version probiert und bin ebenfalls auf die Nase gefallen. Werde mir das Assemblerlisting dazu mal ansehen und mit dem Aktuellen vergleichen. Na ja, ich möchte mit den Registerbänken manuell nichts machen daher ist die USING Problematik nicht wirklich ein Problem für mich. Den Irq im Handler zu sperren hab ich weggelassen. Ich bin aber darauf hingewiesen worden dass ich den IRQ sperren muss wenn ich die Variable des Zeichenindex innerhalb des Haupprogramms ändere - was ich ohne Zweifel mach wenn ich feststelle wieviele Zeichen im Puffer sind. Ich werde jedoch den Teil der Auswertung mal probieren in die ISR zu verlagern. Mal sehen ob ich genug Rechenzeit dafür übrig habe. Das CIV-Protokoll ist so aufwendig nicht und daher hab ich nun was für das kommende Wochenende. Gerd
"Ich bin aber darauf hingewiesen worden dass ich den IRQ sperren muss wenn ich die Variable des Zeichenindex innerhalb des Haupprogramms ändere" Das ist korrekt. In der Mainloop ist Sperren durchaus sinnvoll und sogar notwendig, wenn mit Interrupts Variablen ausgetauscht werden müssen. Im Handler selber ist es Mumpitz, da der sich nicht selbst unterbrechen kann (s.o.). Warum benutzt Du das Large-Modell ? Es erzeugt etwa doppelt so großen Code und läuft nur halb so schnell. Es macht nur Sinn, wenn man ständig mit sehr großen Datenmengen arbeiten muß. Einen simplen FIFO kann man auch im Small Modell als xdata deklarieren, wenn er nicht mehr in die 256 Byte idata paßt. Peter
nochwas was ich vorher vergessen hatte. Der Code mit using 0 wäre korrekt wenn du DPSEL in der main einmalig am Anfang auf 1 gestellt hättest. Dann würde DPTR 0 für den Interrupt verwendet werden DPTR 1 für den normalen Calltree. Das beste ist immer noch "Use multiple DPTR" in den Optionen für deinen Target auszuschalten. Ich habe das gerade nochmal mit V8.02 ausprobiert. ohne multible DPTR support passt der Code auch mit using 0. Dabei habe ich bemerkt, dass S1CON im Gegensatz zu Dallas wohl nicht bitadressierbar ist (Was für ein MIST) mein Vorschlag mit if(TI1) passt dann nicht. es muss dann heisen: if (S1CON & RI1) Thomas
Hallo Peter, warum ich das Large Modell benutze...mhh...wenn der Compiler/Linker fertig ist habe ich es später mit ca 16Kbyte Code Segment size und etwa 32Kbyte XDATA Segment Size zutun. Ich kann die Module selber nicht fertig übersetzten und binden - das erledigt später ein Freund für mich der das Keil-PDK am Institut benutzen darf. Zugegeben ist der Weg umständlich aber für mich ist das Programmieren von Microcontroller nur ein Hobby und dafür wäre die Anschaffung des Keil-Systems vorsichtig ausgedrückt, überzogen. Die frei verfügbaren Umgebungen wie SDCC51 und andere sind mit was den Aspekt des Debuggens betrifft, zu umständlich. Ich schreibe daher mein Projekt in Lego Modulbauweise. Mumpitz, ja recht hast Du - genau das ist es gewesen. Ich hab nochmal etwas über die IRQ-Struktur und der Prioritäten gelesen nach dem ich hier mit der Nase in den Senf gestossen wurde. Wichtiger ist aufzupassen das beim anfassen der Puffer und Zeichenzähler in der Main Loop auf den IRQ aufpasse. Werde mir den ISR nochmal vornehmen.Grundsätzlich löffelt der schon mal nicht mehr ab und verliert auch keine Zeichen mehr. Da scheint was zu gehen - will also die CIV-Messages schon innerhalb der ISR wieder aus den Zeichen zusammenbauen. Damit kann ich Speicher sparen denn die Steuerzeichen muss ich nicht erst speichern sondern mit einem Handler gleich in eine Message-Tabelle schreiben. Noch eine Frage die sicherlich Ansichtssache ist. Ich habe es zum Teil mit Funktionen zutun die mit mehr als einem Argument augerufen werden müssen. Nun hab ich mir angeshen wie umständlich der Compiler die Variablen in ASM übernimmt. Der Fummelt zum Teil mit den DPTR rum das die Heide kracht. Wenn ich die Variablen global halte kann ich die innerhalb jeder Funktion anfassen. Das würde den komplexen Übergabeumgang sparen - schön ist das aber nicht. Wie machst Du sowas? Schreibst Du die Funktionen komplett mit Übergabeparametern und Retcode? Die Alternative wäre eine Struktur zu bauen und dann nur den Zeiger auf die Struktur übergeben. Gerd
Dabei habe ich bemerkt, dass S1CON im Gegensatz zu Dallas wohl nicht bitadressierbar ist (Was für ein MIST) mein Vorschlag mit if(TI1) passt dann nicht. es muss dann heisen: if (S1CON & RI1) Ja, ist verdammter MIST. Ich hab ein Makro für RI1 und TI1 gebaut. Ist später (wenn ich noch mehr graue Haare hab) mal etwaseinfache zu lesen was dort passiert ohne gross drüber nachdenken zu müssen das Siemens beim S1CON und weiteren SFR gepennt haben. Beim S0CON sind die Flags Bitadressierbar. Warum nicht auch beim zweiten Port öffnet sich mir nicht. Gerd
"Nun hab ich mir angeshen wie umständlich der Compiler die Variablen in ASM übernimmt. Der Fummelt zum Teil mit den DPTR rum das die Heide kracht. Wenn ich die Variablen global halte kann ich die innerhalb jeder Funktion anfassen. Das würde den komplexen Übergabeumgang sparen - schön ist das aber nicht. Wie machst Du sowas?" Das sind die Folgen des Large-Modells und genau deshalb benutze ich es nicht. Es gibt überhaupt keinen Grund das Large-Modell zu nutzen. Die Größe des Programms hat damit überhaupt nichts zu tun. Im Small Modell muß man lediglich große Variablenfelder, die nicht mehr in den idata passen als xdata deklarieren. Large erspart Dir also nur Schreibarbeit für die explizite Speicherbereichzuweisung bei großen Variablenfeldern. Nimm mal Small und staune, wie klein die Programme plötzlich werden. Lies Dir auch mal den C51-Primer durch. Peter
Hallo Peter, C51-Primer - ja, gut Idee. Small Model hab ich mal eingeschaltet. Die Codesize ändert sich um 1Byte. Large benutzt 1Byte weniger als Small. Es sieht so aus als dass sich nicht viel ändert. Liegt evtl auch am Compiler/Linker im Zusammenhang mit dem Umstand dass ich nur die EVAL hab. Der Borland PC-Compiler für DOS unterscheidet auch zwischen den Speichermodellen. Der generierte Code sieht erheblich anders aus. Es ist schade dass der Compiler so teuer ist. Ist ein sehr schönes Werkzeug.
"Large benutzt 1Byte weniger als Small." Bei kurzen einfachen Funktionen kann es durchaus nur ein Byte Unterschied sein. Sind nur wenige lokale Variablen zu bearbeiten, hält auch LARGE sie in Registern und braucht den DPTR garnicht. Du mußt das schon bei umfangreicheren Funktionen oder ganzen Programmen betrachten, da wird der Unterschied wesentlich deutlicher. Anbei mal ein Beispiel (15 Byte / 9 Byte) Peter
"Anbei mal ein Beispiel (15 Byte / 9 Byte)" Der Compiler 8.02 für Windows erzeugt exakt den gleichen Code. Die Fummelei mit DPTR liegt ja in der Natur der Sache. XDATA-Zugriffe werden eben über die DPTR gemacht. Sieht halt nicht sehr schön aus und schneller werden die Programme bei extensivem Genuss dessen, auch nicht. ich hab das Array dass die CIV-Messages aufnimmt in das IDATA Segment verlegt. Das geht sort recht gut ab. Nun kommt nochmal das eigentliche Protokoll-Handling. Ich werde ncohmal versuchen es in den ISR zu verlegen. Damit kann ich mir eine recht große Tabelle sparen und eine Menge an Traffic innerhalb der Programme spare ich auch ein. Gruß aus dem warmen (na endlich) Dortmund, Gerd
Der ISR für den 80c537 ist nun fertig und liefert erstaunlich lückenlose Ergebnisse. Ich bin beendruckt wie schnell der doch betagte Controller mit 19k2 ohne Handshake umgeht. Das CIV-Protokoll sieht sowas nicht vor. Nochmal meine Dank für die Hilfe. Gerd aus dem warmen Dortmunder Westen
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.