Forum: Mikrocontroller und Digitale Elektronik NMEA - Protokoll / UBLOX SAM - LS / ATMEGA 16


von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute.

Ich hab gerade ein Problem mit einem Ublox SAM - LS GPS Receiver.
Ich will einfach die Daten über die serielle Schnittstelle einlesen 
(verwende einen ATMEGA 16). Besonders interresiert mich der GGA 
Datensatz des NMEA Protokolls. Hat irgendjemand schon einmal einen C 
Algorithmus geschrieben der das macht?
Ich glaube meiner ist falsch denn ich bekomme lauter wirre Zeichen, die 
nicht mal richtig nach ASCII ausschauen.

Hoffe ihr könnt mir helfen.

Danke Martin

PS: Anbei findet ihr noch die Schaltung und ein Datenblatt des Receivers

von Martin (Gast)


Angehängte Dateien:

Lesenswert?

und nun noch das Datenblatt

von Martin (Gast)


Lesenswert?

hat keiner eine Idee?

von Rahul, der Trollige (Gast)


Lesenswert?

Wie wäre es, noch etwas Code mitzuliefern?
Das "Bild.gif" ist ja eher fürn Poschi, und im Datenblatt ist auch nicht 
wirklich viel beschrieben.
Hast du das Ding schon an einem PC betrieben?
An die Unterlagen, die im Datenblatt noch angesprochen werden, komme ich 
leider nicht ran (scheinbar irgendwelche Sicherheitseinstellungen...).

von Martin (Gast)


Lesenswert?

wart ich schick einfach mal den source:

Das ist die Initialisierung des USART:

#include<avr/io.h>
#include<Standard_Basisstation_PA.h>

#define FOSZ 7372800
#define BAUD 9600


unsigned char MYUBRR;              //globale Variable für die Baudrate





/* ********************* Initialize_USART *********************
Autor: Worzfeld Martin
Klasse: 5AHELI
Datum: 12.2.2007

Übergabeparameter:   keine Übergabeparameter

Beschreibung:       Subroutine wird verwendet um die Serielle 
Schnittstelle des ATMEGA 16 zu initialisieren
          Dazu wird zunächst die Baudrate eingestellt und danach die 
einzelnen Empfangs und Senderegister
          freigegeben
***************************************************************/
void Initialize_USART()
{
  MYUBRR = (FOSZ/16/BAUD) -1;          //Errechnen der Baudrate
  UBRRH = (unsigned char)(MYUBRR>>8);      //Es wird die Baudrate 
eingestellt
  UBRRL = (unsigned char)MYUBRR;        //Es wird die Baudrate 
eingestellt


  SET_BIT(UCSRB, RXEN);            //Der Empfänger wird aktiviert
  //SET_BIT(UCSRB, TXEN);            //Der Sender wird aktiviert

  SET_BIT(UCSRC, URSEL);            //Es kann in das C Register 
geschrieben werdden

  CLEAR_BIT(UCSRC, UMSEL);
  CLEAR_BIT(UCSRC, UPM0);            //No Parity!
  CLEAR_BIT(UCSRC, UPM1);            //No Parity!
  SET_BIT(UCSRC, UCPOL);
  CLEAR_BIT(UCSRC, USBS);            //One Stopbit



  CLEAR_BIT(UCSRB, UCSZ2);          //8 Data Bit
  SET_BIT(UCSRC, UCSZ1);            //8 Data Bit
  SET_BIT(UCSRC, UCSZ0);            //8 Data Bit


  CLEAR_BIT(UCSRC, URSEL);


}

von Martin (Gast)


Lesenswert?

und noch die Hauptroutine:

#include <avr/io.h>          //Allgemeine Include File
#include <USART_WM.h>        //Include File für die Funktionen der 
Seriellen Schnittstelle
#include <Standard_Basisstation_PA.h>  //Include für die Standard 
Bitfunktionen
#include <LCD_WM.h>
#include <stdint.h>


int main(void)
{
  DDRA = 0xFF;
  DDRC = 0xFF;
  DDRD = 0xFF;

  CLEAR_BIT(DDRD, 0);


  long i,j;

  char c[20];


  for(i=0; i<9000; i++){}

  Initialize_Display();
  Firstline();


  for(i=0; i<9000; i++){}

  Initialize_USART();


  TOGGLE_BIT(PORTD, 4);


while(1)
{
for(i=0; i<20; i++)
{

  while(!(UCSRA & (1<<RXC)));

  for(j=0; j<9000; j++){}
  c[i] = UDR;


}

for(i=0; i<20; i++)
{

  Fast_Write(c[i]);

}

}

von Martin (Gast)


Lesenswert?

Den Header füs Display braucht ihr nicht
Das Display funktioniert einwandfrei

von Martin (Gast)


Lesenswert?

Auch ja. Die Platine wird nicht an einen PC gehängt.

von Rahul, der Trollige (Gast)


Lesenswert?

>  SET_BIT(UCSRB, RXEN);            //Der Empfänger wird aktiviert
>  //SET_BIT(UCSRB, TXEN);            //Der Sender wird aktiviert

>  SET_BIT(UCSRC, URSEL);            //Es kann in das C Register
geschrieben werdden

>  CLEAR_BIT(UCSRC, UMSEL);
>  CLEAR_BIT(UCSRC, UPM0);            //No Parity!
>  CLEAR_BIT(UCSRC, UPM1);            //No Parity!
>  SET_BIT(UCSRC, UCPOL);
>  CLEAR_BIT(UCSRC, USBS);            //One Stopbit



>  CLEAR_BIT(UCSRB, UCSZ2);          //8 Data Bit
>  SET_BIT(UCSRC, UCSZ1);            //8 Data Bit
>  SET_BIT(UCSRC, UCSZ0);            //8 Data Bit


>  CLEAR_BIT(UCSRC, URSEL);

Geht viel einfacher (, übersichtlicher und kürzer):
UCSRB = (1<<RXEN) | (1<<TXEN);
UCSRC = (1<<UCSZ0) | (1<<UCSZ0);

>Auch ja. Die Platine wird nicht an einen PC gehängt.
Das GPS-Modul funktioniert am PC, aber nicht am Mikrocontroller?
Funktioniert denn eine Kommunikation zwischen PC und Mikrocontroller?
So kann man zuindest ausprobieren, ob die Routine überhaupt 
funktioniert.

>  while(!(UCSRA & (1<<RXC)));

>  for(j=0; j<9000; j++){}
Warum wartest du hier?
>  c[i] = UDR;


>unsigned char MYUBRR;

Schade... (hatte ich völlig übersehen): Wenn dann müsste MYUBRR unsigned 
int sein. Normalerweise ist es ein Makro, dessen Wert der Compiler (oder 
der Präprozessor) berechnet und die Werte einträgt. Dafür braucht man 
keine Variable.

>  MYUBRR = (FOSZ/16/BAUD) -1;
Führt dann natürlich auch zu einem Fehler.
Mach das mal so:
#define MYUBRR (FOSZ/16L/BAUD) -1
Ohne MYUBBR irgendwo als Variable zu deklarieren.

von Martin (Gast)


Lesenswert?

Hallo,

ok die Warteschleife war umsonst, aber auch mit der neuen 
initialisierung hat sich nicht gerade viel geändert.
Ich speicher ja immer 2 byte in array und schreib die dann auf ein 
Display hinaus. Aber am Display kommen echt nur die wildesten Zeichen.

Ach ja, ich hab nie gesagt das der GPS Receiver am PC getestet wurde. 
Der hat seine Anwendung nur auf einer Platine. Und auch die Platine wird 
nicht an den PC geschlossen.


Danke mal für eure bemühungen

Greets martin

von Martin (Gast)


Lesenswert?

Ach ja
wollte noch erwähnen das die geschichte mit myubrr gut funktioniert hat 
kann wie auch händisch errechnet 2F heraus. Der Debugger sagt auch das 
2F dann im UbrrL drin steht

von Martin (Gast)


Lesenswert?

weis eigentlich irgendwer was beim start vom gps geschickt wird
kommen da gleich die nmea daten?

von Rahul, der Trollige (Gast)


Lesenswert?

>Ach ja
>wollte noch erwähnen das die geschichte mit myubrr gut funktioniert hat
>kann wie auch händisch errechnet 2F heraus. Der Debugger sagt auch das
>2F dann im UbrrL drin steht
Bei 9600Baud ist UBRRH = 0. UBRRH wird erst bei kleineren Baudraten > 0.
Sofern du die Baudrate während des Programmes nicht ändern willst, sehe 
ich keinen Sinn darin, dafür eine Variable zu benutzen (ist aber deine 
und nicht meine Entscheidung).

Stimmt das Bild.gif mit deinem realen Aufbau überein?
Im Programm hast du eine Fosc von 7,xxx MHz und im Schaltplan 12,xxx 
MHz.
Eins davon passt auf keinen Fall.

>Ach ja, ich hab nie gesagt das der GPS Receiver am PC getestet wurde.
Ich weiß, deswegen habe ich ja gefragt. Nicht, dass das Ding einen an 
der Marmel hat.

>Der hat seine Anwendung nur auf einer Platine. Und auch die Platine wird
>nicht an den PC geschlossen.
Hast du denn schon mal eine Kommunkation über die serielle Schnittstelle 
zwischen PC und ATMega16 zum Laufen bekommen? (Vielleicht sogar mit 
diesem Aufbau + RS232-Pegelwandler?)

von Rahul, der Trollige (Gast)


Lesenswert?

>weis eigentlich irgendwer was beim start vom gps geschickt wird
>kommen da gleich die nmea daten?

Sowas steht in der Regel im entsprechenden Datenblatt, das man sich bei 
u-blox runterladen kann (scheinbar jeder ausser mir...).

von Martin (Gast)


Lesenswert?

Nun ja. Ich verwende eine Fosc von 7 MHz. Ich hab mal das GPS auf einem 
GPS Steckbrett augebaut und mir den TXD am Oszi angeschaut. Schaut ganz 
super aus, sprich ich hab ein sauberes Signal. Das GPS müsste normal 
funktionieren ist noch neu und bis auf den Testaufbau noch nie in 
verwendung geweseen.

Zu deiner letzten frage:
Nein mit einem ATMega16 hab ich noch nie eine verbindung zum PC 
aufgebaut (brauch sie ja auch nicht). Weiters kann ich nur sagen das ich 
in einem alten projekt mit einem 8051 ein verbindung mit dem PC über USB 
(FTDI - Bautein) hergestellt hab.

Welches Datenblatt benötigts du? ich bin auf der ublox seite 
registriert. Schick mir einfach den link und lad es dir runter.

Danke für deine Hilfe

Greets martin

von Rahul, der Trollige (Gast)


Lesenswert?

>Weiters kann ich nur sagen das ich in einem alten projekt mit einem 8051 >ein 
verbindung mit dem PC über USB (FTDI - Bautein) hergestellt hab.
Falk oder scheibt dann gerne: "Apfelmus ist Mus aus Äpfeln"...

Vielleicht solltest du mal probieren, mit dem Mega16 Daten vom PC zu 
empfangen. Wenn das klappt, funktioniert wenigstens deine 
Empfangsroutine...

von Martin (Gast)


Lesenswert?

Ich kann die platie nicht an einen pc anschließen kein serielle 
schnittstelle kein usb

von Martin (Gast)


Lesenswert?

ich hab jetzt den txd und rxd zusammengeschlossen und das gps gerät 
abgehängt. hab dann über txd zeichne hinausgeschrieben und diese 
erfolgreich am rxd empfangen und am display ausgegeben. Also die 
empfangsroutine funktioniert

von Rahul, der Trollige (Gast)


Lesenswert?

Supi

von Rahul, der Trollige (Gast)


Lesenswert?

Vielleicht so:
while(1)
{
  while(!(UCSRA & (1<<RXC)));
  c[0] = UDR;
  Fast_Write(c[0]);
}

Wie funktioniert Fast_Write?
Schreibt es einfach das übergebene Zeichen auf die aktuelle Stelle des 
Display's? Nach 20 Zeichen springt er dann wieder auf die erste Stelle?

>Welches Datenblatt benötigts du? ich bin auf der ublox seite
>registriert. Schick mir einfach den link und lad es dir runter.

Im oben von dir geposteten Datenblatt stehen gaaanz unten zwei Quellen. 
Die kann man scheinbar bei u-blox runterladen...

von Martin (Gast)


Lesenswert?

Also: Hier ist mal der source für das Display

Die Waitzeiten sind erforderlich da wir den Enable selber toogeln müssen
/*********************************************************************** 
********
**                                                        **
**  Datei:        lcd.c                                        **
**  Funktion:      Ausgabe eines Textes auf LCD 
**
**            Möglich in beiden Zeilen mittels Umschaltung          **
**                                                **
**  Version:       V 1.1                                      **
**                                                        **
**  Autor:         Martin Worzfeld                        **
**                                         **
**   Weitere Autoren:  Andreas Pendl                      **
**                                                         **
**  Date: 13.03.2006                                              **
**                                                        **
**  Eingangsparameter:  keine                                      **
**                                                        **
**  Ausgangsparameter:  keine                                       **
**                                                        **
**  Rückgabewert:    keine                                      **
**                                        **
************************************************************************ 
******/

#include <avr/io.h>


/* ************************************ KONSTANTE 
****************************/

#define CLEAR_DISPLAY 0x01        // Befehl löscht ganzes Display
#define RETURN_HOME 0x02          // Setzt Cursor an Anfangsposition
#define ENTRY_MODE_SET 0x06       // Increment Display-Position, no 
Shift
#define FUNCTION_SET 0x38         // 8Bit Interface, 2 Line Display, 5x7 
Matrix
#define DISPLAY_ON 0x0E           // Display ON, Cursor ON, Blink OFF
#define DISPLAY_OFF 0x0A          // Display OFF, Cursor ON, Blink OFF
#define CURSOR_DISPLAY_SHIFT 0x14     // Cursor Move, Shift Left (<--)


/* ************************************ Funktionsprototypen 
******************/



void LCD_Out(char , int );        // char = p4 , int = wert für register
void Firstline();            // Wechsel in die erste Zeile
void Secondline();            // Wechsel in die zweite Zeile
void Initialize_Display();        // Subroutine zum inititialisieren des 
Displays
void Clear_Display();          // Subroutine um das Display zu testen
unsigned char Spiegeln(unsigned char);  // Funktion zum Spiegeln eines 
unsigned chars


/* **************** Register-Zuweisung **************** */

#define REGSELECT 7   // 1= DatenReg, 0= InstructionReg
#define READWR 6    // 1= lesen   , 0= schreiben
#define ENABLE 5    // von 1 auf 0 = TAKT-Flanke



/* **************** Bit - Funktionen ****************** */

#define SET_BIT(PORT, BITNUM)    ((PORT) |=  (1<<(BITNUM)))    //Zum 
setzen von einzelnen Bits
#define CLEAR_BIT(PORT, BITNUM)  ((PORT) &= ~(1<<(BITNUM)))    //Zum 
loeschen von einzelnen Bits
#define TOGGLE_BIT(PORT, BITNUM) ((PORT) ^=  (1<<(BITNUM)))    //Zum 
toogeln von einzelnen Bits



/* ********************* Clear_Display *********************
Autor: Worzfeld Martin
Klasse: 5AHELI
Datum: 30.1.2007

Übergabeparameter:  keine Übergabeparameter

Beschreibung:       Funktion um den Display inhalt zu löschen
*******************************************************/
void Clear_Display()
{
  LCD_Out(CLEAR_DISPLAY, 0);
}



/* ********************* LCD_out *********************
Autor: Worzfeld Martin
Klasse: 5AHELI
Datum: 30.1.2007

Übergabeparameter: char out == Byte der an das Display gesendet wird
           int reg == Registerwahl
           reg = 1 ==> Es wird ins Datenregister geschrieben
           reg = 0 ==> Es wird ins Instructionregister geschrieben

Beschreibung:       Funktion wird verwendet um Bytes an das Display 
hinauszuschreiben.
*******************************************************/
void LCD_Out(char out, int reg)
{

  out = Spiegeln(out);    //Der zu sendende Charakter muss noch 
gespiegelt werden
    int i;

  CLEAR_BIT(PORTD, READWR);  //Es wird geschrieben nicht gelesen

  if(reg == 0)        //Abfrage ob ins Daten oder Instruction Register 
geschrieben wird
  {
    CLEAR_BIT(PORTD, REGSELECT);
  }
  else
  {
    SET_BIT(PORTD, REGSELECT);
  }


  SET_BIT(PORTD, ENABLE);    //Steigende Taktflanke

    for(i=0; i<1000;i++);      // wait...

    PORTC = out;            // Ausgabe des übergebenen ASCII-Werts!

  CLEAR_BIT(PORTD, ENABLE);   // Fallende Taktflanke! Werte werden 
Übernommen.
    for(i=0; i<1000;i++);      // wait...
}


/* ********************* Firstline *********************
Autor: Worzfeld Martin
Klasse: 5AHELI
Datum: 30.1.2007

Übergabeparameter:  keine Übergabeparameter
Beschreibung:       Subroutine wird verwendet um in die erste Zeile des 
Displays zu springen
*******************************************************/
void Firstline()
{
  LCD_Out(0x80, 0); // Write to Instruction Register
}



/* ********************* Secondline *********************
Autor: Worzfeld Martin
Klasse: 5AHELI
Datum: 30.1.2007

Übergabeparameter:  keine Übergabeparameter
Beschreibung:       Subroutine wird verwendet um in die zweite Zeile des 
Displays zu springen
*******************************************************/
void Secondline()
{
  LCD_Out(0xC0, 0); // Write to Instruction Register
}




/* ********************* Initialize_Display *********************
Autor: Worzfeld Martin
Klasse: 5AHELI
Datum: 30.1.2007

Übergabeparameter:  keine Übergabeparameter
Beschreibung:       Subroutine wird verwendet um das Display zu 
initialisieren
          Genaue Beschreibung siehe Kommenatere unterhalb
*******************************************************/
void Initialize_Display()
{
  int i;                  //Zaehlvariable

  CLEAR_BIT(PORTD, READWR);          // Es wird geschrieben
  SET_BIT(PORTD, REGSELECT);        // Es wird ins Instructions - 
Register geschrieben

  for(i=0;i<10000;i++);            // Wait

  LCD_Out(FUNCTION_SET, 0);          // Betriebsmodus wird festgelegt
  LCD_Out(DISPLAY_ON, 0);           // Display einschalten
  LCD_Out(ENTRY_MODE_SET, 0);        // Eingabemodus
  LCD_Out(CURSOR_DISPLAY_SHIFT, 0);        // Cursor springt automatisch 
weiter
  LCD_Out(CLEAR_DISPLAY, 0);        // Display wird gelöscht
  LCD_Out(RETURN_HOME, 0);

}


/* ********************* Spiegeln *********************
Autor: Pendl Andreas
Klasse: 5AHELI
Datum: 12.02.2007

Übergabeparameter:  ein zu spiegelnder unsigned char c
Beschreibung:       Subroutine wird verwendet um das Display zu 
initialisieren
          Genaue Beschreibung siehe Kommenatere unterhalb
*******************************************************/
unsigned char Spiegeln (unsigned char c)
{
  unsigned char i, back;          //i = Zaehlvariable   // back der 
gespiegelte unsigned char

  for (i =0; i < 8; i++)          //Algorithmus zum spiegeln eines 
unsigned chars
  {
    if (((c << i) & 0x80) == 0x00)
      CLEAR_BIT (back, i);
    else
      SET_BIT (back, i);

  }

  return(back);              //gespiegelter Datentyp wird zurückgegeben

}

void Fast_Write(unsigned char out)
{

  out = Spiegeln(out);    //Der zu sendende Charakter muss noch 
gespiegelt werden
    int i;

  CLEAR_BIT(PORTD, READWR);  //Es wird geschrieben nicht gelesen
  SET_BIT(PORTD, REGSELECT);



  SET_BIT(PORTD, ENABLE);    //Steigende Taktflanke

    for(i=0; i<1000;i++);      // wait...

    PORTC = out;            // Ausgabe des übergebenen ASCII-Werts!

  CLEAR_BIT(PORTD, ENABLE);   // Fallende Taktflanke! Werte werden 
Übernommen.
    for(i=0; i<1000;i++);      // wait...
}


von Jan (Gast)


Lesenswert?

- zumindest die Beschriftung am Stecker X4 ist falsch. GND ist 1,3,5... 
nicht 2,4,6...; muß aber noch nix heißen

- du verwendest Pin 13 (eigentlich 14) RxD; vermutlich auf RxD vom Mega 
16?? Die Daten kommen aber auf TxD/Pin 12 (Pin 11 in deinem Schaltplan)

von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Hy, Ich verwende ein Adapterboard von ublox. Vielleicht deswegen die 
Verwirrung

von Martin (Gast)


Lesenswert?

Hallo,

ich glaub das ganze funktioniert nicht da die Initialisierung des USART 
nicht richtig durchgeführt wird.

Köntne mir bitte jemand posten wie man eine Serielle Schnittstelle für 
folgende Einstellungen richtig initialisert:

9600BAUD; 7372800 FOsc; 8 Datenbits, 1 Stopbit, no parity

Und was ist der genau unterschied zwischen asynchroner und synchroner 
übertragung?

Danke Martin

von Rahul, der Trollige (Gast)


Lesenswert?

>Und was ist der genau unterschied zwischen asynchroner und synchroner
>übertragung?

Das "a"...

Hast du dir mal meinen Vorschlag oben angeguckt?

#define FOSC 7372800
#define BAUD 9600
#define MYUBRR FOSC/16L/BAUD-1

UBRRH = (unsigned char) (MYUBRR>>8);
UBRRL = (unsigned char) MYUBRR;

UCSRB = (1<<RXEN) | (1<<TXEN);
UCSRC = (1<<UCSZ0) | (1<<UCSZ0);


Synchron bedeutet, dass ein Takt mitübertragen wird. Bei einer 
asynchronen Übertragung hat man sich auf eine Baudrate geeinigt. Als 
Startsignal wird dazu dann die fallende Flanke des Startbits benutzt.

von Rahul, der Trollige (Gast)


Lesenswert?

>UCSRC = (1<<UCSZ0) | (1<<UCSZ0);

Muss
       UCSRC = (1<<UCSZ0) | (1<<UCSZ0) | (1<<URSEL);
heissen

von Martin (Gast)


Lesenswert?

Hy Rahul,

sicherlich hab ich mir deine Initialisierung angeschaut, bringt aber 
genau das gleiche Ergebnis wie die meine. Ich bin so langsam echt am 
Verzweifeln. Hab so gar schon in der Schweiz angerufen um Support zu 
bekommen, aber die können mir auch nicht weiterhelfen. Ich bin mir 
ziemlich sicher das es an der Initialiserung liegt.

Hättest du sonst noch Ideen. Ich könnt sie echt brauchen ;-)

mfg Martin

von Rahul, der Trollige (Gast)


Lesenswert?

Hast du ein Speicher-Oszi zur Hand?
Entweder per Oszi oder per serieller PC-Schnittstelle.

von Martin (Gast)


Lesenswert?

Nein leider nicht

von Martin (Gast)


Lesenswert?

Hallo Rahul,

ich glaub deine letzte Init funktioniert. Ich hab in regelmäßigen 
abständen ein $ am display und dazwischen ein Sonderzeichen "|||" 
welches vermutlich ein Trennzeichen darstellt. Da ich in meinem Haus 
arbeite habe ich vermutlich nur schlechten bis gar keinen GPS Empfang. 
Glaubst du es ist reiner Zufall, das ich plötzlich das $ bekomme;

HINWEIS: laut NMEA stellt das $ den anfang eines neuen Datensatzes, zum 
beispiel gga da.

von Wolgang (Gast)


Lesenswert?

Hallo Martin,

schau mal bei http://www.holger-klabunde.de/avr/avrboard.htm#GPSdisplay

Gruß Wolfgang

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.