PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Sprung zw. Haupt- und Subroutine



SlimJim1988
25.06.2009, 20:33
hay leutz,

ich versuch mich seit ca 3 wochen an nem atmel32 in bascom. ich habe mir eine pc-tastatur an meinen atmel angeschlossen. nun versuche ich mittels 2 tasten der tastatur zwischen meinem hauptprogramm und einer subroutine hin- und her zuspringen. das ganze lasse ich mir dann mit nem display anzeigen. allerding muss ich die jeweilige taste ca 1 sekunde lang drücken bis etwas auf dem display passiert. ich hoffe mir kann jmd behilflich sein.
danke schonmal.



$regfile = "m32def.dat"
$crystal = 16000000

Config Keyboard = Pinb.1 , Data = Pinb.2 , Keydata = Keydata

Dim Key As Byte

Declare Sub Test() As Byte


Config Portb.0 = Output
Led Alias Portb.0

'LCD Config
Config Lcdpin = Pin , Rs = Portd.0 , E = Portd.1 , Db4 = Portd.2 , Db5 = Portd.3 , Db6 = Portd.4 , Db7 = Portd.5
Config Lcd = 20 * 2
Config Lcdbus = 4
Initlcd
Cls
Cursor On


Main:

Do

Led = 1
Locate 1 , 1
Lcd "Main"

Key = Getatkbd()
If Key = 119 Then 'w
Call Test()
End If

Loop

End


Sub Test()

Do

Key = Getatkbd()
If Key = 113 Then 'q
Goto Main

End If
Loop


End Sub


'scan code übersetzungstabelle

Keydata:
'normal keys lower case
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , &H5E , 0
Data 0 , 0 , 0 , 0 , 0 , 113 , 49 , 0 , 0 , 0 , 122 , 115 , 97 , 119 , 50 , 0
Data 0 , 99 , 120 , 100 , 101 , 52 , 51 , 0 , 0 , 32 , 118 , 102 , 116 , 114 , 53 , 0
Data 0 , 110 , 98 , 104 , 103 , 121 , 54 , 7 , 8 , 44 , 109 , 106 , 117 , 55 , 56 , 0
Data 0 , 44 , 107 , 105 , 111 , 48 , 57 , 0 , 0 , 46 , 45 , 108 , 48 , 112 , 43 , 0
Data 0 , 0 , 0 , 0 , 0 , 92 , 0 , 0 , 0 , 0 , 13 , 0 , 0 , 92 , 0 , 0
Data 0 , 60 , 0 , 0 , 0 , 0 , 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0
Data 48 , 44 , 50 , 53 , 54 , 56 , 0 , 0 , 0 , 43 , 51 , 45 , 42 , 57 , 0 , 0

'shifted keys UPPER case
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
Data 0 , 0 , 0 , 0 , 0 , 81 , 33 , 0 , 0 , 0 , 90 , 83 , 65 , 87 , 34 , 0
Data 0 , 67 , 88 , 68 , 69 , 0 , 35 , 0 , 0 , 32 , 86 , 70 , 84 , 82 , 37 , 0
Data 0 , 78 , 66 , 72 , 71 , 89 , 38 , 0 , 0 , 76 , 77 , 74 , 85 , 47 , 40 , 0
Data 0 , 59 , 75 , 73 , 79 , 61 , 41 , 0 , 0 , 58 , 95 , 76 , 48 , 80 , 63 , 0
Data 0 , 0 , 0 , 0 , 0 , 96 , 0 , 0 , 0 , 0 , 13 , 94 , 0 , 42 , 0 , 0
Data 0 , 62 , 0 , 0 , 0 , 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0 , 0
Data 48 , 44 , 50 , 53 , 54 , 56 , 0 , 0 , 0 , 43 , 51 , 45 , 42 , 57 , 0 , 0

uwegw
25.06.2009, 21:28
Nie, Nie, Nie mit goto aus ner Subroutine woandershin springen!!! Irgendwann läuft dir so der Stack über. Goto ist in 99,9% der Fälle, in denen es verwendet wird, falsch.

Was willst du an der Stelle mit dem goto main bewirken? Doch wohl, dass die Subroutine sofort verlassen und das Programm an der Stelle hinter dem Sub-Aufruf weiter ausgeführt wird. Also 'EXIT SUB' verwenden!

SlimJim1988
25.06.2009, 22:01
erstmal danke für deine antwort.

ich wollte sozusagen bei erfüllter bedingung vom hauptprogramm in die subroutine springen. diese wollte ich dann mittels loop solange ausführen lassen bis die bedingung für einen rücksprung zum hauptprogramm erfüllt ist.

kurz: ich will, das sich nicht immer das komplette programm abspult sondern immer nur der teil der gerade gebraucht wird. und meine idee war halt das ganze mit subroutinen zu realisieren.

problem is halt eigentlich nur das es ca eine sekunde dauert bis etwas passiert. und das ist meiner ansicht nach eindeutig zu lange.

mfg SlimJim1988

for_ro
25.06.2009, 22:51
Dann sollte die Sub eher so aussehen:


Sub Test()
Do
Key = Getatkbd()
Loop Until Key=113
End Sub

Gruß

Rolf

SlimJim1988
26.06.2009, 15:40
danke, das hat mir schon etwas weitergeholfen.

kannst du mir bitte erklären worin der praktische unterschied zwischen deiner sub und meiner besteht?



aus der sub komm ich jetzt wunderbar schnell raus. aber wenn ich die sub aufrufe dauert es leider immer noch die besagte sekunde bis sich etwas tut.
hat noch jmd ne idee was das programm so langsam macht?

for_ro
26.06.2009, 16:47
danke, das hat mir schon etwas weitergeholfen.

kannst du mir bitte erklären worin der praktische unterschied zwischen deiner sub und meiner besteht?

Wie Uwe schon geschrieben hat, geht ein Goto raus aus einer SUB überhaupt nicht, weil dann der Stack nicht gepopt wird. Ein GOTO an sich ist schon schlechter Stil und fast immer überflüssig.
Aber: Es ist meistens die schnellste Möglichkeit.

Bzgl. der Geschwindigkeit sehe ich im Moment nur den GetATKbd Befehl, den ich wohl in der Simulation nicht ausführen kann. Dabei nehme ich an, dass du das Programm tatsächlich auf deinem Controller laufen lässt.

Gruß

Rolf

SlimJim1988
26.06.2009, 19:59
Wie gesagt ich bin halt noch am Anfang und probiere noch viel aus, auch wegen der Befehle und so. Ich habe das Programm in der Sub geändert:

Do
Key = Getatkbd()
Loop Until Key = 113

Wie ich schon sagte funktioniert der Sprung aus der Sub in das Hauptprogramm jetzt schon bei einem kurzen Tastenanschlag. Anders herum leider noch nicht. Bei einem Sprung vom Hauptprogramm in die Sub, muss ich die Taste ca ne Sekunde drücken, bevor etwas passiert. Und so riesig ist der Code ja nicht das der Chip ne Sekunde braucht um durchzulaufen.

Das Programm lasse ich direkt auf dem Microcontroller laufen.
Verwendete Hardware: Atmel32, PC-Tastatur, LCD-Display


Geänderter Code:


$regfile = "m32def.dat"
$crystal = 16000000

Config Keyboard = Pinb.1 , Data = Pinb.2 , Keydata = Keydata

Dim Key As Byte

Declare Sub Test() As Byte


Config Portb.0 = Output
Led Alias Portb.0

'LCD Config
Config Lcdpin = Pin , Rs = Portd.0 , E = Portd.1 , Db4 = Portd.2 , Db5 = Portd.3 , Db6 = Portd.4 , Db7 = Portd.5
Config Lcd = 20 * 2
Config Lcdbus = 4
Initlcd
Cls
Cursor On


Main:

Do

Led = 1
Locate 1 , 1
Lcd "Main"

Key = Getatkbd()
If Key = 119 Then 'w
Call Test()
End If

Loop

End


Sub Test()

Led = 0
Locate 1 , 1
Lcd "test"
Do
Key = Getatkbd()
Loop Until Key = 113

End Sub



'scan code übersetzungstabelle

Keydata:
'normal keys lower case
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , &H5E , 0
Data 0 , 0 , 0 , 0 , 0 , 113 , 49 , 0 , 0 , 0 , 122 , 115 , 97 , 119 , 50 , 0
Data 0 , 99 , 120 , 100 , 101 , 52 , 51 , 0 , 0 , 32 , 118 , 102 , 116 , 114 , 53 , 0
Data 0 , 110 , 98 , 104 , 103 , 121 , 54 , 7 , 8 , 44 , 109 , 106 , 117 , 55 , 56 , 0
Data 0 , 44 , 107 , 105 , 111 , 48 , 57 , 0 , 0 , 46 , 45 , 108 , 48 , 112 , 43 , 0
Data 0 , 0 , 0 , 0 , 0 , 92 , 0 , 0 , 0 , 0 , 13 , 0 , 0 , 92 , 0 , 0
Data 0 , 60 , 0 , 0 , 0 , 0 , 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0
Data 48 , 44 , 50 , 53 , 54 , 56 , 0 , 0 , 0 , 43 , 51 , 45 , 42 , 57 , 0 , 0

'shifted keys UPPER case
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
Data 0 , 0 , 0 , 0 , 0 , 81 , 33 , 0 , 0 , 0 , 90 , 83 , 65 , 87 , 34 , 0
Data 0 , 67 , 88 , 68 , 69 , 0 , 35 , 0 , 0 , 32 , 86 , 70 , 84 , 82 , 37 , 0
Data 0 , 78 , 66 , 72 , 71 , 89 , 38 , 0 , 0 , 76 , 77 , 74 , 85 , 47 , 40 , 0
Data 0 , 59 , 75 , 73 , 79 , 61 , 41 , 0 , 0 , 58 , 95 , 76 , 48 , 80 , 63 , 0
Data 0 , 0 , 0 , 0 , 0 , 96 , 0 , 0 , 0 , 0 , 13 , 94 , 0 , 42 , 0 , 0
Data 0 , 62 , 0 , 0 , 0 , 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0 , 0
Data 48 , 44 , 50 , 53 , 54 , 56 , 0 , 0 , 0 , 43 , 51 , 45 , 42 , 57 , 0 , 0


Ich freue mich über jede art von Hilfe!

MFG SlimJim1988

for_ro
26.06.2009, 20:15
Wenn der die Sub sofort verlässt, kann es auch nicht an der Ausführungszeit des getatkbd liegen.
In der Main gibst du ja auch noch bei jedem Loop das Wort Main aufs LCD.
Probier doch mal so:


Main:
Do
Led = 1
Locate 1 , 1
Lcd "Main"
Do
Key = Getatkbd()
Loop Until Key = 119 'w
Call test
Loop

End

Sub Test()
Led = 0
Locate 1 , 1
Lcd "test"
Do
Key = Getatkbd()
Loop Until Key = 113
End Sub

Gruß

Rolf

Klingon77
26.06.2009, 22:28
hi,

ich bin zwar ein Frischling in Bascom; mache aber bei Problemen folgendes:

Zwei Variablen vor die DO-LOOP Schleife, welche dann in der Schleife hochgezählt wird und über das LCD ausgegeben wird.

Ein Befehl wird durch Varible 1 und Variable 2 "eingerahmt".

Je nachdem wo ich die Zählvariable inkrementiere und ausgebe kann ich den Befehl, welcher die Verzögerung verursacht lokalisieren.



Die Permanente Ausgabe auf dem LCD bei jedem Durchlauf benötigt schon viel Zeit; eine Sekunde ist aber definitiv zu lange.


liebe Grüße,

Klingon77

SlimJim1988
27.06.2009, 08:39
Erstmal danke ich allen die versucht haben mir zu helfen.

@for_ro

Dein Code klappt wunderbar. Kannst du mir evt erklären was dein Code anders macht als meiner? Lags an den IF-Abfragen, das es so langsam reagiert hat? Und was mache ich wenn ich vom Hauptprogramm in mehrere Subs verweisen möchte?

MFG SlimJim1988

for_ro
27.06.2009, 11:19
Kannst du mir evt erklären was dein Code anders macht als meiner?

LCD Ausgaben brauchen ihre Zeit. In deiner Do..Loop wird bei jedem Umlauf d die Variable Led auf 1 gesetzt, das LCD auf die erste Stelle in der ersten zeile positioniert und dann der Text "Main" ausgegeben. Und das, obwohl sich in der Zwischenzeit ja gar nichts geändert hat. Wenn du zu schnell auf das LCD schreiben willst, wird der Text nicht mehr gut lesbar. Du solltest versuchen, dass so zu ändern, dass nur geschrieben wird, wenn es etwas neues anzuzeigen gibt.

Wenn du also eine Do..Loop hast, in der praktisch auf die nächste Eingabe gewartet wird, dann sollte diese nur über den GetAtKbd Befehl laufen. Ich nehme an, dass der Befehl 0 zurückliefert, wenn keine Taste gedrückt wurde. Dann würde ich das etwa so machen:

Do
Key = GetAtKbd()
Loop Until Key > 0

Jetzt kommt die Auswertung von Key. Da das Programm die Schleife nur verlassen kann, wenn eine Taste gedrückt wurde, kannst du nun z.B. über ein Select..Case oder auch mehrere Ifs ein entsprechende Aktion ausführen. Dies muss nicht unbedingt in einer Sub ablaufen, kann es aber.
Also etwa so:

Select Case Key
Case 119: Call Test
Case 125: Befehle
End Select

In den Subs führst du dann die gewünschten Aktionen aus, evtl. inklusive einer Anzeige aud dem LCD. Sorge nur dafür, dass nicht zu schnell aufs LCD geschrieben wird.

Gruß

Rolf