Forum: Mikrocontroller und Digitale Elektronik Keine GPS Datenanzeige auf GLCD Display (Navilock 552ettl)


von Alex (Gast)


Lesenswert?

Hallo liebe Forengemeinde,

nachdem ich mich dank euch und den wirklich guten Tutorials auf dieser 
Seite in die µC-Technik eingearbeitet habe, stehe ich nun vor einer 
schier unüberwindbaren Hürde und hoffe das ihr mir helfen könnt. In der 
Suchfunktion finde ich leider nur Infos für nicht GLCD Displays.
Ich möchte über ein 128x64 Pixel GLCD Display die Daten, die ich vom 
Navilock 552ettl GPS-Empfänger erhalte, anzeigen. Der C-Code 
funktioniert fast unverändert bei einem 16x2 LCD Display. Lediglich die 
Funktion lcd_puts_p wird dort durch lcd_string ersetzt.
Ich hoffe ihr könnt mir helfen. Im Anhang das Mainprogramm, welches sehr 
stark an Tutorials bzw. Forenbeiträge angelehnt ist.

Vielen Dank schonmal.
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <stdlib.h>
4
#include <string.h>
5
6
#include "Nmea2Gps.h"
7
#include "mylcd.h"
8
#include "small_font.h"
9
#include "mega.h"
10
#include "Grafiken.h"
11
#include "big_font.h"
12
#include "font6x8.h"
13
14
static char testString[] =
15
"$GPGGA,094149.000,5008.5464,N,01114.9928,E,1,8,1.00,290.4,M,47.7,M,,*5E\
16
$GPGLL,5008.5464,N,01114.9928,E,094149.000,A,A*59\
17
$GPGSA,A,3,23,31,13,11,20,17,25,04,,,,,1.66,1.00,1.33*05\
18
$GPGSV,3,1,12,23,84,151,20,20,58,094,29,13,51,221,17,04,44,298,39*77\
19
$GPGSV,3,2,12,32,31,092,,33,27,213,,25,20,170,25,17,19,238,29*7E\
20
$GPGSV,3,3,12,31,17,038,35,11,12,163,17,02,10,316,,07,03,179,*7E\
21
$GPRMC,094149.000,A,5008.5464,N,01114.9928,E,0.08,165.51,070509,,,A*6B\
22
$GPVTG,165.51,T,,M,0.08,N,0.15,K,A*37";
23
24
25
static void uart_init(void){
26
  #undef BAUD            // avoid compiler warning
27
  #define BAUD 38400UL
28
  #include <util/setbaud.h>
29
  UBRRH = UBRRH_VALUE;
30
  UBRRL = UBRRL_VALUE;
31
  #if USE_2X
32
  UCSRA |= (1 << U2X);
33
  #else
34
  UCSRA &= ~(1 << U2X);
35
  #endif
36
  UCSRB |= (1<<TXEN)|(1<<RXEN);
37
  //UCSRB |= (1<<RXEN);
38
  
39
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1
40
}
41
42
uint8_t uart_getc(void){
43
  while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
44
  ;
45
  return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
46
}
47
48
void uart_gets( char* Buffer, uint8_t MaxLen ){
49
  uint8_t NextChar;
50
  uint8_t StringLen = 0;
51
  
52
  do{
53
    NextChar = uart_getc();
54
  }while(NextChar != 0);    // Warte auf erstes Zeichen
55
  
56
  while(NextChar != '*' && StringLen < MaxLen - 1){
57
    *Buffer++ = NextChar;
58
    StringLen++;
59
    NextChar = uart_getc();
60
  }
61
  
62
  *Buffer = '\0';          // Noch ein '\0' anhängen um einen Standard C-String daraus zu machen
63
}
64
65
int main (void)
66
{
67
    
68
//LCD initialisieren
69
  lcd_init();
70
  uart_init();
71
  lcd_clear();
72
  char gps_data[128];
73
  
74
  
75
while(1){
76
    uart_gets(gps_data, sizeof(gps_data));  //Navilock 552ETTL auslesen
77
    
78
    //lcd_set_cursor(0,LINE0);
79
    //lcd_puts_p(small_font,gps_data);
80
    
81
    lcd_set_cursor(0,LINE2);
82
    lcd_puts(small_font,gps_data);
83
    _delay_ms(12500);
84
    
85
    lcd_set_cursor(0,LINE2);        //Überprüfung ob Schleife bis hierher gelangt, wenn ja, wird uart_gets abgearbeitet
86
    lcd_puts_p(small_font,PSTR("Line"));
87
    
88
    _delay_ms(12000);
89
    lcd_clear();
90
    _delay_ms(1500);
91
    }
92
  return 0;
93
  
94
}

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Nun ja, das Problem liegt nicht in dem gezeigten Code. Wenn lcd_puts 
nichts ausgibt, klemmt es zwischen GLCD-lib und dem GLCD.

LCD richtig angeschlossen? GLCD-Lib richtig parametriert? usw...

Oliver

von Quack (Gast)


Lesenswert?

Schritt 1: Frage formulieren.
Schritt 2: Code auf's Minimum reduzieren.
Schritt 3: Hardware zeigen.

von Alex (Gast)


Lesenswert?

Danke für die Antwort Oliver.
 Das GLCD ist richtig angeschlossen. Die Anzeige "Line" geht auch. Habs 
etliche Male geprüft. Den Funktionscode hänge ich heute abend mit dran.

von Dieter F. (Gast)


Lesenswert?

Alex schrieb:
> while(NextChar != '*' && StringLen < MaxLen - 1)

Einige Klammern würden dem C-Compiler deutlich machen, was in welcher 
Reihenfolge womit verglichen werden soll ...

von dummy (Gast)


Lesenswert?

do{
    NextChar = uart_getc();
  }while(NextChar != 0);    // Warte auf erstes Zeichen


Sicher das du da nicht in einer Endloschleife kleben bleibst?
NMEA schickt so weit ich weiss keine binäre 0.

von Alex P. (alex2203)


Lesenswert?

Die Punkte von dummy und Dieter Frohnapfel hab ich nun umgesetzt. Nun 
steht
1
while(NextChar != '$');    // Warte auf erstes Zeichen
und
1
while((NextChar != '*') && (StringLen < MaxLen - 1)){
im Code.
Anbei nun noch die Funktion lcd_puts. Die Microcontrollerei find ich 
echt geil und spannend aber solche Fehler kosten auch den letzten Nerv.
1
// ---------------------------------
2
// put string to screen (from ram)
3
// ---------------------------------
4
void lcd_puts(uint8_t* font,char* string)
5
{while(*string)lcd_putc(font,*string++);}
und da sie mit aufgerufen wird die lcd_puts_p...
1
void lcd_putc(uint8_t* font,uint8_t chr)
2
{
3
  uint8_t x,page,bit,data,cnt=0;
4
  
5
  if (font_char_present(font,chr)==1)  // print only if letter is present in font
6
  {
7
    if ( ( (cursor_x + font_char_width(font,chr)) <128)  && ((cursor_y+font_char_height(font))<=64))  // only print leeter if it fits in screen
8
    {
9
      uint16_t offset= font_start_offset(font,chr);  // get the position of the first byte in font-array
10
      
11
      for(page=0;page<=(font_char_height(font)-1)/8;page++)  // write all pages(rows)
12
      {
13
        lcd_write_cmd(LCD_SET_PAGE|((cursor_y/8)+page),CHIP1|CHIP2);  // calc the current page
14
15
        if (cursor_x<64)  // set cursor to its poition (0 on the inactive controller so it can start directly on chip change)
16
        {
17
          lcd_write_cmd(LCD_SET_ADD|cursor_x,CHIP1);
18
          lcd_write_cmd(LCD_SET_ADD|0,CHIP2);
19
        }
20
        else
21
        {
22
          lcd_write_cmd(LCD_SET_ADD|(cursor_x-64),CHIP2);        
23
        }
24
25
        for (x=cursor_x;x<cursor_x + font_char_width(font,chr);x++)  //fill "pages"
26
        {
27
          data= pgm_read_byte(font+offset+cnt++);
28
29
          if ( page==font_char_height(font)/8)    
30
            data>>=8-(font_char_height(font)%8);  // if char height is bigger than 8 we have to remove some leading zeros
31
          
32
          #ifdef FASTTEXT                // this is much much faster than using set_pixel (see discription in header file)
33
          if (cursor_y%8==0 )
34
          {
35
            if (x<64)                
36
              lcd_write_data(data,CHIP1);            
37
            else                  
38
              lcd_write_data(data,CHIP2);          
39
          }
40
          else
41
          #endif
42
          {
43
            for (bit=0;bit<8;bit++)
44
            {
45
              if ((data&(1<<bit))!=0)
46
               lcd_set_pixel(x,cursor_y+page*8+bit,BLACK);
47
            }
48
          }
49
        }      
50
        
51
        #ifdef FASTTEXT
52
        if(cursor_y%8==0)
53
        {
54
          if (x<64)                
55
            lcd_write_data(0,CHIP1);            
56
          else                  
57
            lcd_write_data(0,CHIP2);        
58
        }
59
        #endif
60
      }      
61
      cursor_x += font_char_width(font,chr)+1;
62
63
64
    }
65
  }
66
}

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

Habe es mal auf die Empfangsroutine (in dieser Form funktionierend) 
reduziert:

In lcd_puts steht jetzt natürlich nur ein Platzhalter ...

Die Klammern im Ausdruck "while((NextChar != '\n') && (StringLen < 
(MaxLen - 1)))" müssen IN DIESEM FALL nicht sein, dienen aber (für mich) 
der Lesbarkeit. Ich setze IMMER Klammern, dann weiß ich auch sicher, wie 
verglichen etc. wird.

Die Abfrage auf "*" habe ich auf Line-Feed angepasst, da der NMEA-String 
immer durch CR/LF abgeschlossen wird. CR lese ich auch ein, überschreibe 
es aber dann mit dem String-Ende-Marker.
1
#define BAUD 38400UL
2
#define F_CPU 16000000UL
3
4
#include <avr/io.h>
5
#include <util/delay.h>
6
#include <stdlib.h>
7
#include <string.h>
8
#include <util/setbaud.h>
9
10
11
static void uart_init(void)
12
{  
13
  UBRRH = UBRRH_VALUE;
14
  UBRRL = UBRRL_VALUE;
15
  
16
  UCSRB |= (1<<TXEN)|(1<<RXEN);
17
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1
18
}
19
20
uint8_t uart_getc(void)
21
{
22
  while ((UCSRA & (1 << RXC)) == 0);
23
  return UDR;                  // Zeichen aus UDR an Aufrufer zurueckgeben
24
}
25
26
void uart_gets( char* Buffer, uint8_t MaxLen )
27
{
28
  uint8_t NextChar;
29
  uint8_t StringLen = 0;
30
  
31
  NextChar = uart_getc();
32
    
33
  while((NextChar != '\n') && (StringLen < (MaxLen - 1)))
34
  {
35
    *Buffer++ = NextChar;
36
    StringLen++;
37
    NextChar = uart_getc();
38
  }
39
40
  *--Buffer = '\0';                // Noch ein '\0' statt CR anhängen um einen Standard C-String daraus zu machen
41
}
42
43
44
45
// ---------------------------------
46
// put string to screen (from ram)
47
// ---------------------------------
48
void lcd_puts(uint8_t test)
49
{
50
  static uint8_t Test;
51
  
52
  Test++;
53
}
54
55
56
int main (void)
57
{
58
  uart_init();
59
  char gps_data[128];
60
61
  while(1)
62
  {
63
    uart_gets(gps_data, sizeof(gps_data));  //Navilock 552ETTL auslesen
64
65
    lcd_puts(1);
66
  }
67
  return 0;
68
69
}

von holger (Gast)


Lesenswert?

Was soll uns dein neues Programm jetzt sagen?
Welchen Controller verwendest du eigentlich?

von Dieter F. (Gast)


Lesenswert?

@holger: Meinst Du mich?

Alex soll es sagen, dass die "vorgestellte" Empfangsroutine sicher 
funktioniert und er seine LCD-Ausgaben Schritt für Schritt dazupacken 
kann.

Ich verwende den ATMEGA32, da mir die Register bekannt vorkamen und Alex 
vermutlich auch einen ATMEGAxx einsetzt.

von Alex P. (alex2203)


Lesenswert?

Hallo Dieter,
danke für die Mühe. Leider ist das Ergebnis unverändert. Ich besitze ein 
KS0108 compatibles 128x64 Grafik LCD Display. Ich muss doch bei lcd_gets 
noch die Schriftart dazu reinschreiben oder? (sprich: 
lcd_gets(Schriftart, Char-Array).
Ich bin bald echt am verzweifeln. Das Ganze ist für ein Schulprojekt zum 
Elektrotechniker. Bin kurz davor ein 4x20 Zeilen Display zu nehmen, 
wobei man natürlich mit nem GLCD wesentlich mehr machen könnte. Ich 
hoffe euch fällt da noch was ein wie ihr mich auf die richtige Spur 
bringt. Habe Spaßeshalber mal nach Deklarierung des Char Arrays (somit 
vor Beginn der While(1) Schleife sowie nach der uart_gets(...) Zeile 
eine einfache Textzeile eingefügt. Der Text nach der uart_gets wird 
nicht angezeigt. Das bedeutet doch das er uart_gets nicht abarbeitet 
oder irre ich mich da?
Ich nutze übrigens einen Atmega16. Momentan noch mit 8Mhz internen Takt.

: Bearbeitet durch User
von Mike (Gast)


Lesenswert?

Alexander Plöger schrieb:
> Der Text nach der uart_gets wird
> nicht angezeigt. Das bedeutet doch das er uart_gets nicht abarbeitet
> oder irre ich mich da?

Lass dir doch über irgendwelche freien Pins Signale ausgeben, anhand 
derer du auf einem Oszi oder LA verfolgen kannst, wo sich das Programm 
gerade rumtreibt. Textausgaben können das Timing des Programms ziemlich 
durcheinander bringen.

von Dieter F. (Gast)


Lesenswert?

Alexander Plöger schrieb:
> Das bedeutet doch das er uart_gets nicht abarbeitet
> oder irre ich mich da?

Hallo Alexander,

ich bin sicher (mit HTERM als "GPS-Ersatz" ausprobiert), dass die 
USART-Routinen in meinem angepassten Beispiel funktionieren.

Mit der Lib, die Du verwendest, habe ich noch nicht gearbeitet. Ich 
vermute, Du nutzt die von

Author: Andre Fabricius  (mailto:master.andre@web.de) 
Date: 13.08.08 18:32

Ich habe nur diese, relativ alte, Version gefunden. Die Angabe der 
Schriftart ist bei LCD_PUT.. immer erforderlich, soweit ich sehe.

Nimm doch mal bitte die Definition

char gps_data[128];

aus main() raus und stelle diese im Anschluss die #include-Statements 
ein. Ich bin mir da nicht sicher, aber ggf. liegt es an der fehlenden 
globalen Definition dieser String-Variablen, dass LCD_PUT.. nichts damit 
macht.

Im Schlimmst-Fall kannst Du mir auch mal das komplette Programm (falls 
Du nicht "öffentlich" werden willst auch per PN) senden und ich debugge 
es mal (habe ein JTAGICE). Ich verfüge zwar nicht über das entsprechende 
Display, aber ich kann schauen, wie die Funktionen aufgerufen werden 
bzw. mit welchen Inhalten.

von Alex P. (alex2203)


Lesenswert?

Also, ich habe nun das Char Array aus Main rausgenommen... keine 
Änderung. Danke für dein Angebot Dieter. Ich hab dir ne PN geschickt. 
Ich würd dir für die Lösung sogar mein Display zukommen lassen ;) 
(kleiner Spaß).

Danke schonmal für die Mühe. Auch allen anderen für die Antworten. Ein 
wirklich sehr gutes und kompetentes Forum :)

Gruß

von Karl H. (kbuchegg)


Lesenswert?

Ich würd mir ja mal hier
1
uint8_t uart_getc(void)
2
{
3
  while ((UCSRA & (1 << RXC)) == 0);
4
  return UDR;                  // Zeichen aus UDR an Aufrufer zurueckgeben
5
}
eine zusätzliche Ausgabe des gerade empfangenen Zeichens einbauen.
Mitlesen zu können, was vom GPS kommt und ab wann es dann klemmt, könnte 
einigen Aufschluss darüber geben, was da im System los ist.

von Dieter F. (Gast)


Lesenswert?

Alexander Plöger schrieb:
> Ich hab dir ne PN geschickt.

Hallo Alexander,

mache ich heute Abend. Ein virtuelles Weizenbier ist immer willkommen 
:-)

Gruß
Dieter

von Dieter F. (Gast)


Lesenswert?

Hallo Alexander,

aus einem anderen Post hier habe ich:

In der wait_while_chip_is_busy() Funktion muss es statt
1
  LCD_CMD_PORT &= ~(1<<CD);
2
  LCD_CMD_PORT |=(1<<RW)|(1<<EN);
3
  _delay_us(1);

heissen:
1
  LCD_CMD_PORT &= ~(1<<CD);
2
  LCD_CMD_PORT |=(1<<RW);
3
  LCD_CMD_PORT |= (1<<EN);
4
  _delay_us(1);
Macht Sinn (und ist lt. Datenblatt auch erforderlich), dass zunächst 
Read/Write gewählt wird und etwas später (Tasu - ist zwar im Datenblatt 
gezeichnet aber nicht in ns angegeben) - ich würde mal mindestens 10 ns 
analog Tah nehmen - der Enable-Impuls kommt.
Die Ausführungszeit der Zuweisung LCD_CMD_PORT |=(1<<RW); reicht dafür 
dann (bei 8 MHz Takt) wahrscheinlich aus.

Die busy-Flag-Abfrage nutze ich eigentlich nie bei den LCD-Displays 
(weil ich auch mit SPI-Ansteuerung "herumspiele") und setze statt dessen 
immer auseichende _delay(..)-Statements ein. Wird im vorgenannten Post 
auch beschrieben.

Ist aber egal, wenn mit dieser Korrektur alles läuft kannst Du ja auch 
nicht meckern :-)

Falls ich keine Erfolgsmeldung von Dir lese debugge ich heute Abend ...

Gruß
Dieter

: Bearbeitet durch User
von Dietrich L. (dietrichl)


Lesenswert?

Alexander Plöger schrieb:
> Ich nutze übrigens einen Atmega16. Momentan noch mit 8Mhz internen Takt.

Ist der Takt für die Baudrate vielleicht nicht genau genug?
Außerdem vermisse ich
1
#define F_CPU 8000000UL
am Programmanfang.

Gruß Dietrich

von Alex P. (alex2203)


Lesenswert?

Also ich hab nun die Lösungsvorschläge eingearbeitet und ausprobiert. 
Alle ohne Erfolg. Ich komm einfach nicht drauf, wieso er in den Code 
geschriebene Texte und zB von Int nach String umgewandelte Variablen 
anzeigt aber das GPS Signal nicht....

von holger (Gast)


Lesenswert?

>Also ich hab nun die Lösungsvorschläge eingearbeitet und ausprobiert.
>Alle ohne Erfolg. Ich komm einfach nicht drauf, wieso er in den Code
>geschriebene Texte und zB von Int nach String umgewandelte Variablen
>anzeigt aber das GPS Signal nicht....

Zeig dein komplettes Programm. Woher soll jemand wissen
welchen Bockmist du da jetzt schon wieder eingebaut hast?

von Alex (Gast)


Lesenswert?

Niveau wird nicht in blauen Dosen verkauft Holger. Außer nicht 
konstruktiver Kritik kam von dir hier auch noch nichts! Spar sie dir für 
jemand anderen um dort dein Unwissen zu verbergen.

von holger (Gast)


Lesenswert?

>Niveau wird nicht in blauen Dosen verkauft Holger. Außer nicht
>konstruktiver Kritik kam von dir hier auch noch nichts!

Doch, aber unter anderem Namen.

>Spar sie dir für
>jemand anderen um dort dein Unwissen zu verbergen.

Kein Sourcecode, keine Antworten.
Mal sehen wer länger durchhält.

von Alex P. (alex2203)


Lesenswert?

Ja, schauen wir mal.
@ Dietrich. Danke für den Hinweis :) Im Code isses eingetragen, 
anscheinend hats das (hab ich es zwinker ) hierher aber nicht 
übertragen.

Gruß

Alex

von dummy (Gast)


Lesenswert?

>Der Text nach der uart_gets wird
>nicht angezeigt. Das bedeutet doch das er uart_gets nicht abarbeitet
>oder irre ich mich da?

Richtig. Der bleibt scheinbar einfach hängen.

>Ich nutze übrigens einen Atmega16. Momentan noch mit 8Mhz internen Takt.

Hast du mal kontrolliert ob der auch mit 8MHz läuft?
Vieleicht läuft der ja nur mit 1MHz. Fuses?
Dann stimmt die Baudrate nicht. Oder es kommt gar kein
GPS Signal am ATMega an.

Das sind die Dinge die du kontrollieren musst.

von spess53 (Gast)


Lesenswert?

Hi

>Dann stimmt die Baudrate nicht. Oder es kommt gar kein
>GPS Signal am ATMega an.

Mit dem internen RC-Oszillator ist die korrekte Baudrate eher 
Glückssache.

MfG Spess

von Alex (Gast)


Lesenswert?

Ich danke Dieter auf diesem Wege auch nochmals für die Lösung meines 
Problems :)
Es lag an verschiedenen Kleinigkeiten. U.a. das die Schriftart static 
und nicht const war.

Danke dir. Prost :D


Alex

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.