PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : servo-befehl in interrupt-routine funzt nicht



Che Guevara
28.02.2009, 15:58
hallo leute,

aus einer "spielerei" ist jetzt die idee entstanden, folgendes zu verwirklichen:

ein "roboter" fährt geradeaus und sobald er ein hindernis bemerkt bleibt er stehen. vorne befindet sich ein servo, auf welchem ein us-sensor befestigt ist.
im normalfall ist der us-sensor gerade nach vorne ausgerichtet. wenn ein hindernis detektiert wird, soll sich der servo nach links drehen, schauen, ob dort auch ein hindernis ist, dann nach rechts und dort auch wider schauen, ob ein hindernis vorhanden ist.
dann soll entschieden werden, wie ausgewichen wird (nach links, nach rechts, zurück und dann nach links, usw.)

das programm möchte ich schritt für schritt aufbauen. jetzt hänge ich allerdings fest:



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

Declare Sub Serv(byref Wert As Byte)
Declare Sub Ausweichen(byref Abstand_1 As Byte , Byref Abstand_2 As Byte , Byref Abstand_3 As Byte)

Config Servos = 1 , Servo1 = Portb.0 , Reload = 10
Config Portb.0 = Output

Config Int0 = Falling
Enable Int0
On Int0 Isr_von_int0

Config Pind.2 = Input
Portd.2 = 1

Waitms 200

Enable Interrupts

Servo(1) = 150

Dim Wert As Byte
Dim Abstand_1 As Byte
Dim Abstand_2 As Byte
Dim Abstand_3 As Byte

Abstand_1 = 0
Abstand_2 = 0
Abstand_3 = 0

Config Portc.0 = Output
Config Portc.1 = Output
Portc.0 = 1
Portc.1 = 1

Config Portc.2 = Output
Portc.2 = 1

Do

!nop

Loop

End

Isr_von_int0:
If Pind.2 = 0 Then Abstand_1 = 1
Wert = 100
Call Serv(wert)
Wait 1
If Pind.2 = 0 Then Abstand_2 = 1
Wert = 200
Call Serv(wert)
Wait 1
If Pind.2 = 0 Then Abstand_3 = 1
Wert = 150
Call Serv(wert)
Wait 1
Call Ausweichen(abstand_1 , Abstand_2 , Abstand_3)
Abstand_1 = 0
Abstand_2 = 0
Abstand_3 = 0
Return

Sub Serv(byref Wert As Byte)
Servo(1) = Wert
Toggle Portc.2
End Sub

Sub Ausweichen(byref Abstand_1 As Byte , Byref Abstand_2 As Byte , Byref Abstand_3 As Byte)
If Abstand_1 = 1 And Abstand_2 = 1 And Abstand_3 = 1 Then
Toggle Portc.0
Else
Toggle Portc.1
End If
End Sub


bei diesem code hänge ich fest. in der isr_von_int0 bewegt sich der servo nicht!
die sub serv ist nur da, weil ich zuerst dachte, das in einer interrupt-routine der servo befehl nicht funzt, allerdings war meine annahme falsch, habs mit einem anderen programm herausgefunden, dass das doch geht!!

warum bewegt sich der servo in der routine nicht??

schon mal danke im vorraus

gruß
chris

p_mork
28.02.2009, 18:49
Hallo Chris,

das Servo-Ansteuerung wird in Bascom dadurch realisiert, dass da ein Timer in gewissen Zeitabständen einen Interrupt auslöst und in der ISR die Signale für die Servos generiert. Nun sind aber die Interrupts in einer ISR (und damit auch in deiner INT0-ISR) gesperrt, weshalb die ISR vom Timer für die Servoansteuerung nicht angesprungen wird und das Servo keine Signale erhält.

Normaleweise löst man dieses Problem, indem man in der ISR nur einen Flag setzt und nichts direkt macht. Im Hauptprogramm wird dann ständig dieses Flag abgefragt und wenn es gesetzt sein sollte, wird eben das entsprechende ausgeführt.

MfG Mark