Forum: Mikrocontroller und Digitale Elektronik Problem mit Waitkey und serialcharmatch


von Martin B. (gixxer)


Lesenswert?

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
von troll (Gast)


Lesenswert?

Bascom?

von Martin B. (gixxer)


Lesenswert?

Ja mit Bascom :)

von Tim Taler (Gast)


Lesenswert?

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

von Martin B. (gixxer)


Lesenswert?

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...

von Weingut P. (weinbauer)


Lesenswert?

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.

von Martin B. (gixxer)


Angehängte Dateien:

Lesenswert?

so ich hab jetzt mal den Code als .txt datei angehängt, vlt hilft das ja 
bei der Fehlersuche ;)..

vielen dank schonmal im vorraus.

von Weingut P. (weinbauer)


Lesenswert?

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 :)

von Martin B. (gixxer)


Lesenswert?

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

von Weingut P. (weinbauer)


Lesenswert?

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"

von Martin B. (gixxer)


Lesenswert?

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

von weinbauer (Gast)


Lesenswert?

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.

von Martin B. (gixxer)


Lesenswert?

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?

von weinbauer (Gast)


Lesenswert?

disable urxc
waitkey
enable urxc

von Martin B. (gixxer)


Lesenswert?

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

von Weingut P. (weinbauer)


Lesenswert?

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.

von Martin B. (gixxer)


Lesenswert?

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

von Martin B. (gixxer)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.