Hallo Volker,

selbstverständlich habe ich mein GPS-Modul konfiguriert. Das habe ich auch in einem meiner Beiträge angedeutet.

Das Modul ist ein Sirf3-Chip den ich auf 4800 Baud und nur die Meldungen $GPRMC und $GPGSA im Sekunden-Takt konfiguriert habe. Wenn ich mir die geschickten Daten im Hyperterminal ansehe kommen die beiden Nachrichten fast auf einen Schlag in der Reihenfolge RMC und GSA, danach eine Sekunde Pause und wieder die Nachrichten...

Ich habe ja dank des Denkanstosses von PicNick festgestellt das der Controller schnell genug ist um die Daten zu Empfangen. Bei 4800 Baud habe ich wie gesagt über 2ms Zeit zwischen den Zeichen. Das sind bei 8Mhz auf jeden Fall über 1000 Befehle.

Ich speichere die empfangenen Zeichen im USART-IRQ in einen Buffer und setze ein Flag, wenn eine Nachricht vollständig angekommen ist. Wenn im Hauptprogramm Zeit ist wird dieses Flag überprüft, und wenn gesetzt der Buffer ausgewertet. Ich arbeite sogar mit 2 Buffern, um einen auswerten zu können und im anderen schon wieder die nächste Nachricht aufzuzeichnen.

Allerdings funktioniert irgendwas nicht. Ich habe heute fast den ganzen Tag an dem Problem gesessen, aber keinen Fehler gefunden. Vermutlich sehe ich den Wald vor lauter Bäumen nicht mehr. Deshalb wäre es nett wenn mal hier jemand schnell über den Quellcode gucken kann wo mein brutaler Denkfehler ist.

Erst mal die Deklarationen der Buffer, Flags, Pointer, etc.:

volatile U8 Akt_GPS_Rekord_Buffer= 0;
volatile U8 Akt_GPS_Rekord_Ende= 254;
volatile U8 GPS_Buffer_Auswerten[2];
volatile U8 GPS_Buffer_Pointer[2];
volatile char GPS_Buffer1[255];
volatile char GPS_Buffer2[255];

#define Aus 0
#define Ein 1

Und hier die IRQ-Behandlung:

ISR (USART1_RX_vect)
{char Zeichen;

Zeichen = UDR1;

if (Zeichen == '$')
{if (Akt_GPS_Rekord_Buffer == 0)
{if (GPS_Buffer_Auswerten[1] == Aus)
Akt_GPS_Rekord_Buffer = 1;

if (GPS_Buffer_Auswerten[2] == Aus)
Akt_GPS_Rekord_Buffer = 2;
}

if (Akt_GPS_Rekord_Buffer > 0)
{GPS_Buffer_Pointer[Akt_GPS_Rekord_Buffer] = 0;
Akt_GPS_Rekord_Ende = 254;
}
} else if ((Zeichen == '*') & (Akt_GPS_Rekord_Buffer > 0))
{if (GPS_Buffer_Pointer[Akt_GPS_Rekord_Buffer] < 253)
Akt_GPS_Rekord_Ende = GPS_Buffer_Pointer[Akt_GPS_Rekord_Buffer] + 2;
else
Akt_GPS_Rekord_Buffer = 0;
}

if (Akt_GPS_Rekord_Buffer > 0)
{switch (Akt_GPS_Rekord_Buffer)
{case 1: {GPS_Buffer1[GPS_Buffer_Pointer[Akt_GPS_Rekord_Buffer]++] = Zeichen;
break;}
case 2: {GPS_Buffer2[GPS_Buffer_Pointer[Akt_GPS_Rekord_Buffer]++] = Zeichen;
break;}
}

if (GPS_Buffer_Pointer[Akt_GPS_Rekord_Buffer] > Akt_GPS_Rekord_Ende)
{if (Akt_GPS_Rekord_Ende < 254)
GPS_Buffer_Auswerten[Akt_GPS_Rekord_Buffer] = Ein;
Akt_GPS_Rekord_Buffer = 0;
}
}
}

Für alle die nicht wissen wie eine NMEA-Nachricht aufgebaut ist: Sie fangen mit einem Dollar ($) an, und enden mit einem Asteriks (*) gefolgt von zwei Zeichen für die Checksumme. Also zum Beispiel:
$GPRMS.......*AA

Viele Grüße
Andreas