- Labornetzteil AliExpress         
Ergebnis 1 bis 7 von 7

Thema: UART, zeitlicher Ablauf Subprogramme

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    27.10.2008
    Beiträge
    50

    UART, zeitlicher Ablauf Subprogramme

    Anzeige

    Praxistest und DIY Projekte
    Hallo
    ich habe ein kleines Verständnisproblem, wobei mir Mr Google und Tante SuFu auch nicht helfen konnten.

    Es geht um die Reihenfolge in der das Main und die Sub ablaufen.

    Folgende Konstellation:
    Über die UART kommen Nachrichten rein die mit CR enden. In der Main loop wird das erste Zeichen der Nachricht per if-Schleife ausgewertet und danach in die jeweiligen Sub gesprungen.

    Frage 1.
    Wenn ich das bisher richtig verstanden habe wird die Main-Loop immer wieder ausgeführt , sie macht also so lange keine neues Telgramm kommt immer wider die Verarbeitung der alten Nachricht.
    Sinnvoll ist das bestimmt nicht, wäre es denn schädlich ?
    Kann man das sinnvoll verhindern

    Frage 2
    Wie und in welcher zeitlichen Reihefolge werden die Subs bearbeitet und wie wirkt sich das aus:
    Folgendes Beispiel:
    Es kommen 2 Nachrichten direkt hintereinander rein, die den gleichen Nachrichtenkenner haben also in die gleiche subroutine laufen

    Beispiel
    Nachricht 1 kommt herein. durch das CR wird die Sub für die UART angsprochen. die ändert den Inhalt der Variabelen für den nachrichten inhalt, die Mainloop verzweigt in die subroutine mit byval wird das telegramm für die Routine für das sub mit übergeben. Die Subroutine fängt an zu arbeiten.
    Während die subroutine noch arbeitet wird die direkt folgende nachricht mit cr abgeschlossen.
    Sie ändert damit die variabele für die nachricht

    Code:
    Sub Serial0charmatch()
    Input Telegramm Noecho
    End Sub Serial0charmatch()
    und dann ?????

    A: Geht es dann in der unterbrochenen Subroutine weiter, bis diese abgearbeitet ist und springt dann in die Main-Loop zurück und stößt das gleiche Sub mit der neuen Variabelen an

    oder

    B: springt das Sub(mit dem input) in die Mainloop und würde dann damit eine nur halb verarbeitete 1. Nachricht hinterlassen.

    Wenn normalerweise Fall B eintritt, gibt es eine Möglichkeit es so zu machen, das es doch zu Fall a wird ?

    Das Thema ist bei mir halt besonders wichtig, da nicht nur alle Sekunde eine Nachricht kommt, sondern auch dazwischen und oft auch 2 Nachrichten direkt in Folge.
    (Ein bestimmter Event beim Sender führt zu 2 unterschiedlichen Nachrichten des gleichen Typs)

    Danke im voraus

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Hast Du mehr Code?

    Es lässt sich nicht pauschal sagen, dass die Mainloop ständig / immer wieder durchlaufen wird. Das passiert nur, wenn die subs auch wieder sauber zurückspringen.

    Serialcharmatch und Co nutze ich nicht. Ich arbeite immer mit ischarwaiting(). Für ein passendes Beispiel bräuchte ich mindestens deine Auswerteroutine.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    27.10.2008
    Beiträge
    50
    ja klar:

    Hier ein Ausschnitt

    Code:
    $regfile = "M32def.dat"
    $crystal = 4000000
    $hwstack = 32
    $swstack = 10
    $framesize = 40
    $baud = 9600
     
    Config Serialin = Buffered , Size = 60 , Bytematch = 013    ' Serielles Input
    'Ausgänge:
    Zeit_segmente Alias Portc.7                                 ' Ausgang für die Uhr
    Rennz Alias Portc.6                                         ' Ausgang für die verbleibende Restzeit
    Licht_5 Alias Portc.5                                       ' Ausgang für Lampe 5
    Licht_4 Alias Portc.4                                       ' Ausgang für Lampe 4
    Licht_3 Alias Portc.3                                       ' Ausgang für Lampe 3
    Licht_2 Alias Portc.2                                       ' Ausgang für Lampe 2
    Licht_1 Alias Portc.1                                       ' Ausgang für Lampe 1
    
    Do
    Ttyp = Mid(telegramm , 2 , 1)
    If Ttyp = Lebensz Then
    Call Zeit(telegramm)
    End If
    If Ttyp = Platzt Then
    Call Platz(telegramm)
    End If
     
    Loop
    End
     
    Sub Serial0charmatch()
    Input Telegramm Noecho
    End Sub Serial0charmatch()
     
    Zeit:
    Uz_std10 = Mid(telegramm , 5 , 1)
    Uz_std1 = Mid(telegramm , 6 , 1)
    Uz_min10 = Mid(telegramm , 7 , 1)
    Uz_min1 = Mid(telegramm , 8 , 1)
    Uz_sek10 = Mid(telegramm , 9 , 1)
    Uz_sek1 = Mid(telegramm , 7 , 1)
     
    If Uz_std10 = "0" Then
       Uz1 = Seg_array(10)
       Else
       Uz1 = Seg_array(uz_std10)
    End If
    If Uz_std1 = "0" Then
        Uz2 = Seg_array(10)
        Else
        Uz2 = Seg_array(uz_std1)
        End If
    If Uz_min10 = "0" Then
        Uz3 = Seg_array(10)
        Else
        Uz3 = Seg_array(uz_min10)
    End If
    If Uz_min1 = "0" Then
       Uz4 = Seg_array(10)
       Else
       Uz4 = Seg_array(uz_min1)
    End If
    If Uz_sek10 = "0" Then
       Uz5 = Seg_array(10)
       Else
       Uz5 = Seg_array(uz_sek10)
    End If
    If Uz_sek1 = "0" Then
       Uz6 = Seg_array(10)
       Else
       Uz6 = Seg_array(uz_sek1)
    End If
    LA1 = Mid(telegramm , 5 , 1)
    LA2 = Mid(telegramm , 6 , 1)
    LA3 = Mid(telegramm , 7 , 1)
    LA4 = Mid(telegramm , 8 , 1)
    LA5 = Mid(telegramm , 9 , 1)
    If LA1 = "1" Then
       Licht_1 = 1
       Else
       Licht_1 = 0
    End If
    If LA2 = "1" Then
       Licht_2 = 1
       Else
       Licht_2 = 0
    End If
    If LA3 = "1" Then
       Licht_3 = 1
       Else
       Licht_3 = 0
    End If
    If LA4 = "1" Then
       Licht_4 = 1
       Else
       Licht_4 = 0
    End If
    If LA5 = "1" Then
       Licht_5 = 1
       Else
       Licht_5 = 0
    End If
    Shiftout Data_channel , Clock_channel , Uz1
       Shiftout Data_channel , Clock_channel , Uz2
       Shiftout Data_channel , Clock_channel , Uz3
       Shiftout Data_channel , Clock_channel , Uz4
       Shiftout Data_channel , Clock_channel , Uz5
       Shiftout Data_channel , Clock_channel , Uz6
       Pulseout zeit_strobe_port , zeit_strobe_pin , 10000
    Return

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    27.10.2008
    Beiträge
    50
    erstmal danke peterfido
    hatte ich ganz vergessen.

    Habe mir mal das ISCHARWAITING angesehen.
    grundsätzlich wäre es glaube ich interessant weil ich die Nachricht im UART Puffer bleibt und ich diese nur dann abrufe, wenn ich auch die neue Nachricht verarbeiten kann.

    Allerdings ist immer die Rede von einem Zeichen. Bei mir sind es aber bis zu 60 Zeichen pro Nachricht.

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Irgendwie fehlt mir da was. Beispielcode sollte compilierfähig sein.


    Dein Code würde ich etwa so umsetzen (Fehlende Typen einfach angenommen, natürlich ungestestet)):
    Code:
    $regfile = "M32def.dat"
    $crystal = 4000000
    $hwstack = 32
    $swstack = 10
    $framesize = 40
    $baud = 9600
    
    Dim Position As Byte
    Dim B As Byte
    Dim Uz(6) As Byte
    Dim Telegramm(60) As Byte
    Dim Ttype As Byte At Telegramm + 1 Overlay
    Dim Uz_std10 As Byte At Telegramm + 4 Overlay               ' = Mid(telegramm , 5 , 1)
    Dim Uz_std1 As Byte At Telegramm + 5 Overlay                ' = Mid(telegramm , 6 , 1)
    Dim Uz_min10 As Byte At Telegramm + 6 Overlay               ' = Mid(telegramm , 7 , 1)
    Dim Uz_min1 As Byte At Telegramm + 7 Overlay                ' = Mid(telegramm , 8 , 1)
    Dim Uz_sek10 As Byte At Telegramm + 8 Overlay               ' = Mid(telegramm , 9 , 1)
    Dim Uz_sek1 As Byte At Telegramm + 9 Overlay                ' = Mid(telegramm , 7 , 1)
    
    La1 alias Uz_std10
    La2 Alias Uz_std1
    La3 Alias Uz_min10
    La4 Alias Uz_min1
    La5 Alias Uz_sek10
    
    Const Lebensz = 5                                           '???
    Const Platzt = 6                                            '???
    
    Dim Seg_array(10) As Byte                                   '???
    
    Config Serialin = Buffered , Size = 60                      ', Bytematch = 013    ' Serielles Input
    'Ausgänge:
    Zeit_segmente Alias Portc.7                                 ' Ausgang für die Uhr
    Rennz Alias Portc.6                                         ' Ausgang für die verbleibende Restzeit
    Licht_5 Alias Portc.5                                       ' Ausgang für Lampe 5
    Licht_4 Alias Portc.4                                       ' Ausgang für Lampe 4
    Licht_3 Alias Portc.3                                       ' Ausgang für Lampe 3
    Licht_2 Alias Portc.2                                       ' Ausgang für Lampe 2
    Licht_1 Alias Portc.1                                       ' Ausgang für Lampe 1
    
    Zeit_strobe_port Alias Portb                                '???
    Zeit_strobe_pin Alias 0                                     '???
    Data_channel Alias Portb.1
    Clock_channel Alias Portb.2                                 '???
    Do                                                          '???
       If Ischarwaiting() = 1 Then
          Gosub Empfangen
       End If
    
    
    Loop
    End
    
    Empfangen:
       B = Inkey()
       If B = 13 Then
          Gosub Auswerten
          Position = 0
       Else
          Incr Position
          Telegramm(position) = B
       End If
    
    
    Return
    
    Auswerten:
       If Ttype = Lebensz Then
         If Uz_std10 = 48 Then
            Uz(1) = Seg_array(10)
         Else
            Uz(1) = Seg_array(uz_std10)
         End If
         If Uz_std1 = 48 Then
             Uz(2) = Seg_array(10)
             Else
             Uz(2) = Seg_array(uz_std1)
             End If
         If Uz_min10 = 48 Then
             Uz(3) = Seg_array(10)
             Else
             Uz(3) = Seg_array(uz_min10)
         End If
         If Uz_min1 = 48 Then
            Uz(4) = Seg_array(10)
            Else
            Uz(4) = Seg_array(uz_min1)
         End If
         If Uz_sek10 = 48 Then
            Uz(5) = Seg_array(10)
            Else
            Uz(5) = Seg_array(uz_sek10)
         End If
         If Uz_sek1 = 48 Then
            Uz(6) = Seg_array(10)
            Else
            Uz(6) = Seg_array(uz_sek1)
         End If
    '     LA1 = Mid(telegramm , 5 , 1)
    '     LA2 = Mid(telegramm , 6 , 1)
    '     LA3 = Mid(telegramm , 7 , 1)
    '     LA4 = Mid(telegramm , 8 , 1)
    '     LA5 = Mid(telegramm , 9 , 1)
         If LA1 = 49 Then
            Licht_1 = 1
         Else
            Licht_1 = 0
         End If
         If La2 = 49 Then
            Licht_2 = 1
         Else
            Licht_2 = 0
         End If
         If La3 = 49 Then
            Licht_3 = 1
         Else
            Licht_3 = 0
         End If
         If La4 = 49 Then
            Licht_4 = 1
         Else
            Licht_4 = 0
         End If
         If La5 = 49 Then
            Licht_5 = 1
         Else
            Licht_5 = 0
         End If
         Shiftout Data_channel , Clock_channel , Uz(1)
         Shiftout Data_channel , Clock_channel , Uz(2)
         Shiftout Data_channel , Clock_channel , Uz(3)
         Shiftout Data_channel , Clock_channel , Uz(4)
         Shiftout Data_channel , Clock_channel , Uz(5)
         Shiftout Data_channel , Clock_channel , Uz(6)
         Pulseout Zeit_strobe_port , Zeit_strobe_pin , 10000
    
    
    
       Elseif Ttype = Platzt Then
          nop
       End If
    
    
    Return
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    27.10.2008
    Beiträge
    50
    Ersteinmal Danke für die Antwort

    Soorry wegen der nicht compilierfähigkeit.

    Da der Code bereits über 4k groß ist, wollte ich ihn nicht komplett einstellen.

    Kurz vorab.
    Es gibt 4 Verschiedene Nachrichten unterschieden werden sie am 2. Zeichen der Nachricht. Für jeden Nachrichtentyp hatte ich eine eigene Subroutine vorgesehen:
    die Typen sind Lebenszeichen ( L ) Platzierung ( P) Initialisierung (I) und Bestround (B). Dafür die Variabelen Platzt und Lebensz

    Const Lebensz = 5 '???
    Const Platzt = 6 '???

    Müsste es dann nicht so heißen:
    Const Lebensz = 76 ' Ascii Nummer für L
    Const Platzt = 80 'Ascii Nummer für P

    In jedem der Telegramme sind eine Reihe an Informationen enthalten.

    Hier am Beispiel L:
    Telegrammtyp, Aktuelle Uhrzeit; Restzeit, Lampe 1 an oder aus, Lampe 2 an oder aus,Lampe 3 an oder aus,Lampe 4 an oder aus,Lampe 5 an oder aus.

    Die variabelen Fangen deshalb bei mir auch so an:
    LA = Lampe
    UZ = Uhrzeit
    RZ = restzeit

    wen ich das richtig verstehe, hast du die String-Werte aus dem String durch deren ASCII Code nummer ersetzt.

    Das ist nicht ganz richtig, der Fehler liegt aber bei mir
    La2 Alias Uz_std1
    La3 Alias Uz_min10
    La4 Alias Uz_min1
    La5 Alias Uz_sek10
    Die Lampen haben keine Gemeinsamkeit mit den Uhrzeiten
    Aber da ich noch nicht ganz fertig bin und Teile des Protokolls noch in der Abstimmung sind, waren noch nicht alle Platzangaben in den Telegrammen richtig gesetzt.

    Zeit_strobe_port Alias Portb '???
    Zeit_strobe_pin Alias 0 '???
    Data_channel Alias Portb.1
    Clock_channel Alias Portb.2

    Insgesamt habe ich 13 Blöcke mit sieben Segement Anzeigen
    Alle 13 Blöcken hängen am gleichen Data out port und am gleichen Clock Port, der Strobe Port wird je Block gesetzt ( Uhrzeit und Restzeit sind ein block -> Zeit_Strobe)

    Dim Seg_array(10) As Byte '???
    Das ist das Array in dem steht welche 8 Binärzeichen für die Siebensegmentanzeige an die Schiebregister gesendet werden sollen.
    Quasi die Übersetzungsliste Dezimal-Zahl zu Siebensegmentanzeige. Da keine Nachgeschaltete Logik dahinter ist muss ich das hier im Programm machen.
    Glaube ich zumindest.

    Gruß Martin
    Ich habe hier gerade nicht den kompletten Code zur hand. Ich baue das ein und schreibe das nochmal hier.

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Klingt so, als ob Du meine Vorgehensweise erkannt hast.

    Wenn möglich, arbeite ich mit Overlays, was hier gut geht. Spart umkopiererei. "Strings" der Länge 1 werte ich normal als byte aus. Spart in dem Beispiel hier die ganzen MIDs. Zumal das Vergleichen von Strings mehr Zeit benötigt.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

Ähnliche Themen

  1. Programm-Ablauf wird nicht eingehalten.
    Von RobbyMartin im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 11.06.2011, 16:39
  2. Paralleler ablauf von Funktionen im ATMega 16 / 32?
    Von Henry im Forum C - Programmierung (GCC u.a.)
    Antworten: 10
    Letzter Beitrag: 16.07.2009, 17:52
  3. Ablauf des Programms sehr zögerlich...
    Von Black_Arrow im Forum PIC Controller
    Antworten: 4
    Letzter Beitrag: 29.01.2008, 07:34
  4. Ablauf von Programmen generell
    Von The Man im Forum Assembler-Programmierung
    Antworten: 2
    Letzter Beitrag: 18.08.2007, 15:21
  5. Ablauf der IRSs mit SIGNAL
    Von weijr im Forum Elektronik
    Antworten: 5
    Letzter Beitrag: 03.12.2006, 22:47

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests