Data aus USART vom SAM7-EX256 lesen

OP #4209565
Lesenswert?

Hallo,

ich möchte die GPS-Daten vom Board Olimex SAM7-EX256 lesen und diese 
durch den Terminal Putty auf meinem Rechner anzeigen. Das GPS ist an 
USART1 (RxD0) angeschlossen und der USB-RS232 Adapter an RS232 (USART0) 
des Boards und am PC angeschloßen. Wie es im Code zu sehen ist, habe ich 
erstmal USART0 und USART1 initialisiert und dann zwei Funktionen read 
und write erstellt. Wenn ich den Code auf dem Board flashe, kriege ich 
nichts auf Putty. Ich habe den Code schon mehrmals untersucht, um zu 
sehen, ob ich vielleicht etwas entweder bei der Initialisierung oder 
woanders vergessen habe, aber ich komme immer nicht voran.

Hätte ich vielleicht vergessen oder falsch gemacht?
Angehängte Dateien:
Gast #4212114
Lesenswert?

HI
1
//set baud rate divisor register
2
  u_pUSART1->US_BRGR = 78; //((48000000)/38400x16)
Das ist schlecht!!!
Entweder ein Define verwenden oder aber richtig machen und die aktuelle 
Frequenz aus den Register holen!
Mit der Frequenz kannst du auch dann den Wert richtig ausrechnen lassen.
1
#define EXT_OC          18432000   // Exetrnal ocilator MAINCK
2
#define MCK             47923200   // MCK (PLLRC div by 2)
3

4
unsigned long ctl_at91sam7_get_mck_frequency(unsigned long mainck_frequency);

Die define's sind Standard, aber die Funktion ist von CrossWorks die 
kann ich hier nicht reinschreiben(bin nicht sicher, lieber nicht).
Aber auch andere habe schon solche Funktion gebaut.(Bing ist dein 
Freund)

Warum nimmst du nicht die Beispiele von Atmel?(sind zwar alt aber..)
Bei mir liefen die auf dem Board direkt.

viel Spaß
OP #4213443
Lesenswert?

Stephan schrieb:
> Warum nimmst du nicht die Beispiele von Atmel?

Hi Stephan,

und dke für deine Antwort. Meinst du vielleicht das Beispiel über 
Serial?Wenn ja, dann habe ich schon angeschaut  aber ich musste ein paar 
Anpassungen machen wie es im Anhang zu sehen ist. Zu Bsp die Baudrate; 
Mein GPS läuft mit einer Baudrate von 38400 bps. Deswegen habe ich im 
US_BRGR den Wert 78 = MCK/(16*38400). Übrigens, ich habe diese Formel 
aus dem Datasheet genommen, weil ich im Asynchronous Mode bin und OVER = 
0 (siehe den Wert, der im US_MR geschrieben wird).
Gast #4213490
Lesenswert?

Hi Yann,
ja aber könntest du so nicht einfach ein 'Hello World' für deine UART 
Ausgabe schreiben?
Alles so lassen und an einem Terminal prüfen ob es läuft, dann deine 
Änderungen machen und Spass haben. :-)

Wie ist denn deine PLL eingestellt? (Code?)
Gast #4214082
Lesenswert?

hi,
klar, mit welcher Frequenz läuft denn dein MC?
doch nicht etwa mit dem SLOW CLOCK? oder mit der Quarz-Frequenz?

Eigentlich glaube ich es ja nicht, aber hast du deinen Startup-Code 
geändert?
Normalerweise sind doch alle Beispiele auf die 48MHz ausgelegt.
Gast #4214308
Lesenswert?

HA erwischt!
Da muss die PLL ja programmiert sein!
Sonst kann der MC KEINE 48MHz!

Hier kann einiges schief gehen, deshalb der Hinweis das du die Frequenz 
die gerade genutzt wird, wieder aus den MC auslesen sollst.

Aber OK, teste mit deinem 'Hello World' Programm, das sollte dir genug 
Punkte zur Fehlersuche im richtigen Programm geben können.

Wenn noch Fragen offen sind, frag einfach. :-)
OP #4214429
Lesenswert?

Dieses Programm habe ich gerade geschrieben und es basiert sich auf das 
"Hello worl" Programm mit ein paar Anpassungen. Aber, wenn ich das 
Programm debugge, kriege das beigefügte screenshot: Das sind aber keine 
GPS Daten. Entweder ist liegt es an meinem Code oder liest irgendwas auf 
RXD1 aus.

Ansonsten hätte ich noch eine Frage: Kann ich direkt im US_RHR Charakter 
schreiben, Wie ich sogar gemacht habe? Oder müssen nur die Adressen 
sowohl in RHR als auch im THR geschrieben werden?

Ich freue mich wieder auf eure Meldungen.

Yann

Anhang: Code1 und debug_result1
Angehängte Dateien:
#4214446
Lesenswert?

Yann B. schrieb:
> Dieses Programm habe ich gerade geschrieben und es basiert sich auf das
> "Hello worl" Programm mit ein paar Anpassungen.

Und das "Hello, World" war im putty zu lesen? Dein Fehler sieht nämlich 
nach flasch programmierter Baudrate aus.

Mit dem Debugger könnte man sich anschauen, ob die Daten beim GPS UART 
falsch rauskommen oder nur am PC die Daten falsch ankommen.

Achtung: Das RHR besser nicht direkt im Debugger lesen, sondern ein 
gelesenes Byte in einer Variable (besser: Array) speichen und die dann 
auslesen. Das Lesen vom UART im Debugger kann unerwartete Nebenwirkungen 
haben.
OP #4214504
Lesenswert?

Jim M. schrieb:
> Und das "Hello, World" war im putty zu lesen?

Ja.

>Mit dem Debugger könnte man sich anschauen, ob die Daten beim GPS UART
>falsch rauskommen oder nur am PC die Daten falsch ankommen.

Was meinst du eigentlich damit? Wenn ich das GPS Modul direkt am PC 
anschließe erhalte durch PUTTY richtige Daten.

>Achtung: Das RHR besser nicht direkt im Debugger lesen, sondern ein
>gelesenes Byte in einer Variable (besser: Array) speichen und die dann
>auslesen. Das Lesen vom UART im Debugger kann unerwartete >Nebenwirkungen
>haben.

Danke für den Tipp, ich probiere gleich ohne Debug aus. Und was ist mit 
THR? Darf ich auch direkt den Inhalt von RHR drin schreiben oder lässt 
dies nur Adresse zu?
Gast #4214577
Lesenswert?

Hi,

so das 'Hello World' ist gelaufen?!?
Dann muß der Quarz und die PLL richtig sein.
(die INIT der UARTs sollten dann auch richtig sein)

1
char* nmea_data = 0x0;
was ist das?
Das mit dem SAM7 ist schon lange her, aber liegen nach einem REMAP nicht 
in INT-Vectoren an der Adresse???
Wenn kein REMAP erfolgte, war dann nicht der Flash-Speicher an der 
Adresse, das müßte dann aber in einem RESET des MCs enden.

Bitte mach das weg und sag was du damit vorhast, du solltest nicht in 
den Speicher wild deine Daten schreiben.

Wenn das ein Debug-Buffer sein sollte geht es vielleicht so:
1
void read_write_ch(char* tempbuf, int lenght){
2
  static int i=0;
3
  while((u_pUSART1->US_CSR & AT91C_US_RXRDY)==1)
4
  {
5
    tempbuf[i]= u_pUSART1->US_RHR;
6
    if(tempbuf[i] != '\0' )
7
    {
8
      while (!(u_pUSART0->US_CSR&AT91C_US_TXRDY));
9
      u_pUSART0->US_THR = tempbuf[i];
10
    }
11
    i++;
12

13
    if (i >= lenght)
14
      i= 0;
15
  }
16
}
17

18
int main (void)
19
{
20
  char nmea_data[10]={0};
21
   
22
  InitUSART0();
23
  InitUSART1();
24
  while (1){
25
    read_write_ch(&nmea_data[0], 10);
26
  }
27
}
nicht getestet!
Gast #4214581
Lesenswert?

Yann, könntest du das Programm so erweitern und nochmal einen Screenshot 
machen?
Danke.
1
int main (void)
2
{
3
  char nmea_data[10]={0};
4
   
5
  InitUSART0();
6
  InitUSART1();
7

8
  // einfach ein Hallo ausgeben
9
  printfUSART0("Hallo");
10
  // oder einfacher
11
  putsUSART0("Hallo");
12

13
  while (1){
14
    read_write_ch(&nmea_data[0], 10);
15
  }
16
}
OP #4215172
Lesenswert?

Stephan schrieb:
> char* nmea_data = 0x0;
> was ist das?

Sorry es war ein Fehler. Ich wollte den Zeiger initialisieren. Wenn ich 
den Code teste, erhalte ich den beigefügten Anhang (gps_test_2). Ich 
konnte das "printf" nicht benutzen, weil das Programm die <stdio.h> Lib 
nicht finden konnte.

Kommischerweise, wenn ich die Baudrate ändere (baud = 9600 -> US_BRGR = 
313) bekomme ich trotzdem Daten, die leider auch keine GPS-Daten sind. 
Ist es überhaupt möglich?
Angehängte Dateien:
Gast #4215272
Lesenswert?

Yann was machst du bloß? :-|
1
int uart0_putc(int ch)
2
{
3
    while (!(u_pUSART0->US_CSR & AT91C_US_TXRDY));   // Wait for Empty Tx Buffer
4
    return (u_pUSART0->US_THR = ch);                 // Transmit Character
5
}
6

7
int uart0_putchar(int ch) {                      // Write Character to Serial Port
8

9
  if (ch == '\n')                               // Check for LF
10
  {
11
    uart0_putc( '\r' );                         // Output CR
12
  }
13
  return uart0_putc( ch );                     // Transmit Character
14
}
15

16
int uart0_puts( char* s )
17
{
18
    int i = 0;
19
    while ( *s )
20
    {
21
        uart0_putchar( *s++ );
22
        i++;
23
    }
24
    return i;
25
}
hier mal ein kleines puts zusammen kopiert. Bitte den Code prüfen!

gib doch zum Testen nochmal das mit aus:
1
uart0_puts("Hallo PC");

Yann B. schrieb:
> Kommischerweise, wenn ich die Baudrate ändere (baud = 9600 -> US_BRGR =
> 313) bekomme ich trotzdem Daten, die leider auch keine GPS-Daten sind.
> Ist es überhaupt möglich?

Sicher schau dir nochmal an wie die Daten von UART (RS232) decodiert 
werden.

Ich hab in einer alten Datei von Atmel dies noch gefunden:
1
//*----------------------------------------------------------------------------
2
//* \fn    AT91F_US_Baudrate
3
//* \brief Caluculate baud_value according to the main clock and the baud rate
4
//*----------------------------------------------------------------------------
5
__inline unsigned int AT91F_US_Baudrate (
6
  const unsigned int main_clock, // \arg peripheral clock
7
  const unsigned int baud_rate)  // \arg UART baudrate
8
{
9
  unsigned int baud_value = ((main_clock*10)/(baud_rate * 16));
10
  if ((baud_value % 10) >= 5)
11
    baud_value = (baud_value / 10) + 1;
12
  else
13
    baud_value /= 10;
14
  return baud_value;
15
}
16

17
//*----------------------------------------------------------------------------
18
//* \fn    AT91F_US_SetBaudrate
19
//* \brief Set the baudrate according to the CPU clock
20
//*----------------------------------------------------------------------------
21
__inline void AT91F_US_SetBaudrate (
22
  AT91PS_USART pUSART,    // \arg pointer to a USART controller
23
  unsigned int mainClock, // \arg peripheral clock
24
  unsigned int speed)     // \arg UART baudrate
25
{
26
  //* Define the baud rate divisor register
27
  pUSART->US_BRGR = AT91F_US_Baudrate(mainClock, speed);
28
}
Wenn du mit dem puts auch keine Ausgabe siehst, prüfe nochmal das 
Baudraten Register, bitte.

Wenn das auch nicht klappt, bin ich mit meiner Weisheit auch am Ende.
Sorry.

zum Bluescreen kann ich leider auch nichts sagen.
Gast #4216205
Lesenswert?

Wow, gut gemacht Yann.

Aber was soll denn dann das Problem im eigentlichen Programm sein?
Kann es sein das der GPS Sensor eine andere Einstellung in der 
Übertragung hat? mit Parity vielleicht?

Versuche alle möglichen Einstellungen der UART(Parity und die andern) 
durch zu testen, dann solltest du schnell ein Ergebnis haben. Sind ja 
nicht all zu viele. ;-)
Gast #4222717
Lesenswert?

Stephan W. schrieb:
> noch dran oder hast schon aufgegeben?

Nee habe ich nicht, ich bin noch dran. Sag mal, ich verwende das GPS 
Modul NL-650ERS von Navilock  sein dritter Pin-Anschluss ist Schield. 
Wozu dient er eigentlich? Ich habe danach recherchiert (auch im 
Datenblatt des GPS) und konnte leider die Frage nicht beantworten. Wenn 
ich das GPS Modul direkt zum PC anschließe, verwende ich nur TX, GND und 
+5V; RX und Schield sind frei (auf der Luft).
Angehängte Dateien:
#4222811
Lesenswert?

Hi,
da biste ja wieder. :-)

Yann schrieb:
> dritter Pin-Anschluss ist Schield.
> Wozu dient er eigentlich?

Da sind die Abschirmbleche drauf, je nachdem wie 'dreckig' die Umgebung 
ist, (Störfrequenzen) desto mehr muß man für die Entstörung tun.

Ich bin mir zwar nicht 100% sicher, aber im Labor wird ich ihn mit GND 
verbinden, aber in der freien Wildbahn....

Auf den 3. Bild steht RS232 xxx an den PINs, jetzt sag nochmal wie du 
den PC und den GPS Baustein angeschlossen hast?

Yann B. schrieb: vom 1. Beitrag:
> Das GPS ist an
> USART1 (RxD0) angeschlossen und der USB-RS232 Adapter an RS232 (USART0)
> des Boards und am PC angeschloßen.
Ich hab mir einmal das olimex board angesehen (Rev C) und glaube den 
Grund für dein nicht funktionieren gefunden zu haben.
DAS Board hat nur 1 ST3232 (RS232) Baustein und da liegt entweder die 
DEBUG oder die USART0(RxD0) Schnittstelle dran!
USART1(RxD1) liegt dort nur als TTL Signal am UEXT(10pol) vor!
KEIN RS232!
Der 2. DSUB ist ein CAN Interface!

Stephan
Gast #4222873
Lesenswert?

Stephan W. schrieb:
> Ich hab mir einmal das olimex board angesehen (Rev C)

Wo hast du es angehängt? Ist es das SAM7-EX256 von Olimex?

Stephan W. schrieb:

>DAS Board hat nur 1 ST3232 (RS232) Baustein

Ja aber es hat 2 RS232 Schnittstellen (USART0 und USART1). Hiermit den 
Links aufs Board:
https://www.olimex.com/Products/ARM/Atmel/SAM7-EX256/

> USART1(RxD1) liegt dort nur als TTL Signal am UEXT(10pol) vor!
> KEIN RS232!
Richtig!
Zwar liegt es auf USART1(RXD1 und TXD1) LVTTL Signale aber warum steht 
auf der Seite 21 des Datenblatts folgendes: RS232 1 Receive und RS232 1 
Transmit? (siehen das angehängte Screenshot darüber).

Ansonsten hast du völlig Recht, auf EXT und UEXT sind LVTTL Pegel. Würde 
es also bedeuten, dass ich den Pegelwandler wie den Max232 bräuchte, 
falls ich die USART1 Verwenden soll?

Außerdem habe ich gerade noch gelesen, dass die beiden USART eigene 
Baudrate haben (Seite 27, Absatz 7.6 RS232). Auf der Seite 28 steht 
auch, dass RS232 mit 9600 als Baudrate arbeitet. Heißt es eigentlich, 
dass der Wert der Baudrate nicht änderbar oder einstellbar ist?

Jetzt würde ich nur mit dem USART0 auch probieren und ich melde mich 
noch später.
Angehängte Dateien:
Gast #4222888
Lesenswert?

Stephan W. schrieb:
> Auf den 3. Bild steht RS232 xxx an den PINs, jetzt sag nochmal wie du
> den PC und den GPS Baustein angeschlossen hast?

GPS                       RS232-USB ADAPTER
          +5V
            |
1:+5V ------|
4: TXD ------------------> PIN 2 (RXD)
5: GND ---->|<-----------  PIN 5 (GND)
            |
            GND

Die +5V erzeuge ich mit einem Stecker-Netzgerät. GND liegt auch darauf.
#4222960
Lesenswert?

Yann schrieb:
> Wo hast du es angehängt? Ist es das SAM7-EX256 von Olimex?

angehängt nicht, aber der Link von dir war richtig.
mit Rev C war der Schaltplan gemeint:
SAM7-EX256 REV.C schematc -> 
https://www.olimex.com/Products/ARM/Atmel/SAM7-EX256/resources/SAM7-EX256_Rev_C-sch.pdf

Yann schrieb:
> aber warum steht
> auf der Seite 21 des Datenblatts folgendes: RS232 1 Receive und RS232 1
> Transmit? (siehen das angehängte Screenshot darüber).

das wäre nicht richtig!

Yann schrieb:
> Ansonsten hast du völlig Recht, auf EXT und UEXT sind LVTTL Pegel. Würde
> es also bedeuten, dass ich den Pegelwandler wie den Max232 bräuchte,
> falls ich die USART1 Verwenden soll?

keinen MAX232 (5V), einen LVTTL zu RS232, wie den ST3232 oder MAX3232!

Yann schrieb:
> Außerdem habe ich gerade noch gelesen, dass die beiden USART eigene
> Baudrate haben (Seite 27, Absatz 7.6 RS232).

Ich hatte dir doch die Funktion "AT91F_US_SetBaudrate" gegeben, dort 
wird doch auch die UART mit übergeben! DIE 3 Schnittstellen DBUG, UART0 
und UART1 sind komplett unabhängig, jede muss einzeln konfiguriert 
werden!

Yann schrieb:
> dass RS232 mit 9600 als Baudrate arbeitet. Heißt es eigentlich,
> dass der Wert der Baudrate nicht änderbar oder einstellbar ist?

NEIN! In dem Beispiel Code für das Board, sind die Funktionen 
"InitUSART0" und "InitUSART1" hart auf 9600bps programmiert. Das soll 
den Einstig in die SW Projekte erleichtern. DU kannst die Baudrate 
ändern wie du willst. ;-)

Dein Bild zum Sensor und PC ist richtig!
Jetzt nur einen 3V LVTTL zu RS232 Wandler aus der Bastelkiste und den 
UART1 anschließen und dein Programm sollte laufen.
(Wenn die Schnittstellen richtig eingestellt ist)

Stephan
OP #4237948
Lesenswert?

Wieder da. Seitdem ich den Adapter bestellt habe ich es von Amazon noch 
nicht bekommen und ich habe mich dazwischen mit dem LCD-Display 
beschäftigt. Mein Ziel ist die GPS Daten jetzt auf dem Display 
anzuzeigen. Ich habe bis jetzt das LCD und das GPS Modul so 
programmiert, dass wenn ich auf dem Switch 1 drücke dann sollte 
mindesten die UTC-Zeit angezeigt werden. So sieht das Szenario aus:

1) Beim Start wird das welcome angezeigt

2) Nach 10 Sek wird dem User 2 Optionen als Menu vorgeschlagen:
 Drücken Sie:
   - SW1: um die Position anzuzeigen
   - SW2: Quit

Wenn der User auf SW1 drückt dann wird der Bildschirm gelöscht und die 
Position sollte wie folgendes angezeigt werden:
    Longitude: ....
    Latitude : ....
    UTC_Time : ....

Wenn ich das programme ausführe passieren die beiden Szenarien (1 und 2) 
mit Erfolg. Aber wenn ich jetzt auf SW1 drücke passiert nichts. Wenn ich 
aber die Funktion parseGGA() auskommentiere, dann ich kriege das Bild 1. 
Ich möchte mich zunächst auf dem Inhalt von UTC_Time nicht 
konzentrieren, weil ich den Pointer im struct nicht initialisiert habe.

mein Problem ist folgendes:

Woran könnte es liegen, dass wenn ich meine Funktion parseGGA() in main 
aufrufe, dann passiert nichts beim Drücken auf Switch 1. Gibt es 
vielleicht etwas Falsches in meiner parseGGA(), was das Programm an 
dieser Stellt blockiert? Weil ich das Programm schon mehrmals überprüft 
habe und bis jetzt noch nichts gefunden, was der Grund sein könnte.

Anbei die verschiedenen betroffenen Funktionnen.
Angehängte Dateien:
OP #4238025
Lesenswert?

Ich konnte selber ein paar Fehler herausfinden. Deswegen habe ich den 
Code angepasst.

Ach so, im ersten vorherigen Post habe ich vergessen, die Rolle der LED 
zu erwährnen. Also, sie sollte leuchten, wenn ein Charakter empfangen 
wird. Nachdem ich gerade den Code angepasst habe und ausgeführt bleibt 
die LED aus. Also gehe ich davon aus, dass entweder das GPS Modul keine 
Daten empfängt oder liegt an der Maskierung in der 
read_char_USART0_nonstop().

Außerdem, wenn ich die Funktion parseGGA in der endlosen while-Schleife 
aufrufe, dann wird nur den UTC_Time beim Drücken auf Switch 1 angezeigt. 
Also nehme ich an, dass das Problem am Source gps.c liegt aber ich weiß 
nicht wo genau.

Irgendweche Idee oder Anmerkung?

Vielen Dank im voraus
Angehängte Dateien:
Gast #4240459
Lesenswert?

Yann kann es sein das du hier ein Copy & Paste Fehler hast?

char *gga_msg1;

Das ist nur ein Pointer! Du wolltest aber dies hier 'wahrscheinlich'

char gga_msg1[100];
parseGGA(&gga_msg1,position1);

Das ist doch auch nur ein Pointer, enthält keine Strukt!!!!
nmea_GGA_tp position1;

nmea_GGA_t  EchtePosition1;
position1= &EchtePosition1;

also die Files vom 18.08.2015 00:24 Uhr
sehen da besser aus, als die vom 18.08.2015 07:05 Uhr
Kann das sein das die sich gar nicht kompilieren lassen???(von 7:05)

Ein kleiner Tip, wenn deine Funktionen mit 'Pointern auf Buffern' 
arbeiten, gib immer die Größe des Buffers mit, So kann die Funktion 
erkennen, wann sie aufhören muss in den Speicher zu schreiben.(Buffer 
overflow)
OP #4251523
Lesenswert?

Sorry, ich war krank.
Stephan schrieb:
> Yann kann es sein das du hier ein Copy & Paste Fehler hast?

Copy & Paste Fehler!!!

Stephan schrieb:
> Ein kleiner Tip, wenn deine Funktionen mit 'Pointern auf Buffern'
> arbeiten, gib immer die Größe des Buffers mit, So kann die Funktion
> erkennen, wann sie aufhören muss in den Speicher zu schreiben.(Buffer
> overflow)

dke für den Tip. Leider kann ich noch nicht die Zeit auf dem Display 
anzeigen lassen. Das Problem ist, dass das GPS Modul kontinuerlich die 
Daten sendet. Die Funktion get_gga_string() ist eigentlich die Funktion 
get_gps_string(), die hier anbei liegt. Diese musste ich noch anpassen, 
aber beim Testen kann ich nur das erste Zeichen des gespeicherten 
Strings nämlich das $ Zeichen anzeichen lassen. Andere Elemente des 
Buffers werden nicht angezeigt und ich habe mich schon lange gefragt, 
was das Problem sein könnte. Ich habe viel recherchiert, um zu sehen, wo 
der Fehler liegt aber ich bin komme immer noch nicht voran.

Ich bitte euch wirklich um Hilfe, sonst werde ich verrückt sein.
Angehängte Dateien:
OP #4251562
Lesenswert?

Ich habe den Fehler gefunden. Vielleicht habt ihr auch gesehen. Der 
Fehler lag in der zweiten do Schleife. Da war die if-Anweisung 
auskommentiert. Jetzt kann ich andere Elemente des Buffers auf dem 
Display anzeigen lassen.

Anbei ein Ergebnis.

Wie gesagt mein Ziel ist die UTC_Zeit aus dem GGA zu holen und 
anzuzeigen. Ich mache jetzt Schritt für Schritt, weil der ganze Code zum 
ersten Versuch nicht funktioniert hat.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren