Hallo,
habe will einen von den GPS- Empfängern aus diesem Thread hier
(Beitrag "GPS - Empfänger günstig bei Ebay")
an einen ATmega8 anschliessen, und erstmal die aktuelle Geschwindigkeit
auf einem LCD ausgeben.
Ich habe die lcd-lib hier aus dem Forum, und die UART-lib von Peter
Fleury verwendet. Das LCD funktioniert, und das GPS- Modul ist korrekt
an RX und TX angeschlossen.
Allerdings empfange ich keine Daten von GPS- Modul.....(oder vielleicht
doch, aber sie werden nicht auf dem LCD ausgegeben?)
Hier mal mein Sourcecode, der übrigends bis auf 7 Warnings fehlerfrei
erstellt wird:
//Wenn Geschwindigkeit noch 2-stellig vor dem Komma, 2. Stelle hinter dem Komma = 0
63
}
64
if(empfangen[2]=='.')
65
{
66
empfangen[4]='0';
67
}
68
//Den String "empfangen" in float umwandeln, zum Rechnen
69
nurzumrechnen=atof(empfangen);
70
//Knoten in kmh umrechnen
71
kmh=nurzumrechnen*1.852;
72
//float wieder in String umwandeln, zum auf LCD ausgeben
73
itoa(kmh,kmh_string,10);
74
//kmh auf LCD ausgeben
75
lcd_string(kmh_string);
76
}
77
}
78
}
Vielleicht fällt ja jemandem etwas auf, was ich noch verbessern kann.
Wie man das GPS- Modul auf 9600 Baud einstellen kann, weiß ich nicht
genau, ich hab einfach mit SIRFDemo das NMEA- Protokoll eingestellt, und
dabei auch 9600 Baud. Allerdings weiß ich nicht, ob die Einstellungen
gespeichert werden, oder ob ich das über den µC jedesmal neu
konfigurieren muss.
Vielen Dank schon einmal im Voraus.
Gruß, Steffen
>Aha, muss ich dann noch eine Funktion machen, die solange wartet, bis>ein Zeichen da ist, also z.B. so:
Gute Idee.
>void getchar()
void ist aber nicht gut wenn man einen Wert zurückgeben will ;)
Und unsigned char zeichen[1]; kann man auf char zeichen, reduzieren.
Aber damit bist du immer noch nicht am Ziel.
>Wie kann ich schreiben, dass die Variable>"zeichen" nichts enthält?
uart_getc() gibt einen bestimmten Wert zurück wenn
noch kein Zeichen da ist. Einfach mal in den Beispielcode schauen?
Der Wert ist ein unsigned int und kein char.
Sir alan Teplotaxl wrote:
>zeichen==0>Wie wärs damit?
Aber wenn uart_getc() noch nchts empfängt, dann steht doch in der
Variable zeichen gar nichts, auch keine 0, oder?
holger wrote:
>>Aha, muss ich dann noch eine Funktion machen, die solange wartet, bis>>ein Zeichen da ist, also z.B. so:>> Gute Idee.>>>void getchar()>> void ist aber nicht gut wenn man einen Wert zurückgeben will ;)
Ja, ich werde dann int verwenden ;-).
> Und unsigned char zeichen[1]; kann man auf char zeichen, reduzieren.
Ok, mach ich auch.
> Aber damit bist du immer noch nicht am Ziel.>>Wie kann ich schreiben, dass die Variable>>"zeichen" nichts enthält?>> uart_getc() gibt einen bestimmten Wert zurück wenn> noch kein Zeichen da ist. Einfach mal in den Beispielcode schauen?> Der Wert ist ein unsigned int und kein char.
Im Beispiel von Peter Fleury wird das so gemacht:
1
unsignedintc;
2
....
3
c=uart_getc();
4
if(c&UART_NO_DATA)
5
{
6
/*
7
* no data available from UART
8
*/
9
}
10
else
11
{
12
/*
13
* new data available from UART
14
* check for Frame or Overrun error
15
*/
16
if(c&UART_FRAME_ERROR)
17
{
18
/* Framing Error detected, i.e no stop bit detected */
19
uart_puts_P("UART Frame Error: ");
20
}
21
if(c&UART_OVERRUN_ERROR)
22
{
23
/*
24
* Overrun, a character already present in the UART UDR register was
25
* not read by the interrupt handler before the next character arrived,
26
* one or more received characters have been dropped
27
*/
28
uart_puts_P("UART Overrun Error: ");
29
}
30
if(c&UART_BUFFER_OVERFLOW)
31
{
32
/*
33
* We are not reading the receive buffer fast enough,
34
* one or more received character have been dropped
35
*/
36
uart_puts_P("Buffer overflow error: ");
37
}
38
/*
39
* send received character back
40
*/
41
uart_putc((unsignedchar)c);
42
}
Soll ich einfach das alles in die Funktion getchar() packen?
Gruß, Steffen
OK, ich hab nun die Austrittsbedingung so gemacht:
}while(UART_NO_DATA)
Muss ich da nicht schauen, ob die Variable c Daten enthält? Weil so
überprüfe ich ja nochmal den UART, aber da wurden die Daten ja schon
abgeholt.
Wie überprüfe ich, ob die Variable c irgendeinen Inhalt hat?
Gruß, Steffen
Ok, hab ich nun so gemacht. Allerdings kommen immernoch keine Daten vom
GPS-Modul an. Ich glaub ich muss echt noch eine Baudrateneinstellung
beim GPS-Modul machen.
Kommt eigentlich bei jeder Baudrate was an, wenn es die falsche ist,
eben nur Unsinn?
Gruß, Steffen
>Kommt eigentlich bei jeder Baudrate was an, wenn es die falsche ist,>eben nur Unsinn?
In der Regel ja. Hast du vieleicht RxD und TxD vertauscht? GND
angeschlossen?
Wie sieht deine Schaltung aus?
GND is angeschlossen, und RX und TX sind eigentlich auch nicht
vertauscht. Wenn ich die beiden mal vertausche, dann kommen auf dem LCD
zig Zeichen, die aber alle keinen Sinn ergeben.
Die Schaltung hab ich auf einem BReadboard von Reichelt aufgebaut, kann
es sein, dass deswegen die 9600 Baud nicht klappen?
Gruß, Steffen
>Wenn ich die beiden mal vertausche, dann kommen auf dem LCD>zig Zeichen, die aber alle keinen Sinn ergeben.
Ja, ja, ja ...... dann ist es richtig rum !
Stell mal die Baudrate auf 4800 Baud.
Ok, ich hab nun die Baudrate bei 4800 Baud, aber da kommt beim
Einschalten gleich mal UART Frame Error, und irgendwann dann auch noch
ein Buffer Overflow :-(.
Also kann die Einstellung irgendwie nicht stimmen, oder?
Vielleicht muss ich noch beim Modul die Baudrate einstellen....
Gruß, Steffen
holger wrote:
> Vieleicht brauchst du einen MAX232 am ATMega?
Quatsch! Hab das Modul auch an nem Mega16 hängen ohne alles.... Versuch
mal 38400baud, das ist die Standardeinstellung des Moduls.
Ich hab das zu debugging zwechen so gemacht das ich RX des Megas
zusätzlich an eine MAX232 und an die Serielle des PCs dann sieht man
alles was der µC empfangen sollte nochmal auf dem PC und kann dann
leichter verifizieren was überhaupt ankommt.
Ich würde an deiner Stelle erstmal so anfange, das du alle Empfangenen
Zeichen bis zum \r\n auf dem LCD darstellst so das du siehst ob der
String überhaupt korrekt ankommt.
Ich mache das folgendermaßen: (Pseudocode!)
Ok, ich werd dann morgen mal meinen PC parallel dazu dranhängen, dann
sieht man was ankommt, bzw. sollte.
Ich hab nun mal 38400 Baud eingestellt, dann kommt nach dem Einschalten
UART Frame Error, und danach beide Zeilen des Dislays voll mit X und
einem Strich jeweils darüber.
Kann es auch sein, dass es nicht klappt, weil die Leitungen des
Breadboards bei 38400 Baud irgendwie nicht mehr mitspielen?
Hast du auch die rote Leitung an RX, und die weiße an TX?
Ich hab nun mal deine Funktion verwendet, aber ich bekomme weiterhin
einen UART Frame Error, nun eben nicht mit den X und den Strichen
drüber....
Vielen Dank schon einmal im Voraus.
Gruß, Steffen
Einen 4Mhz Quarzoszillator an XTAL1 angeschlossen, und den Controller
auf external clock gefused.
Meinst du ich soll einen Baudratenqurz verwenden?
Ich hab mit dem 4Mhz Oszillator auch schon mit dem PC kommuniziert, usw.
Gruß, Steffen
Hi
Zumindest wollte ich erst mal sicherstellen, das kein RC-oszillator im
Spiel ist.
Welche Teile deines Programms hast du schon einzeln getestet, und bist
sicher das die funktionieren. Nur als Hintergrund: Schaltung aufbauen,
Programm schreiben und geht, läuft selten.
Mein persönlicher Ansatz wäre einen kompletten NMEA-Sring in einen
Puffer einlesen, und dann in Ruhe auswerten
MfG Spess
So, nun hab ich den Empfänger an den Mega8 angeschlossen, und dazwischen
einen Pegelwandel, der an den PC mit nem Terminalprogramm angeschlossen
ist.
Der GPS-Empfänger sendet brav seinen NMEA Datensatz, bei 9600 Baud, wie
ich es eingestellt hatte. Am Terminalprogramm kann ich alle Strings gut
lesen, und es sind keine falschen Zeichen dabei.
Also liegt es definitiv am µC, bzw. der Software. Ich poste hier nochmal
meinen kompletten Code, der eigentlich bei 4Mhz funktionieren sollte,
vielleicht wisst ihr ja noch was.
1
#include<avr/io.h>
2
#define F_CPU 4000000
3
#include<util/delay.h>
4
#include<stdlib.h>
5
#include<avr/interrupt.h>
6
7
#include"lcd-routines.h"
8
#include<uart.h>
9
10
#define UART_BAUD_RATE 9600
11
12
intgetchar()
13
{
14
unsignedintc;
15
do
16
{
17
c=uart_getc();
18
19
if(c&UART_NO_DATA)
20
{
21
/*
22
* no data available from UART
23
*/
24
}
25
else
26
{
27
/*
28
* new data available from UART
29
* check for Frame or Overrun error
30
*/
31
if(c&UART_FRAME_ERROR)
32
{
33
/* Framing Error detected, i.e no stop bit detected */
34
lcd_string("UART Frame Error: ");
35
}
36
if(c&UART_OVERRUN_ERROR)
37
{
38
/*
39
* Overrun, a character already present in the UART UDR register was
40
* not read by the interrupt handler before the next character arrived,
41
* one or more received characters have been dropped
42
*/
43
lcd_string("UART Overrun Error: ");
44
}
45
if(c&UART_BUFFER_OVERFLOW)
46
{
47
/*
48
* We are not reading the receive buffer fast enough,
49
* one or more received character have been dropped
//Wenn Geschwindigkeit noch 2-stellig vor dem Komma, 2. Stelle hinter dem Komma = 0
114
}
115
if(empfangen[2]=='.')
116
{
117
empfangen[4]='0';
118
}
119
//Den String "empfangen" in float umwandeln, zum Rechnen
120
nurzumrechnen=atof(empfangen);
121
//Knoten in kmh umrechnen
122
kmh=nurzumrechnen*1.852;
123
//float wieder in String umwandeln, zum auf LCD ausgeben
124
itoa(kmh,kmh_string,10);
125
//kmh auf LCD ausgeben
126
lcd_string(kmh_string);
127
}
128
}
129
}
Auf dem Display erscheinen, wenn ich alles angeschlossen habe
irgendwelche Zeichen, in !beiden! Zeilen, und irgendwo dazwischen kommen
mal Bruchstücke von Overflow Error, usw..
Irgendwann kommt auch mal ein Teil von "Fix gefunden".....
Ich bin echt scheon ein wenig verzweifelt, weil ich nicht weiß, woran es
liegt, und es partout nicht klappen will :-(.
Ich hoffe, jemand weiß noch Rat....
Vielen Dank schon einmal im Voraus.
Gruß, Steffen
>lcd_string(temp);>lcd_string(nmea[0]);
temp ist kein String. nmea[0] ist auch kein String.
Wenn du lcd_string() nur ein char übergibst jagt es
quer durch den Speicher und gibt alles aus was nicht 0 ist.
Also soll ich dann "temp" mit unsigned char temp[1] initialisieren, und
immer wenn es gebraucht wird eben temp[0] schreiben?
Und bei der Ausgabe mit lcd_string nicht einen einzelnen Wert (temp[0]),
sondern einfach lcd_string(temp) ?
Wenn dann alles ausgegeben wird, was nicht 0 ist, würde das erklären,
warum da überall irgendwelche Zeichen auf dem Display erscheinen.
Ich werde es mal versuchen.
Gruß, Steffen
Nein, du solltest eine LCD-Funktion benutzen, die keinen String ausgibt,
sondern nur ein einzelnes Zeichen, wie auch immer die bei der LCD-Lib
heißen mag (geben tut es sie bestimmt, vielleicht lcd_putc?).
Nein, in meiner lib gibt es lcd_data, ich glaub mit dem gibt man immer
nur ein Zeichen aus. Ganz sicher bin ich mir aber nicht, ich werde es
schnell mal nachprüfen. Wenn es das richtige sein sollte, einfach alle
lcd_string durch lcd_data ersetzen?
Gruß, Steffen
So, hab nun mal alle lcd_string durch lcd_data ersetzt, nun komt nach
dem Einschalten UART Frame Error (die Meldung kommt eigentlich jedesmal,
egal was ich am Code veränder!), und dann nur noch das Zeichen E, in
beiden Zeilen.
Gruß, Steffen
holger wrote:
>>So, hab nun mal alle lcd_string durch lcd_data>> Nein ! Ich dreh durch :( Doch nicht ALLE.> Nur die wo nur EIN Zeichen übergeben wird.
Ja, ich hab natürlich nur die geändert, wo ein Zeichen übergeben wird,
bei denen, wo ein String übergeben wird, steht natürlich noch
lcd_string.
Gruß, Steffen
Hallo Steffan
Wo hast du deinen GPS Empfänger her?
Weiss jemand wo man günstig GPS Empfänger herbekommt?
Ich bräuchte auch ein paar... so günstig wie möglich... :)
Liebe Grüsse
Claudio