Forum: Mikrocontroller und Digitale Elektronik hilfe! Bascom/UART-Interrupt hängt


von Gast (Gast)


Lesenswert?

Hallo,
ich hab ein problem mit meinem bascom program. Ich sende dem µc über den 
uart zB einen String wie L12crfl. die 12 soll in eine variable übergeben 
werden und zunächst eien servo steuern. das ganze haut auch hin aber nur 
ein mal!? danach hängt das programm in der hauptschleife fest?! warum 
löst der interrupt nur einmal aus?
Ich wäre für jede hilfe dankbar
hier der code:
----------------------------------------------------------
$regfile = "m8def.dat"
$crystal = 3686400
$baud = 9600

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

On Urxc Onrxd
Enable Urxc
Enable Interrupts

Dim Dat As Byte
Dim Lr As String * 1
Dim Inputstr As String * 6
Dim Ml As String * 6
Dim Mr As String * 6
Config Servos = 2 , Servo1 = Portc.0 , Servo2 = Portc.1 , Reload = 10

Inputstr = ""

Main:
        Servo(1) = Ml * 10
        Servo(2) = Mr * 10
        Print Ml ; Mr
Goto Main


Onrxd:
Do                                                          'interrupt 
bei
   If Usr.rxc = 1 Then
   Inputstr = Inputstr + Chr(udr)
   If Udr = 13 Then Goto Lor
   End If
Loop
Return

Lor:
Print Inputstr
Lr = Left(inputstr , 1)                                     'L oder R ?
   Select Case Lr
      Case "L"
      Goto L

      Case "R"
      Goto R
   End Select
Goto Main

L:                                                 'wert auslesen
   Ml = Right(inputstr , 3)
   Ml = Left(ml , 2)
   Print Ml
Goto Main

R:
   Mr = Right(inputstr , 3)
   Mr = Left(mr , 2)
   Print Mr
Goto Main

von STK500-Besitzer (Gast)


Lesenswert?

Du musst deinen Inputstr nach dem Bearbeiten "leeren".

von Gast (Gast)


Lesenswert?

joa das macht sinn, kann ich das so machen?

inputstr = ""

vielen dank schonmal

von Gast (Gast)


Lesenswert?

hab jetzt inputstr = "" in die main schleife eingefügt und in die L und 
R, aber er hängt sich immernoch auf............

von Gast (Gast)


Lesenswert?

ich glaube es liegt daran dass ich das return des interrupts nie 
erreiche; ich wüsste jetzt aber gar nicht wie ich das machen sollte, 
schließlich soll bei "enter" gesprungen werden. jemand ne idee?

von Michael U. (amiga)


Lesenswert?

Hallo,

was soll das werden?
   If Udr = 13 Then Goto Lor

Das Ende der Interruptroutine ist Return und nur Return.
Du solltest Dich mit der Funktion von Interrupts befassen,
auch BasCom dürfte erst mit Return ein RETI machen und damit die 
Interrupts wieder freigeben...

Wie bei "enter" reagiert wird, ist ein Problem der Hauptschleife, die 
Interruptroutine hat nur die Zeichen an den String anzuhängen und weiter 
nichts.

Gruß aus Berlin
Michael

von Axel R. (Gast)


Lesenswert?

die ganzen "GoTo's"...

da fehlt immer ein "Return" an passender Stelle.

Print im USART Interrupt ist auch irgentwie nich richtig

----------------------------------------------------------
$regfile = "m8def.dat"
$crystal = 3686400
$baud = 9600

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

On Urxc Onrxd
Enable Urxc
Enable Interrupts

Dim rechtslinks as Byte
Dim Dat As Byte
Dim Lr As String * 1
Dim Inputstr As String * 6
Dim Ml As String * 6
Dim Mr As String * 6
Config Servos = 2 , Servo1 = Portc.0 , Servo2 = Portc.1 , Reload = 10

Inputstr = ""
rechtslinks = 0
Main:
        Servo(1) = Ml * 10
        Servo(2) = Mr * 10
           Select Case (rechtslinks)
             Case 1
             Print Inputstr
             Case 2
             Print M1
             Case 3
             Print Mr
           End Select
        rechtslinks = 0
Print Ml ; Mr
Goto Main


Onrxd:
                                           'interrupt bei
   Inputstr = Inputstr + Chr(udr)
   If Udr = 13 Then Goto Lor

Return

Lor:
rechtslinks = 1
'Print Inputstr
Lr = Left(inputstr , 1)                        'L oder R ?
   Select Case Lr
      Case "L"
      Goto L

      Case "R"
      Goto R
   End Select
Return


L:                                                 'wert auslesen
   Ml = Right(inputstr , 3)
   Ml = Left(ml , 2)
   'Print Ml
   rechtslinks = 2
Return


R:
   Mr = Right(inputstr , 3)
   Mr = Left(mr , 2)
rechtslinks = 3
'Print Mr
Return

von Michael U. (amiga)


Lesenswert?

Hallo,

naja, irgendwie stimmt die ganze Struktur nicht.

In der IRQ-Routine nur:

Onrxd:
                                           'interrupt bei
   Inputstr = Inputstr + Chr(udr)
   If Udr = 13 Then Flag = true            ' Flag setzen, daß "enter" 
kam

Return

Main:

IF FLAG = true
  den Krempel zur Auswertung hier rein
  flag = false 'Flag hier zurücksetzen wenn fertig bearbeitet.
ENDIF

und der Rest
...
Goto Main

Sorry, benutze kein Bascom, Syntax ist nur Beispiel...

Ich wprde in der IRQ-Routine auch als erstes den Flag-Zustand abfragen 
und den Strin nur erweitern, wenn der vorige fertig bearbeitet wurde, 
sonst den Inhalt von UDR eben wegwerfen.
Das ist aber dann die nöchste Baustelle. ;)

Interrupt-Routinen so kurz wie möglich, Bearbeitung im Hauptprogramm 
sollte mit Sicherheit auch bei Bascom Beachtung finden.

Gruß aus Berlin
Michael

von Gast (Gast)


Lesenswert?

sieht interressant aus, ich probier mal das ganze in eine ähnliche 
struktur zu bringen....
vielen dank

von Michael U. (amiga)


Lesenswert?

Hallo,

ich benutze (in ASM) meist solche einfachen Semaphoren-Strukturen.
Komplett wird es dann etwa so:

Onrxd:
   if flag = true ' letzter Event noch nicht bearbeitet!!!
     error = true ' Fehler, es gingen Daten verloren...
     dummy = UDR  ' Daten abholen und wegwerfen, damit der IRQ nicht 
hängenbleibt
   else
     Inputstr = Inputstr + Chr(udr)
     If Udr = 13 Then Flag = true            ' Flag setzen, daß "enter"
   endif
kam

Return

Beim UART kann man natürlich auch die Flags auswerten, bei anderen 
Sachen, wo ich nicht sicher bin, ob mein Konstrukt in der verfügbaren 
Zeit fertig wird, hat es mir aber schon oft bei der Fehlersuche 
geholfen...

Natürlich muß die Hauptroutine sich noch um das Fehlerflag kümmern.

Alles nur als Anregung zu verstehen.

Gruß aus Berlin
Michael

von Gast (Gast)


Lesenswert?

so das interrupt problem ist gelöst, aber nach einigen sekunden hängt 
sich das programm wieder auf.es bringt wohl die strigs durcheinander.wie 
kann ich denn ein string auf seine richtigkeit überprüfen? ich sende zb:
R13CR
L05CR
R15CR
L09CR
.
.
.

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.