Hallo Leute, ich bin erst neu in dem Forum, falls ich also etwas falsch poste weißt mich bitte darauf hin ... Meine anliegen ist wie folgt: ich verwende bei Bascom serial0charmatch um bei einer bestimmten eingaben, z.b: "test led" und CR in eine sub zu springen und dann verschiedene ports des ATmega 88 zu schalten um zu testen ob die led´s an dessen Port funktionieren. (CR ist hier die match variable) Dies funktioniert auch ohne probleme. Sobald ich dann in der sub bin schalte ich z.b Port B1 auf high und die led beginnt zu leuchten. Als bestätigung soll der anwender dann "j" eintippen und sendet es ebenfalls wieder mit CR an den Atmega. Diese Abfrage habe ich mit waitkey programmiert, also sobald der controller dieses "j" erkennt, springt er zu dem nächsten schritt. nun zum Problem: warum greift hier nicht die interruptroutine von serial0charmatch ein, sobald ich das "j" und CR in das Terminal eintippe?? Den Code kann ich leider im Moment nicht veröffentlichen, da ich an einem anderen Pc arbeite, aber vlt könnt ihr mir ja trotzdem helfen. Achso eins habe ich noch vergessen: ich kommunziere über UART und RS485 mit dem PC (Hyperterminal). MfG
:
Verschoben durch User
Du hättest dich lieber vorher für ein Forum entscheiden sollen http://bascom-forum.de/showthread.php?4569-Problem-mit-Waitkey-und-serialcharmatch&p=34116#post34116
ist doch nicht schlimm in 2 Foren zu fragen oder sind diese beiden Foren "verfeindet"?? eigentlich wollte ich nur etwas hilfe... kann ja nicht ahnen dass das gleich so negativ betrachtet wird...
sory, ohne Code ist es ein im Nebel stochern ... die Bascom Highlevelbefehle sind zwar recht nett, aber wie wann welche Interrupts verwendet werden bleibt dadurch im Dunkel ... hat mich auch schon ein manches Mal Stunden der Fehlersuche gekostet und verwende dergleichen daher nur noch sporadisch.
so ich hab jetzt mal den Code als .txt datei angehängt, vlt hilft das ja bei der Fehlersuche ;).. vielen dank schonmal im vorraus.
ui ui ui ... also: $regfile = "m2560def.dat" du schriebst Mega88 ??? naja, bei 4 x UART muss der 2560 sein. $crystal = 8000000 'intern Der interne Oszillator ist für UART nicht unbedingt der Hit -> Baudratenquarz Das ist genau so ein Beispiel warum ich die highlevelbefehle meide, man weiß nicht was da im Hintergrund passiert. wird die serial0charmatch vom Interrupt aus angesprungen oder wird Code über ein Flag außerhalb des Interrupts aufgerufen? wenn der Code vom Int aus angesprungen wird ist sowas: Waitms 100 Print #1 , "ERROR: unknown command RS232-PS" tödlich, weil der Controller Ewigkeiten in der Interruptroutine hängt, weil wenn ein Interrupt ausgeführt wird keine weiteren aufgerufen werden, es sei denn in der ISR wird der SEI ausgeführt, was aber sehr "interressante" Nebeneffekte auslösen kann. Die Frage, warum Dein Bytematch nicht aufgerufen wird ist daher ganz einfach zu beantworten, weil der Interrupt nicht ausgelöst werden kann, da deine ganzer Programmablauf in ner Interruptroutine liegt und eben der Controller wenn eine ISR läuft keine zweite ISR startet ;) Du bist bis zum Waitkey nicht aus der ISR raus gesprungen, sondern nur immer tiefer in Deine Programmstruktur ... Waitkey in einer ISR ist auch gelinde gesagt Schrott ... -> nochmal, nicht zur Strafe, nur zur Übung :)
ohh ja entschuldigung, ich habe wirklich den 2560 verbaut... muss ich verwechselt haben :) was die uart angeht, die funktioniert wunderbar.. was das serial0charmatch angeht, ist das ja ansich selber ein interrupt, weil sobald ich ein CR über das terminal, uart an den controller sende springt er in die routine des serial0charmatch... von dort aus in die sub, z.b. led_test und dort wartet dann das waitkey. sobald ich dort angelangt bin fragt er mich ja etwas und erwartet ein "j" welches ich über das terminal sende und wieder mit CR sende... dann gehts halt weiter.. jetzt war nur die frage warum er nach diesem "j" und CR nicht wieder in routine von serial0charmatch springt... er springt nicht rein weil er ja immernoch in der interruptroutine ist, sehe ich das richtig?? mfg
richtig, er ist noch in einer Interruptroutine, das Waitkey fragt das UDR-Register ab, wartet bis das J kommt, das nachfolgende <CR> würde wieder den Interrupt auslösen, aber das Programm ist da noch in der Subroutine der Interruptroutine, daher Interrupt gesperrt. Mit Verlaub dein Programmablauf ist murks. Das Bytematch ist auch kein Interrupt, sondern eine Subroutine, die aus der Interruptroutine URXC aus aufgerufen wird. Von der Subroutine aus rufst Du wiederum Subroutinen auf, was bedeutet, dass der Interrupt praktisch nie abgeschlossen wird. ... Du gehst praktisch Zur Haustür hinein in den Flur -> Vom Flur in die Wohnungstür -> Von der Wohnungstür ins Wohnzimmer -> Was machst Du nun wenn Dir auffällt, dass Du am Auto das Bier vergessen hast? ... nee, nicht zum Fenster raus, das ganze wieder rückwärts. In Deinem Programm wartet Deine Frau im Wohnzimmer und sagt Dir: "Hinsetzen Klappe halten"
Danke für die anschauliche Erläuterung, aber das eigentliche hauptprogramm läuft ständig, also die main. Dort werden alle möglichen messungen vorgenommmen und über dieses serial0charmatch wollte ich einfach nur das programm unterbrechen um z.b zu überprüfen ob noch alle led auf der platine funktionieren.... oder wie würdest du dies realisieren? grüße
ganz einfach, Du setzt in der ISR ein Flag ... ne Bitvariable z.B. dim serial0charmatch_flag as bit in der ISR dann: serial0charmatch_flag = 1 in der Mainloop dann: if serial0charmatch_flag= 1 then call tu_was() serial0charmatch_flag=0 endif Merke: Die Interruptroutinen immer so kurz wie möglich, LCD-Ausgaben, Wait, Print, alles was Ewigkeiten in der Abarbeitung dauert hat dort nix verloren ... immer rein, die wichtigsten Operationen durchführen und wieder raus. Langsame Prozesse immer von der mainloop aus anspringen. Beispiel: Du hast irgendwas von Notaus in Deinem Programm ... der ist sinnvollerweise auf einen Interrupt gelegt hoffe ich. In deinem alten Programm würde dieser Interrupt erst ausgeführt wenn der User mit seinen Eingaben zur LED-funktion durch ist :( Dabei sollte der unmittelbar bei Tastendruck kommen ... also bei Tasteninterrupt: Motor aus, ventile zu, Strom weg, Flag setzten dass notaus gedrückt und wieder raus aus der ISR. Die Ansteuerungen in der Mainlopp müssen dann bei jedem Zugriff auf die Peripherie abfragen ob Notausflag gesetzt, wenn gesetzt motor NICHT starten, Ventile NICHT öffnen etc.
ok, vielen vielen Dank Weinbauer für die ausführlichen Antworten. Ich werde deine Hinweise auf jeden Fall in meinem Programm berücksichtigen:) Eine kleine Frage habe ich allerdings noch: Wie umgehe ich dann, dass mein programm bei Waitkey wieder in die Interrupt routine springt, sobald ich das CR beim bestätigen mit "j" sende?
also ich hab das jetzt mal so umgesetzt und es funktioniert auch ohne probleme.. jedoch muss ich disable urxc waitkey enable urxc nicht verwenden... das programm springt nicht in die interruptroutine sobald ich mit j bestätige. Kann es sein das das Waitkey den buffer sofort ausliest und löscht und somit kein interrupt ausgelöst werden kann? beste grüße
das waitkey is nix anderes als warte auf rxc-flag, wenn rxc-flag gesetzt lese udr-Register aus, was dann das flag wieder löscht automatisch. eigentlich sollte die routine aber mit dem j schon abgearbeitet sein und der <cr><lf> dann die interruptroutine anspringen. wie aber bascom das waitkey in der mainloop umsetzt ohne dass dann in der warteschleife die interruptroutine angesprungen wird, da kann dir nur MCS oder der hex-file aufschluss drüber geben. zeig mal dein programm, dann kann man mehr dazu sagen.
ich werde es morgen mal hochladen :) leider kann ich mir die sxc flag nicht anzeigen lassen, bzw bascom will es mir nicht anzeigen ... naja wie gesagt, ich lade das programm morgen mal hoch
Hallo, ich habe das Programm nochmal als anhang eingefügt.
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.