Bascom UART Problem

filth

Neues Mitglied
25. März 2009
26
0
0
Sprachen
Hallo,

ich habe ein Problem. Es sollen Daten von einem GPS Sensor gelesen
werden. Speziell brauche ich nur die GPRMC und GPGGA Strings. Der Sensor
sendet im NMEA format.

Allerdings wird irgendwie die Hälfte vom Empfang verschluckt, manchmal
funktioniert es auch. Es scheint irgendein Timingproblem zu sein.

Hier ist der Code:

Code:
$regfile = "m644pdef.dat"
$crystal = 16000000
$hwstack = 128
$swstack = 512
$framesize = 128
$baud = 38400
$baud1 = 9600


' ************* GPS - TEIL ********************
Open "COM2:" For Binary As #2
Config Serialin = Buffered , Size = 100 , Bytematch = 10

Config Serialin1 = Buffered , Size = 100
Config Portb.6 = Input

Const Id_str_lg = 6                                         ' Länge des Identifiers
Dim Id_str As String * Id_str_lg                            ' ID String
Dim Buff_str_ovrl As String * 99 At _rs232inbuf0 Overlay    ' Einen String über den SerialIn Puffer legen

Dim Wr_ctr As Byte                                          ' Schreibzähler
Dim Wr_b As Byte
Dim Mc As String * 100                                      ' GPS MC - Teil
Dim Ga As String * 100                                      ' GPS GA - Teil
Dim Writestring As String * 30
Dim Length As Integer
Dim B_cpd As Byte                                           ' Hilfsvariable zum Kopieren der Bytes des Stringoverlays
Dim C_st As Byte
Mc = ""
Ga = ""
' ********************************************



Enable Interrupts



Do

Loop

End




'Daten vom Buffer auslesen
Serial0charmatch:

   Pushall

   B_cpd = _rs_bufcountr0 - 2                               ' Anzahl zu kopierender Zeichen des Pufferstrings
   C_st = _rs_head_ptr0 + 1                                 ' Startkopierposition im Pufferstring

   Id_str = Mid(buff_str_ovrl , C_st , Id_str_lg)           ' ID String holen, ab 2tem Zeichen, ohne $

   Print #2 , Buff_str_ovrl

   If Id_str <> "$GPGGA" And Id_str <> "$GPRMC" Then
      Clear Serialin
      Popall
      Return
   End If

   If Id_str = "$GPRMC" And Mc = "" Then
      Mc = Mid(buff_str_ovrl , C_st , B_cpd)                ' Puffer in den String kopieren, ohne $, ohne CR
   End If

   If Id_str = "$GPGGA" And Ga = "" Then
      Ga = Mid(buff_str_ovrl , C_st , B_cpd)                ' Puffer in den String kopieren, ohne $, ohne CR
   End If


   Clear Serialin

   Popall
Return


Die Ausgabe:

Code:
<\n>$GPGGA,205133.560,8960.0000,N,00000.0000,E,0,0,,137.0,M,13.0,M,,*46<\r>
<\n><\r>
<\n>$G33.560,V,8960.0000,N,00000.0000,E,0.00,0.00,190110,,,N*7C<\r>
<\n>M,,*46<\r>
<\n><\r>
<\n>$GPGGA,205133.760,8960.0000,N,00000.0000,E,0,0,,137.0,M,13.0,M,,*44<\r>
<\n><\r>
<\n>$G33.760,V,8960.0000,N,00000.0000,E,0.00,0.00,190110,,,N*7E<\r>
<\n>M,,*44<\r>
<\n><\r>
<\n>$GPGGA,205133.961,8960.0000,N,00000.0000,E,0,0,,137.0,M,13.0,M,,*4B<\r>
<\n><\r>
<\n>$G33.961,V,8960.0000,N,00000.0000,E,0.00,0.00,190110,,,N*71<\r>
<\n>M,,*4B<\r>
<\n><\r>
<\n>$GPGGA,205134.160,8960.0000,N,00000.0000,E,0,0,,137.0,M,13.0,M,,*45<\r>

Es wird immer nur der GPGGA-Teil aufgefangen. Hat evtl jemand eine Idee
warum?

Danke
 
Hallo filth,

zunächst erlaube ich mir mal die Frage, warum Du mit den Befehlen Pushall und Popall arbeitest. Das sind Kommandos die eigentliche der Assembler-Programmierung vorbehalten bleiben. Es sei denn Du hast bei der Definition einer ISR den Parameter NOSAVE angegeben. Dann bist Du selbst für das Pushen und Popen verantwortlich.
Ansonsten macht das alles BASCOM für Dich.

Irgendwie werde ich aber aus Deinem Code nicht schlau und ich nehme an, dass Du mir einiges an Code unterschlagen hast. Kannst Du bitte den vollständigen Code bereitstellen. Speziell bei Timingproblemen wäre das wichtig.

Danke und Grüße,
Ma
 
Hallo Markus,

ja, ich habe den Code etwas aus dem Kontext genommen um die Übersichtlichkeit zu verbessern. Jedoch ist eigentlich der herausgenommene Teil nicht relevant, da er nur dann ausgeführt wird, wenn die $GPGGA und $GPRMC Zeilen gelesen wurden.

Das mit Push/ Pop habe ich eigentlich aus der Bascom-Hilfe. Nicht richtig?

Grüße
Alex
 
Alsooooo....

1. ich würde auf jeden Fall Pushall und Popall entfernen da ich der Meinung bin, dass es in Deinem Context nicht richtig ist! Ich verwende es wirklich nur in Verbindung mit dem Parameter NOSAVE. Ansonsten macht BASCOM das automatisch für Dich. Bedeutet, in Deinem Fall machst Du doppelte Push und Pops und damit verlangsamst Du auf jeden Fall die Subroutine. Wenn Du Timing-Effekte hast dann würde ich das auf jeden fall entfernen.

2. ich gehe davon aus, dass Dir bekannt ist, dass "Serial0charmatch" auf UART/COM0 geht. Ich begreife noch nicht ganz, was Du mit COM2 machst.

Ich glaube aktuell nicht, dass es ein Timing-Problem ist sondern ich vermute ein systematische Problem dahinter, was sich je nach Inhalt der Daten verändert.

Villeicht erklärst Du mir kurz, was Du auf welcher Schnittstelle machen möchtest. Aktuell verwendest Du Com0, Com1 und Com2, hmmm....

Grüße,
Ma
 
Aaalso,

ich verwende ja den Atmega644P-20PU. Dort gibt es 2 Hardware Uarts. An TX0 / RX0 (COM1) hängt der besagte GPS Sensor, von dem die Daten empfangen werden.

An RX1 / TX1 hängt eigentlich ein USB-Interface, welches die Daten dann wegspeichert. Im Moment hängt dort zum Debuggen das Terminal dran :)

Viele Grüße
Alex
 
Alsooooo....

1. ich würde auf jeden Fall Pushall und Popall entfernen da ich der Meinung bin, dass es in Deinem Context nicht richtig ist! Ich verwende es wirklich nur in Verbindung mit dem Parameter NOSAVE. Ansonsten macht BASCOM das automatisch für Dich. Bedeutet, in Deinem Fall machst Du doppelte Push und Pops und damit verlangsamst Du auf jeden Fall die Subroutine. Wenn Du Timing-Effekte hast dann würde ich das auf jeden fall entfernen.
Schau dir mal die Bascom Hilfe zu Config Serialin an, da steht seit einigen Versionen:
When using the BYTEMATCH option, you must preserve the registers you alter. If you do not know which one, use PUSHALL and POPALL.

2. ich gehe davon aus, dass Dir bekannt ist, dass "Serial0charmatch" auf UART/COM0 geht. Ich begreife noch nicht ganz, was Du mit COM2 machst.
Wenn du auf µC mit zwei Hardware UARTs den zweiten benutzen willst, musst du ihn mit Open aufmachen, und zwar genau so, wie filth es getan hat.

Ich glaube aktuell nicht, dass es ein Timing-Problem ist sondern ich vermute ein systematische Problem dahinter, was sich je nach Inhalt der Daten verändert.
Ich denke doch.
@filth
Nach dem Empfang des Line-Feeds (10, ich hätte eigentlich 13 für CR erwartet) springst du in die Ausleseroutine für den UART0.
Dort arbeitest du direkt auf den Variablen des Buffers (_rs_bufcountr0, _rs_head_ptr0) und besonders _rs232inbuf0, den du im Overlay benutzt.
Außerdem ist dort ein Print drin, was ewig lange für die Ausführung braucht (9600 Baud). Da du immer wieder direkt auf den Buffer zugreifst, kann es leicht passieren, dass er schon von neuen Daten überschrieben wurde.
Ich würde das so machen:

Code:
$regfile = "m644pdef.dat"
$crystal = 16000000
$hwstack = 128
$swstack = 512
$framesize = 128
$baud = 38400
$baud1 = 9600


' ************* GPS - TEIL ********************
Open "COM2:" For Binary As #2
Config Serialin = Buffered , Size = 100 , Bytematch = 13

Config Serialin1 = Buffered , Size = 100
Config Portb.6 = Input
Const Id_str_lg = 6                                         ' Länge des Identifiers
Dim Id_str As String * Id_str_lg                            ' ID String
Dim Buff_str As String * 99 , Buff_str_ovrl As String * 99 At _rs232inbuf0 Overlay       ' Einen String über den SerialIn Puffer legen

Dim Wr_ctr As Byte                                          ' Schreibzähler
Dim Wr_b As Byte
Dim Mc As String * 100                                      ' GPS MC - Teil
Dim Ga As String * 100                                      ' GPS GA - Teil
Dim Writestring As String * 30
Dim Length As Integer
Dim B_cpd As Byte                                           ' Hilfsvariable zum Kopieren der Bytes des Stringoverlays
Dim C_st As Byte
Dim Received_flag As Byte
Mc = ""
Ga = ""
' ********************************************

Enable Interrupts

Do
   If Received_flag = 1 Then
      Id_str = Mid(buff_str , C_st , Id_str_lg)             ' ID String holen, ab 2tem Zeichen, ohne $
      Print #2 , Buff_str
      If Id_str = "$GPRMC" And Mc = "" Then
         Mc = Mid(buff_str , C_st , B_cpd)                  ' Puffer in den String kopieren, ohne $, ohne CR
      Elseif Id_str = "$GPGGA" And Ga = "" Then
         Ga = Mid(buff_str , C_st , B_cpd)                  ' Puffer in den String kopieren, ohne $, ohne CR
      End If
      Received_flag = 0
   End If
Loop

End

'Daten vom Buffer auslesen
Serial0charmatch:
   Pushall
   Buff_str = Buff_str_ovrl                                     'eingelesenen String aus dem Buffer wegkopieren
   B_cpd = _rs_bufcountr0 - 2                               ' wieso -2? Willst du den * nicht mit abschneiden?
   C_st = _rs_head_ptr0 + 1                                 ' Startkopierposition im Pufferstring
   Clear Serialin
   Received_flag = 1
   Popall
Return

Ist aber mangels Hardware nicht getestet.
Um die Ausgabe zu verbessern, könntest du Serialout auch noch puffern.

HBA
 
Hallo,

vielen Dank für den Tipp!
Ich kann es heute abend testen, werde dann aber Feedback geben.
Der print ist eigentlich nur zum debuggen da :)

Viele Grüße
Alex
 
Hallo,

ich denke jetzt funktioniert es. Ich habe es so gelöst:

Code:
do
   if GPS_Data_Flag > 0 then Gosub ProcessGPS
loop 


Serial1charmatch:
   pushall
   incr GPS_Data_Flag    ' increment for each new GPS sentence.
   popall
return 

ProcessGPS:
   decr GPS_Data_Flag         ' decriment for the line we are working on

   do                         ' look for start char "$" then continue.
      ch = inkey()          ' if not found in buffer then return.
      if ch = 0 then return   ' this will clear any bad chars.
   loop until ch = "$"        ' once we see the '$' then continue.

   input GPSLine Noecho

return

Es ist nur ein Ausschnitt, aber damit wird es klar, denke ich. Die ISR ist jetzt so weit wie möglich entlastet und setzt nur einen Flag bei Empfang, der weiter in der mainloop verarbeitet wird.

Viele Grüße
Alex
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)