PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programm-Ablauf wird nicht eingehalten.



RobbyMartin
11.06.2011, 13:45
Hallo,

ich habe folgendes Programm:


$regfile = "M48def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 10
$framesize = 40
Dim Zeitpunkt As Word
Dim A As Byte
Zeitpunkt = 0

'Servo
Config Servos = 1 , Servo1 = Portb.1 , Reload = 10
Config Portb.1 = Output


'Pumpe 1 an PD7
Pumpe1 Alias Portd.5
Config Pumpe1 = Output

'Motor Stauchen an PD6
Stauchen Alias Portd.6
Config Stauchen = Output

'Motor Streckenan PD7
Streckenalias Portd.7
Config Strecken = Output

'Pumpe 2 an PB0
Pumpe2 Alias Portb.0
Config Pumpe2 = Output

'TASTER 1 an PD2
Taster1 Alias Pind.2
Config Pind.2 = Input
Portd.2 = 1

'Taster 2 an PD3
Taster2 Alias Pind.3
Config Pind.3 = Input
Portd.3 = 1

On Int0 Zweiter
On Int1 Erster
Config Int0 = Falling
Config Int1 = Falling
Enable Int0
Enable Int1
Enable Interrupts
Servo(1) = 60
Pumpe1 = 1 : Pumpe2 = 0
Do

Loop

Zweiter:
Strecken = 0 : Stauchen = 0 : Servo(1) = 40
Pumpe1 = 1 : Pumpe2 = 1
Waitms 1000
Pumpe1 = 0 : Pumpe2 = 1
Waitms 2000
Strecken = 1 : Stauchen = 0

Return

Erster:

Strecken = 0 : Stauchen = 0 : Servo(1) = 50
Pumpe1 = 1 : Pumpe2 = 1
Waitms 1000
Pumpe1 = 1 : Pumpe2 = 0
Waitms 2000
Strecken = 0 : Stauchen = 1

Return
ReturnMein Problem liegt darin, das in den beiden Interrupt-Routinen beide Motoren 0 sein sollen und gelichzeitig der Servo eine Position abfahren soll.
Doch dies tut das Programm leider nicht.

Eigentlich müsste passieren:
Stecken + Stauchen = 0 -> Korrekt
Servo = Position anfahren -> macht er aber leider erst zum Schluss:(
pumpen mit Pausen
Strecken bzw Stauchen

Der Servo bewegt sich erst wieder wenn, Strecken und Stauchen = 1 bzw. 0 ist.:(
Woran dies liegt kann ich mir leider nicht erklären hoffentlich habt ihr eine Lösung zu meinem Problem

Über Antworten würde ich mich sehr freuen :rolleyes:

Gruß
Martin

Searcher
11.06.2011, 14:41
Hallo,
in der BASCOM - help steht "The CONFIG SERVOS directive will set up a byte array with the servo pulse width values and will initialize an ISR that uses TIMER0".
Das bedeutet, das BASCOM selber ISR benutzt um den Servo laufen zu lassen.

Du rufst SERVO(x) in Deiner ISR auf - damit sind andere ISR für die Dauer Deiner ISR gesperrt. Servo kann nicht loslaufen. Außerdem hast Du da noch WAITs drin, die Deine ISR noch länger andauern läßt.

ISR sollen so schnell wie möglich abgearbeitet werden können!

Also in Deiner ISR zB ein Flag setzen, daß ein INT aufgetreten ist und dann Flagabfrage und den Rest in der Hauptschleife zwischen do und loop machen.

Da gibt es noch ein alias Schreibfehler:

'Motor Streckenan PD7
Streckenalias Portd.7
Config Strecken = OutputGruß
Searcher

RobbyMartin
11.06.2011, 15:10
Vielen Dank Searcher,;)

der Tippfehler wurde seltsamer Weise nie bemängelt und es hat auch mit Tippfehlergeklappt "Komisch;)"

Das klingt logisch was du erzählst mit den ISR.

Leider habe ich noch nie etwas mit Flags gemacht. Ich versuche mal was darüber herauszufinden. Kannst du mir evt ein Beispiel geben?

Gruß
Martin

RobbyMartin
11.06.2011, 15:24
$regfile = "M48def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 10
$framesize = 40
Dim Flag As Word
Flag = 2

'Servo
Config Servos = 1 , Servo1 = Portb.1 , Reload = 10
Config Portb.1 = Output


'Pumpe 1 an PD7
Pumpe1 Alias Portd.5
Config Pumpe1 = Output

'Motor Stauchen an PD6
Stauchen Alias Portd.6
Config Stauchen = Output

'Motor Streckenan PD7
Strecken Alias Portd.7
Config Strecken = Output

'Pumpe 2 an PB0
Pumpe2 Alias Portb.0
Config Pumpe2 = Output

'TASTER 1 an PD2
Taster1 Alias Pind.2
Config Pind.2 = Input
Portd.2 = 1

'Taster 2 an PD3
Taster2 Alias Pind.3
Config Pind.3 = Input
Portd.3 = 1

On Int0 Zweiter
On Int1 Erster
Config Int0 = Falling
Config Int1 = Falling
Enable Int0
Enable Int1
Enable Interrupts
Servo(1) = 60
'Pumpe1 = 1 : Pumpe2 = 0
Do
If Flag = 1 Then
'Servo(1) = 40
'Pumpe1 = 1 : Pumpe2 = 1
'Waitms 1000
'Pumpe1 = 0 : Pumpe2 = 1
'Waitms 2000
Strecken = 1 : Stauchen = 0

Elseif Flag = 0 Then
'Servo(1) = 50
'Pumpe1 = 1 : Pumpe2 = 1
'Waitms 1000
'Pumpe1 = 1 : Pumpe2 = 0
'Waitms 2000
Strecken = 0 : Stauchen = 1
End If
Loop

Zweiter:
Strecken = 0 : Stauchen = 0
Flag = 1

Return

Erster:

Strecken = 0 : Stauchen = 0
Flag = 0

Return
Return

nun habe ich es so gemacht doch leider bleibt der Vorschub an einem ende stehen und kommt bewegt sich nicht zurück

Gruß
Martin

Searcher
11.06.2011, 15:32
Hallo Martin,
hier mal ein Stück Code aus einem meiner Programme. Komplettes Programm hier:
https://www.roboternetz.de/community/entry.php?50-TT-als-Linienfolger



On Pcint0 Set_rc5_flag 'ISR wenn Pin Change Int. Flag von PB3 TSOP kommt

Enable Interrupts 'Interrupts generell erlauben


Do 'Hauptschleife
If Average_speed <> 0 Then Power Adcnoise 'Wenn PWM eingeschaltet dann Sensoren messen
'im noise reduction mode des µC
'hier könnte sich noch ein Bug verstecken, da man nach Datenblatt vorher sicherstellen soll, daß keine Messung läuft

If Rc5_flag = 1 Then 'nach interrupt durch TSOP
Gosub Get_rc5 'lies RC5 CMD
Rc5_flag = 0
Pcmsk = Pcmsk Or &B00001000 'enable interrupts von PB3 (disabled in ISR)
End If
Loop


Set_rc5_flag: 'ISR Pin Change interrupt durch tsop - setzt flag
Pcmsk = Pcmsk And &B11110111 'disable weitere interrupts von PB3
Rc5_flag = 1
Return


In der Hauptschleife, die ja ständig durch do.. loop ausgeführt wird, wird das flag mit zB "if rc5_flag = .." abgefragt und entsprechend reagiert. Nicht vergessen, das flag wieder zurückzusetzen.



Gruß
Searcher

RobbyMartin
11.06.2011, 16:39
Danke Searcher,

Wiedereinmal ein wenig schlauer geworden. ;)

jetzt funktioniert es Wunderbar :)

Gruß
Martin