SW-Uart input abfrage abbrechen ? Hallo, Ich muß mehrere SW-Uart (90S8515)verwenden und habe das Problem das ich an einer Stell auf 6 Zeichen warten muß. Kommen die 6 Zeichen ist auch alles OK. aber wenn sie nicht kommen (oder nur 5) hängt mein Programm. gelöst habe ich es jetzt erst mal mit dem Watchdog aber ich will nicht das ganze Programm neu Starten . Ich denke eine Interruptroutine ist eine Lösung, die darf ich dann aber nicht mit Reti (Return) verlassen, um nicht wider in der Warteschleife zu hängen, sonder mit Goto aber was muß ich da beachten ? Register zurücksetzen ? Ich verwende Bascom aber das Problem ist ja sicher nicht nur Bascom spezifisch ... Danke für eine Hilfe Gruß HansHans
warum nicht im interupt ein flag setzten wenn abgerochen werden soll und dann ganz normal reti und in der schleife darauf prüfen und abbrechen (in c heisst der befehl break, in bascom hab ich keine ahnung)
Also anscheinend doch Bascom spezifisch - - > und in der schleife darauf prüfen und abbrechen auf die Bascom Befehle Inputbin oder Get habe ich aber keinen Einfluß die Wartet nun halt mal auf ein Zeichen .... oder habe ich was übersehen ? Ideal wäre ein Befehl der nur max 0,5s den Eingang abfragt und nicht auf ein Zeichen wartet .
lass doch in der Empfangsroutine die Zeichen nur in einen buffer schreiben, wieviele angekommen sind, steht in einer extra-Variablen. Im Hauptprogramm fragst du nur die Anzahl der Zeichen ab, sind es genug, liest du die Zeichen aus dem Buffer und wertest die dann erst aus.
- - > lass doch in der Empfangsroutine die Zeichen nur in einen buffer schreiben das geht aber bei Bascom nur mit dem HW-Uart für den SW gibt es keinen Buffer und wenn man sich selber einen schreibt bleibt der auch wieder hängen wenn man nach dem Zeichen fragt und keins kommt oder habe ich die falschen Befehle für die SW-Uart Abfrage ?
wer will dich hindern, beim Software-Uart dasselbe wie beim Hardware-Uart zu machen? Bei der HW-Uart löst normalerweise der Rxc-Int dieses aus, beim SW-Uart macht man das halt nach 8,5Bitlängen nach der fallenden Flanke des Startbit. Ich sehe da keinen prinzipellen Unterschied. -ext. Int mit fallender Flanke, Timer auf halbe Bitlänge setzen, ext. Int sperren -nach halber Bitlänge schauen, ob Startbit immer noch 0 nein, war nur ein Rülps, ext. Int wieder freigen, Timer stoppen ja -> Zeichen beginnt Timer auf volle Bitlänge stellen, in der Timer-ISR das Bit einlesen, nach 8 bit ist das Zeichen komplett und wird in den Buffer geschrieben, Schreibpointer erhöhen (max. prüfen, ggf. an den Bufferanfang zurücksetzen), rec_byte_count incrementieren, fertig. Die komplette Pufferung ist in jedem Fall Softwaresache. Zu Bascom-spezifischen Sachen kann ich dir allerdings absolut nicht weiterhelfen.
Hallo, Danke crazy horse aber die ganze SW Routine wollte ich nicht neu schreiben dafür habe ich ja Bascom ... Ich habe eine Lösung gefunden, und mein Programm läuft. Ich verlasse die Timer -Interruptroutine ohne Return (Reti) setze aber Flag I (Bit.7 im SREG) und beende dann mit Goto, somit stopt die SW-UART abfrage wenn nach 1s kein Zeichen kam . Nachteil: 4 Byte bleiben auf den Stack, (warum 4 weis ich nicht, 2 waren mir klar) jetzt mache ich 4 x POP R0 da ich denke (hoffe) das Register R0 von Bascom nicht benutzt wird. Jetzt meine neue Frage an die ASM Fachleute : Wie lösche ich in (mit) ASM 4 Byte vom Stack ? ohne ein Register zu verändern ? oder kann ich den Stack- zeiger verändern ? (meine letztes ASM Programm war noch mit einen Z80) Danke für eine Hilfe......
muss man da nicht nur den Stackpointer entsprechend modifizieren? Also um 4 Positionen weiter oben verschieben (Stackpointer wachsen doch immer noch von oben nach unten, oder?) Zum Thema SW-UART fällt mir eine AN vom Atmel ein (AVR304). Allerdings ist die nur halfduplex. Da wird ein 8Bit-Timer benutzt. könnte man das Ding bei Verwendung eines weiteren Timers nicht sogar zu einer vollduplex-UART aufbohren, sofern man diesen Timer für nix anders braucht? Gruß Rahul
--->Stackpointer entsprechend modifizieren wie ist der ASM Befehl dafür ? INCR ?? DECR ?? Gruß HansHans
Versuch mal folgendes: ; dein interrupteinsprung interrupteinsprung_von_uart: ;stack wurde um 2 erhöht, stack enthält ruecksprungadresse vom ;interrupt ;es werden zwei ramzellen benötigt ;register werden nicht verändert sts ramadresse,temp1 sts ramadresse+1,temp2 ldi temp1,low(interruptabbruch) ldi temp2,high(interruptabbruch) ;erst low-teil dann highteil pushen push temp1 push temp2 lds temp2,ramadresse+1 lds temp1,ramadresse reti Damit hast du die rücksprungadresse manipuliert, deine interruptroutine wird wie ein normaler call bearbeitet, neue interrupts sind zugelassen und können bearbeitet werden interruptabbruch: ;deine routinen ;deine goto-routine ;oder dein assembler wie zum Beispiel ldi temp,irgendwas ; usw ;ende deiner routine ret
"Danke crazy horse aber die ganze SW Routine wollte ich nicht neu schreiben dafür habe ich ja Bascom ..." Das ist der Nachteil an allen vorgefertigten Systemen, Du kannst nur die Funktionen nehmen, die der Entwickler für Dich vorausgesehen hat. Brauchst Du was anderes, mußt Du es selber entwickeln. Deshalb benutze ich kein Bascom. Und da kommt der Vorteil von C ins Spiel: In C gibt es nichts vorausgesehenes, sondern Bibliotheken. Und diese Bibliotheken sind nicht monolitisch im Compiler mit einzementiert, sondern sie liegen als kommentierter Quelltext vor und jeder kann sie nach seinen Wünschen modifizieren und erweitern. Deshalb benutze ich C. Soweit ich bemerkt habe, hält sich Codevision aber nicht daran, sondern da ist auch vieles einzementiert. Ist quasi ein verkapptes Bascom mit C Syntax. Daher würde ich es auch nicht nehmen. Ich benutze WINAVR. Den Stack zu manipulieren ist sehr unsauberes Programmieren !!! Du kannst Dich nicht darauf verlassen, daß die Stackauslastung konstant ist. D.h. solche Programme laufen bei geringen Änderungen an völlig anderer Stelle oder auch bei einer anderen Compilerversion sehr gerne gegen den Baum. Ich würde es daher ausschließlich so machen wie crazy horse. Peter
Das ist aber bitte kein Vorteil C vs. Basic! Selbstverständlich gibt es Basics mit kommentierten Quellcodebibliotheken und C-Compiler ohne. Basic oder C ist nur eine Syntaxfrage, keine Philosophiefrage. Und auch in C gibt es "unvorausgesehendes"; die Sprache legt Dir auch Einschränkungen auf, wie unzählige Fragen hier ("64-Bit-Variablen", "gemeinsamer Pointer für RAM und Flash" fallen mir spontan aus jüngster Zeit ein) belegen. Die Anpassungsfähigkeit von C hört halt hinter den Funktionsaufrufen auf, wenn man an Operatoren und Programmablauf gehen will, muß man dann doch Assembler einflechten, was schnell arg kompliziert werden kann, weil man den Compiler selbst nicht im Griff hat. Also: deshalb benutzt Du WinAVR. Mit C hat das nichts zu tun.
Danke ihr habt ja alle irgendwie recht aber warum immer die Diskussionen ob ASM ,C Basic usw. wechselt ihr bei jedem kleinen Problem eure Sprache ? Wenn es ein Problem gibt muß es gelöst werden, mit dem was man halt gerade hat, und bei ist es halt im Moment Bascom, damit habe ich die auch bisher alles gelöst was ich gebraucht habe, so auch in diesem Fall das Programm läuft bis jetzt problemlos Da Register R0 frei ist,ob das nach Späteren Änderungen auch noch der Fall ist weis ich natürlich nicht. Deshalb such ich ja eine Lösung um 4 Byte vom Stack zu löschen ohne ein Register zu verändern (Ram erlaubt) Die Rücksprungadresse (wie von wb1 vorgeschlagen) zu ändere brauche ich nicht mehr . Nur 4 Byte vom Stack löschen ..... Mehr will ich nicht !!! geht das mit ASM oder auch mit Bascom ? wenn ja wie ? Danke .... (Nur zur Info: In Bascom ist eigenes ASM erlaubt bzw möglich) Gruß HansHans
4x pop r0 trotzdem verdammt schlechter code. es geht ja auch besser, nur willst du dir keine arbeit machen und lieber murksen
-- >4x pop r0 das mache ich doch gerade!! , da verändere ich aber doch r0 , das will ich vermeiden
Speichere ein register im ram, poppe und lade das register mit dem ursprungswert. beginn: sts ramadresse,r16 pop r16 pop r16 pop r16 pop r16 lds r16,ramadresse r16 ist unverändert, sp = sp-4
Danke wp1 ,genau so .... Das habe ich auch gerade gefunden .... Bascom ASM mix .... Var = Peek(0) pop R0 pop R0 pop R0 pop R0 Poke 0 , Var Danke für eure Hilfe Gruß HansHans
Der Vollständigkeit halber: Natürlich kann man auch den StackPointer manipulieren, aber dazu muß man ihn auch in ein Register holen (und dieses vorher retten). Ein IN, SUBI und OUT sind gerade mal drei statt acht (für 4xPOP) Takte. (Beim 90S8515 muß man freilich auch für den Fall der Fälle den Überlauf, d.h. Unterlauf betrachten, hat also IN, SUBI, OUT, IN, SBCI, OUT und damit auch 6 Takte ... bleib bei der Popperei!) Aber: weiß jemand, was der Bascom da noch zusätzlich auf den Stack legt? Da wird er doch mal vermutlich zu Beginn der Interruptroutine ein von ihm benutztes Register ablegen und am Ende wiederherstellen. Wenn Du nicht plötzlich vor einen Voodoo-Phänomen stehen willst, solltest Du da nicht in unverstandenen Eingeweiden rumpfuschen, sondern das Compilat disassemblieren, um zu sehen, was er da wirklich tut. Und dann würde ich die entsprechenden Werte genau dorthin poppen, wo er sie vorher weggepusht hat (falls meine Vermutung da stimmt). Dein Programm mag jetzt laufen, aber je nachdem in welchem Moment das Interrupt zuschlägt, sind vielleicht irgendwelche Register überschrieben, die der Bascom für sicher hielt. Ich weiß es nicht, aber ich würde es überprüfen.
- - >sondern das Compilat disassemblieren das habe ich gemacht daher wußte ich das r0 frei ist. - - > aber je nachdem in welchem Moment das Interrupt zuschlägt Ich gebe den Interrupt nur vor dem Start des SW-Uart frei und sperre ihn gleich wieder wenn die Zeichen eingetroffen sind. somit schlägt er nur innerhalb der SW-Uart Routine zu wenn eine Fehler in der Übertragung ist . Das Programm läuft im Moment wirklich fehlerfrei , aber ich verspreche euch wenn ich wieder Zeit finde, versuche ich die SW-Uart Routine von Bascom nochmals zu disassemblieren und eine Zeitüberwachung direkt einzuarbeiten , dann werde ich aber sicher noch mal Fragen haben. Im Moment muß ich aber erst noch andere Sachen machen . Gruß HansHans
"Das Programm läuft im Moment wirklich fehlerfrei" hihi, das kann wirklich nur ein Anfänger sagen, sorry. Ein Programm ist nicht dann fehlerfrei, wenn es gerade das tut, was es im Moment tun soll, also was der Programmierer eigentlich machen wollte. Die Fehlerarmut (von Fehlerfreiheit will ich gar nicht mehr sprechen) offenbart sich dann, wenn das Programm mit Zuständen (logischen und zeitlichen) konfrontiert wird, die der Programmierer nicht explizit vorgesehen hat. Und gerade dann Mist zu machen - dafür sind deine Ansätze bestens geeignet. Es gibt Software, die läuft monatelang scheinbar fehlerfrei, dann bockt es plötzlich. Wer denkt da an einen Softwarefehler? Richtig, kaum einer, der nichts davon versteht. Es gibt keinerlei Grund, solche Hilfskrücken einzubauen, und die Bemerkung - es läuft ja - kannst du dir getrost sparen, das macht es nicht besser. Man kann auch 230V-Lampen über Klingeldraht oder Koax anschliessen, funktioniert auch. Du handelst dir völlig unnötig Probleme ein, die vielleicht nicht mal jetzt auftreten, sondern später, wenn du scheinbar harmlose Änderungen machst oder ne andere Compilerversion benutzt. Und das alles nur, um sich die Arbeit zu sparen, es mit ein paar Zeilen mehr richtig zu machen, ich versteh es einfach nicht. Dazu kommt, dass man sich einen solchen Stil angewöhnt...
Hi, Was soll ich jetzt noch machen oder bin ich euch schuldig ? 1. ich habe Nachbestellung versprochen obwohl das Programm läuft 2. Ich programmiere kein medizinisches Gerät oder Mondfähren. 3. Es ist nur ein Hilfsmittel zur Meßdatenerfassung 4. Wenns ausfällt ist es unschön aber keine Katastrophe 5. vor meinen -- > Hilfskrücken hing das Programm min. 3 x am Tage da z.B. ein Meßgerät plötzlich keine Daten mehr sendet (Vom Profi programmiert ) 6. Seit meiner Hilfskrücken hing es nicht mehr Ich bin erstmals so zufrieden gelobe aber immer noch Nachbestellung Gruß HansHans
mir persönlich ist völlig egal, was und wie du es machst. Ich wollte dir nur klarmachen, das das, was du gerade machst, nicht die feine Art ist und sich das früher oder später höchstwahrscheinlich rächen wird. Software schreibt man heute nicht mehr "tricky" und kompakt um jeden Preis, sondern übersichtlich und wartbar. Dazu gehört, sich an die Konventionen zu halten. Stackmanipulationen gehören für mich zu den Dingen, die man lassen sollte (zumindest wenn es auch anders geht), der Stack gehört dem Compiler. Und nun lassen wir es gut sein, ja?
Wenn ich das richtig verstanden habe, arbeitet die SW-UART von Bascom nur, wenn Du sie aufrufst. D.h. Du kannst Dich immer nur mit einer unterhalten. Ist es das, was Du wirklich willst ? Sind dann nicht mehrere UARTs sinnlos ? Ich benutze SW-UARTS nur, wenn ich sie gleichzeitig brauche und dann müssen sie in einen Interrupt eingefügt werden. Der (Timer-)Interrupt sammelt die Bits und legt sie in einem Byte ab und setzt ein Flag, daß ein Byte empfangen wurde. Diese Flags von jeder SW-UART kann man dann im Hauptprogramm testen und die Bytes auslesen. Es kommt also nie zu einem Festhängen in der Empfangsroutine. Peter
[HansHans:] > Ich gebe den Interrupt nur vor dem Start des SW-Uart frei und > sperre ihn gleich wieder wenn die Zeichen eingetroffen sind. > somit schlägt er nur innerhalb der SW-Uart Routine zu wenn eine > Fehler in der Übertragung ist . Weißt Du, ob der Compiler ein Register vor dem Aufruf der UART-Routine belegt und nachher wieder liest? Und vielleicht ist es gerade dieses, das die Interruptroutine auf den Stack rettet, weil es das Register dann anders benutzt. Im Augenblick klingt das eher unwahrscheinlich, aber vielleicht erweiterst Du das Programm irgendwann, und plötzlich gibt es dann Probleme, wenn Du an diesen Kniff nicht mehr denkst. Aber das ist Dir ja auch offenbar bewußt. (Und von wegen Anfänger: von all den Ratgebern scheint ja auch keiner an die Gefahren gedacht zu haben ...) Mich würde übrigens einfach nur interessieren, was der Bascom da macht. Es schadet nie, zu wissen, wie ein Werkzeug arbeitet, damit man es optimal einsetzen kann. Dazu müßtest Du ja nur die Interruptroutine finden und schauen, was da gepusht und gepoppt wird.
Hallo HansHans, ich hänge gerade an dem selben Problem. Kann ich bitte mal einen aufschlußreichen Codeauszug von Dir haben ? Das wäre bestimmt sehr hilfreich ... vielen Dank mfg SMILEY
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.