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
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...).
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); }
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]); } }
Den Header füs Display braucht ihr nicht Das Display funktioniert einwandfrei
Auch ja. Die Platine wird nicht an einen PC gehängt.
> 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.
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
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
weis eigentlich irgendwer was beim start vom gps geschickt wird kommen da gleich die nmea daten?
>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?)
>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...).
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
>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...
Ich kann die platie nicht an einen pc anschließen kein serielle schnittstelle kein usb
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
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...
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... }
- 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)
Hy, Ich verwende ein Adapterboard von ublox. Vielleicht deswegen die Verwirrung
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
>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.
>UCSRC = (1<<UCSZ0) | (1<<UCSZ0);
Muss
UCSRC = (1<<UCSZ0) | (1<<UCSZ0) | (1<<URSEL);
heissen
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
Hast du ein Speicher-Oszi zur Hand? Entweder per Oszi oder per serieller PC-Schnittstelle.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.