Hallo,
Ich versuche im Moment das L80 GPS von Quectel auszulesen.
Mein Aufbau soll periodisch einen NMEA Satz empfangen und dann für eine
bestimmte Zeit in den Sleep-Modus gehen.
Mein Aufbau besteht aus einem Atmega328, dem oben genannten L80 und
einem Display zur Überprüfung.
In meinem Programm wecke ich zuerst das GPS-Modul auf, warte dann auf
ein Interrupt an INT0, welches am PPS vom GPS hängt. Dann wird ein
einziger Datensatz ausgelesen, an das Display weitergeleitet und dann
wird das GPS und der Mikrocontroller in den Sleepmodus versetzt.
Nun zu meinen zwei Problemen(Wobei das erste nicht so schwerwiegend
ist):
1)Ich verwende für den Uart keinen Puffer. Ich warte einfach bis ein
$-Zeichen empfangen wird und speichere dann alle weiteren Zeichen bis
'\n'.
Ich brauche ja nur einen Datensatz alle paar Minuten. Jedoch empfange
ich nach dem aufwachen des L80 immer noch die Bestätigung, das er
aufgewachen ist(PMTK-Satz) obwohl ich ja erst warte bis dieser ein
3D-Fix hat, bevor ich Uart einlese. Ich habe extra keinen Puffer
verwendet um diese PMTK-Sätze zu überspringen. Deshalb mein Dummy-Array
:) Aber es müsste doch auch ohne gehen? Warum "Verliere" ich diese PMTK
Sätze nicht, obwohl ich Uart erst viel später auslese?
2)Ich habe das Problem, dass das PPS Signal nach dem ersten Interrupt
komischerweise fix auf "1" bleibt. Versetze ich das GPS jedoch nie in
den Sleep-Mode, habe ich dieses Problem nicht.
Ich hoffe ich habe alle relevanten Infos angegeben. Falls nicht, fragt
nach :)
Mfg Kevin
Hier meine Main. Habe Initialisierungen die nicht relevant sind
weggelassen. Da programmtechnisch ja eigentlich alles funktioniert bis
auf UART.
1 | int main(void)
|
2 | {
|
3 | uint8_t data[51];
|
4 | uint8_t Dummy[51];
|
5 |
|
6 | InitUART(UBRR_VAL);
|
7 | Display_init(LCD_DISP_ON);
|
8 | Display_home();
|
9 |
|
10 | send_Uart(PMTK314); //Nur GPGLL Satz
|
11 | get_Uart(Dummy); //Bestätigung empfangen
|
12 |
|
13 | DDRD &= ~(1 << DDD2); //PD2 als Eingang
|
14 | PORTD &= ~(1<<PORTD2); //Pull-up an PD2 deaktivieren
|
15 |
|
16 | EICRA |= (1<<ISC01)|(1<<ISC00); //Interrupt auf steigende Flanke
|
17 | EIMSK |= (1 << INT0); //Interrupt aktivieren
|
18 |
|
19 | watchdogInit(); // Watchdog initialisieren.
|
20 | Display_puts("START");
|
21 |
|
22 | while (1)
|
23 | {
|
24 | send_Uart(PMTK101); //L80 Hot-Start
|
25 | get_Uart(Dummy);
|
26 | while(!GPS_Signal); //Warte auf 3D_Fix
|
27 | get_Uart(data); //GPGLL-Satz empfangen
|
28 | send_Uart(PMTK161); //Sleep Mode
|
29 | get_Uart(Dummy);
|
30 | Display_clrscr();
|
31 | Display_puts(data); //GPGLL ausgeben
|
32 | GPS_Signal=0;
|
33 | EIMSK |= (1 << INT0); //Interrupt wieder aktivieren
|
34 | Sleep(2); //Für 2*8s mit Watchdog-Timer schlafen
|
35 | }
|
36 | }
|
37 |
|
38 | ISR(INT0_vect)
|
39 | {
|
40 | GPS_Signal=1;
|
41 | EIMSK &= ~(1 << INT0); //Interrupt deaktiviern, damit nich jede sek wieder in die ISR gesprungen wird.
|
42 | }
|
Meine Uart Funktionen:
1 | void get_Uart(uint8_t* Buffer)
|
2 | {
|
3 | uint8_t c;
|
4 | while(ReceiveByte()!='$');
|
5 | *Buffer++='$';
|
6 | c=ReceiveByte();
|
7 | while(c!='\n'){
|
8 | *Buffer++=c;
|
9 | c=ReceiveByte();
|
10 | }
|
11 | *Buffer='\n';
|
12 | }
|
13 |
|
14 | uint8_t ReceiveByte(void)
|
15 | {
|
16 | while (!(UCSR0A & (1<<RXC0)));
|
17 | return UDR0;
|
18 | }
|