UART - Serialin Bascom

Gast #1532766
Hallo,

ich empfange Daten von einem GPS Modul, das Programm in Bascom sieht 
gekürzt so aus:

...
Config Serialin1 = Buffered , Size = 20 , Bytematch = 13
...

do
 print incoming_data
 waut 2
loop

...

sub Serial1charmatch:
 input incoming_data noecho
 Return
end sub


Sprich wenn ein \r erkannt wird, werden die ankommenden Daten in eine 
Variable geschrieben und im Hauptprogramm ausgegeben.

Die gesendeten Strings vom Sensor sehen ja pro Durchlauf in etwa so aus:
$GPRMC,191410,A,4735.5634,N,00739.3538,E,0.0,0.0,181102,0.4,E,A*19
$GPRMB,A,9.99,L,,Exit,4726.8323,N,00820.4822,E,29.212,107.2,,V,A*69
$GPGGA,191410,4735.5634,N,00739.3538,E,1,04,4.4,351.5,M,48.0,M,,*45
$GPGSA,A,3,,,,15,17,18,23,,,,,,4.7,4.4,1.5*3F
$GPGSV,2,1,08,02,59,282,00,03,42,287,00,06,16,094,00,15,80,090,48*79
$GPGLL,4735.5634,N,00739.3538,E,191410,A,A*4A
$GPBOD,221.9,T,221.5,M,Exit,*6B

Mein Problem ist nun, dass ich immer nur die erste Zeile, also den 
$GPRMC Teil bekomme, da jede Zeile per \r abgeschlossen wird. Ich 
benötige aber den $GPGGA Teil.

Könnte mir jemand einen Tipp geben, wie ich den Code abändern muss?

Danke!
Gast
Das ist nur ein Beispiel, ich habe es aus dem Kopf getippt. Tatsächlich 
steht da meintwegen 200. Trotzdem ist nur die komplette erste Zeile 
verfügbar - die würde in die 20 Zeichen auch nicht passen. Das sind 
nämlich ca 69 Zeichen.
Alex schrieb:
> Das ist nur ein Beispiel, ich habe es aus dem Kopf getippt.

Dann bin ich raus

Ich habe es nämlich satt, Fehler in Code zu suchen, der nicht dem 
entspricht, der tatsächlich auf dem AVR läuft und der dann auch nur aus 
ein paar nichtssagend hingerotzten Zeilen besteht.

Du sitzt vor dem Programm, hast es laufen und findest den Fehler nicht. 
Und wir sollen hier aus ein paar Bruchstücken erraten, was da wieder mal 
schief läuft.
Gast
Der Vorlage angemessen auch mal so nichtssagend hingerotzt:
Alle Zeilen wegschmeissen, bis  die richtige da ist.

Das ist aber nun wirklich Programmieren erstes Kapitel und zeigt 
anschaulich was passiert, wenn ein Anfaenger einfach 
drauflosprogrammiert, ohne sich vorher Gedanken zu machen.

Gast
Hallo,


Du detektierts halt "$GPGGA" und verarbeitest dann erst weiter...

Die überlegng hat mit "programmieren" erst einmal noch nichts zu tun, 
sondern nur mit etwas Nachdenken.

Entweder Du postest hier den gesamten Code und alle Unmstände oder Du 
läßt es besser sein.

Man will Dir ggf. helfen, aber nicht verarscht werden, alles klar ?!


DS
Gast
Hier das Programm

$regfile = "m644pdef.dat"
$crystal = 16000000
$baud = 9600
$baud1 = 9600


Declare Sub Serial0charmatch()
Config Serialin = Buffered , Size = 200 , Bytematch = 13

Dim Incoming_data As String * 200
Dim Filtered As String * 200
Dim Writestring As String * 20
Dim Length As Integer
Dim Var As Integer

'Hauptschleife
Waitms 500



Dim A As Word , B As Word
Dim Einzelzeichen As String * 1


Enable Interrupts

Do
   If Var = 1 Then

      Disable Interrupts
      Length = Len(incoming_data) - 1
      Filtered = Mid(incoming_data , 2 , Length)

      print Filtered

      Enable Interrupts
      Var = 0
    End If

   Wait 2
Loop

End


'Daten vom Buffer auslesen
Sub Serial0charmatch()

     Incoming_data = ""
    Input Incoming_data Noecho

       Var = 1

    Return
End Sub
schau Dir mal hier das 2. Beispiel mit den Overlays an und lies Dir mal 
durch was der sachkundige Autor schreibt. Das ist sehr strukturiert und 
wäre eine gute und bessere Ausgangsbasis für einen funktionierenden 
Code..

http://www.rowalt.de/mc/index.htm


......


Wer das Vorgehen String=String+Zeichen nicht mag, kann mit einem kleinen 
Trick optimal vorgehen: In Bascom ist es möglich, ein und denselben 
SRAM-Platz mit mehreren Variablen zu belegen. Wir können z.B. anweisen, 
daß unsere String-Variable auf Adresse &H60 gesetzt werden soll. 
Gleichzeitig können wir ein Feld mit 11 Bytes dimensionieren, das auf 
der gleichen Adresse liegen soll (ein 10 Byte langer String benötigt 11 
Bytes Platz). Damit können wir ganz einfach und effizient über völlig 
verschiedene Methoden auf denselben Speicher zugreifen. Schauen Sie sich 
bitte das folgende Listing an. '0011.BAS: Optimierter String-Empfang
$Regfile = "2313def.dat"
$Crystal = 3686400
$Baud    = 9600

Dim s As String*10 At &H60
Dim b(11) As Byte At &H60 Overlay
Dim n As Byte

On URXC OnRxD
Enable URXC
Enable Interrupts

Main:
  If n > 9 Then
    Print s
    n = 0
  End If
Goto Main

OnRxD:
  Incr n
  b(n) = UDR
Return


Der String wird auf Adresse &H60 im AVR abgelegt. Dies ist die Adresse 
des ersten Bytes im SRAM (da der AT90S2313 über 128 Bytes SRAM vefügt, 
ist die höchste SRAM-Adresse &HDF). Quasi "darüber", also auf die selbe 
Adresse, legen wir ein Feld, das genauso lang wie der String ist. Das 
ist alles. Der Trick ist nur, daß wir beim Füllen des Strings in unserem 
Anwendungsfall am effizientesten mit einem Feld arbeiten können, während 
in anderen Fällen die Arbeit mit einem String günstiger sein kann. 
Welche Wege man in der Praxis gehen will, hängt natürlich immer von der 
Anwendung ab. Die Anwendung des Overlay-Tricks kostet weder zusätzlichen 
Code, noch SRAM. Es ist vielleicht eher wie die Auswahl zwischen 
Buddelschippe, Schaufel und Bagger bei ein und dem selben Haufen Sand.

Und noch ein drittes UART-Mißverständnis trat wiederholt auf: Der 
UART-Empfangs-Interrupt meldet, daß ein Zeichen empfangen wurde. In der 
Interrupt-Routine kann man deshalb auch immer nur ein Zeichen auslesen. 
Zum Beispiel macht es daher keinen Sinn, in der Interrupt-Routine den 
Bascom-Befehl Input einzusetzen, um doch mehrere Zeichen empfangen zu 
können.
Gast
Was ich aber nicht verstehe ist folgendes:


Declare sub serial0charmatch()

config serialin = buffered, size = 100, bytymatch = 13
dim incoming_data as string *100

do
 print incoming_data
 wait 2
loop

end

sub serial0charmatch()
 input incoming_data noecho
 'print incoming_data
end sub


das print in der hauptschleife gibt immer nur eine empfangene zeile aus.
Kommentiere ich das print in der serial0charmatch ein, dann gibt es alle 
empfangenen zeilen aus - eben das, was ich benötige.

Warum ist es so?
Alex schrieb:

> das print in der hauptschleife gibt immer nur eine empfangene zeile aus.
> Kommentiere ich das print in der serial0charmatch ein, dann gibt es alle
> empfangenen zeilen aus - eben das, was ich benötige.
>
> Warum ist es so?

Wahrscheinlich deshalb, weil dieses print in der ISR mit dem Empfang 
synchronisiert ist. Es gibt nur dann aus, wenn auch tatsächlich ein 
String epfangen wurde. Wohingegen deine Hauptschleife auf biegen und 
brechen ausgibt.

Auch interessant:
Die Ausgabe dauert ja auch seine Zeit.
Was passiert eigentlich, wenn während der Ausgabe die serial0charmatch 
aufgerufen wird, und dem PRINT die Daten unter dem Allerwertesten 
umdreht.
Gast
Nein daran scheint es nicht zu liegen:

Declare sub serial0charmatch()

config serialin = buffered, size = 100, bytymatch = 13
dim incoming_data as string *100
dim flag as byte

flag = 0

do
 if flag = 1 then
  print incoming_data
  flag = 0
 endif

 wait 2
loop

end

sub serial0charmatch()
 flag = 1
 input incoming_data noecho
 'print incoming_data
end sub


liefert das gleiche ergebnis - immer nur eine empfangene zeile
Bist du sicher, dass dein GPS Empfänger mit 9600 Baud sendet?

Meistens haben die nämlich nur 4800 Baud.
Die Schlussfolgerung wäre dann
$crystal = 16000000
Dein µC läuft in Wirklichkeit mit 8Mhz, so dass sich wieder korrekte 
4800 ergben.
Aber:
  wait 2
das werden dann 4 Sekunden Wartezeit
Gast
Karl Heinz:

Ich weiß es nicht genau ehrlich gesagt.
Ich habe es so gelöst, dass ich in der Interrupt-Routine den 
Empfangsstring zerlegt habe und in zwei weiteren globalen Variablen die 
MMC und GGA Strings gespeichert habe.


Sub Serial0charmatch()

   Input Incoming_data Noecho

   If Len(incoming_data) > 50 Then
      Filter = Incoming_data
      Subfilter = Mid(incoming_data , 2 , 6)

      If Subfilter = "$GPRMC" And Mc = "" Then
         Mc = Filter
      End If

      If Subfilter = "$GPGGA" And Ga = "" Then
         Ga = Filter
      End If

   End If

   Return
End Sub

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.