Forum: Mikrocontroller und Digitale Elektronik Display3000-UART-Problem


von Markus V (Gast)


Lesenswert?

Hallo,

ich möchte gerne die ASCII-Daten eines GPS-Empfängers mit einem 
Mikrocontroller auslesen und auf einem Display darstellen. Der 
GPS-Empfänger hat einen direkten seriellen Ausgang und ist mit 9600 Baud 
(8N1) konfiguriert. Über ein USB-RS232-Adapter (von Belkin) kann ich mir 
die Ausgabe mit einem Terminalprogramm anzeigen; also funktioniert alles 
soweit.

Jetzt habe ich
- ein Olimex MT-128 (ATmega128 mit 16x2-LCD) 
http://www.olimex.com/dev/avr-mt128.html und
- ein Display3000-D071x (auch ATmega128 mit Farbdisplay) 
http://www.shop.display3000.com/bauteile/d071x-mikrocontroller-atmega-tft-farbdisplay-21.html. 
(externer 16MHz-Quarz auf Display3000 wird verwendet!)

Auf beiden µC's läuft (im Prinzip) folgendes Programm:


#define F_CPU       16000000L
#define OSCSPEED  16000000L    /* in Hz */

#include <stdio.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include <math.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#define LCD_DDR DDRB

[...]

ISR(USART1_RX_vect) {

  unsigned char Ch = UDR1;

  // "$" kommt auf jeden Fall in den Daten vor, aber es wird nicht 
erkannt...
  if (Ch == '$') {
    LCD_Print("GPS", 1, 1, 1, 1, 1, black, white);     // wird nie 
ausgegeben...
  }

}


void UART_Init(uint32_t Baud)
{

    unsigned int BaudRate = 103; // OSCSPEED / (16 * Baud) - 1;

    UBRR1H = (unsigned char) (BaudRate>>8);
    UBRR1L = (unsigned char) BaudRate;

    UCSR1C = 0x06; // 0b0000|0110 = character size 8bit
    UCSR1B = ( (1<<RXCIE1) | (1<<RXEN1) );

}


int main(void) {

    LCD_Init();
    LCD_Cls(white);

    delay_ms(1000);

    UART_Init(9600);

    delay_ms(1000);

    Orientation = Landscape180; //Portrait180;

    sei();

    while(1) {

  delay_ms(250);

    }

    return 0;

}


Aber nur über das Olimex-Board funktioniert das Lesen von Zeichen vom 
GPS-Empfänger (per Nullmodem-Kabel). Beim Display3000-Modul klappt es 
nicht, d.h. es werden nur viele "?" auf dem Display dargestellt. Ich 
kann jedoch über ein Terminalprogramm und USB-RS232-Adapter einzelne 
Zeichen ans Display3000-Modul schicken. Diese werden richtig 
dargestellt.

Woran kann es liegen, dass das Display3000-Modul über den Adapter lesen 
kann, aber nicht über das (einfacherer) Nullmodemkabel? Die Ursache muß 
doch irgendwie am USB-RS232-Adapter liegen, oder?

Bin für jede Hilfe dankbar!

Gruß,
Markus

von Basti (Gast)


Lesenswert?

Sind die Fuses richtig gesetzt (Quarz)
Kannst du normalen Text ausgeben? (Hello World)
Ich erinnere mich Dunkel dass irgendwas gejumpert werden musste. Mal ins 
Doku geschaut? Display3000 sind sehr hilfsbereit. Mal anrufen...

von Juergen A. (juergen_a)


Lesenswert?

Hi,
ich würde den String komplett einlesen und erst danach auf dem Display 
ausgeben.
Glaube nicht, dass die Ausgabe in der ISR funktioniert.

Bei mir war es auch so, dass zwischen zwei LCD_Print-Aufrufen einige ms 
Pause sein mussten.

Viel Erfolg,
Jürgen

von Markus V (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

Danke für Eure schnellen Antworten!

Die Fuses sind meines Erachtens richtig gesetzt (siehe Anhang).

Ich habe jetzt alle Display-Funktionen aus der ISR-Routine rausgenommen 
und zähle einfach nur noch die Anzahl der ankommenden Nachrichten (die 
mit "$" beginnen und jede Sekunde kommen). Bei jeder dritten Nachricht 
soll "GPS" auf dem Display erscheinen. Damit sollte der Controller nicht 
überfordert sein...

Aber es ist wie vorher: Wenn ich vom Terminalprogramm aus (inkl. 
USB-RS232-Adapter) irgendwas eingebe, werden die "$"'s korrekt gezählt 
und die "GPS"-Ausgabe erscheint nach jeweils drei "$"'s. Aber es klappt 
nicht mit der direkten Verbindung (direktes Kabel und/oder 
Nullmodemkabel). Es wird überhaupt nichts gezählt.

Hier das Programm:
#define F_CPU       16000000L
#define OSCSPEED  16000000L    /* in Hz */

#include <stdio.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include <string.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#define LCD_DDR DDRB
#include <glcd-Display3000-211.h>
extern const prog_uint8_t Font1[], Font2[];

char message0[120];
int  message0Pos = 0;
int  messageCounter = 0;
int  previousmessageCounter = 0;
int  row = 1;
int  col = 1;


ISR(USART1_RX_vect) {

  unsigned char Ch = UDR1;

  if (Ch == '$') { message0Pos = 0; messageCounter++; }

}


void UART_Init(uint32_t Baud) {

    unsigned int BaudRate = 103; // OSCSPEED / (16 * Baud) - 1;

    UBRR1H = (unsigned char) (BaudRate>>8);
    UBRR1L = (unsigned char) BaudRate;

    UCSR1C = 0x06; // 0b0000|0110 = character size 8bit
    UCSR1B = ( (1<<RXCIE1) | (1<<RXEN1) );

}

int main(void) {

    LCD_Init();  // caution: this also defines SPI for the display and 
also PortB (all ports but MISO are output)
    LCD_Cls(white);

    delay_ms(1000);

    UART_Init(9600);

    delay_ms(1000);

    Orientation = Landscape180; //Portrait180;

    LCD_Print("TEST", 1, 70, 3, 3, 3, black, white);

    delay_ms(1000);

    sei();

    while(1) {


       if ((messageCounter > 0 ) && (messageCounter % 3 == 0)) {

           LCD_Print("GPS", col, row, 1, 1, 1, black, white);
           delay_ms(50);

     row = row + 10;
           messageCounter = 0;

        //delay_ms(50);

  }

     }

     return 0;

}

Sehr komisch... Habt Ihr noch einen Rat? Vielen Dank,
Markus

von x64 (Gast)


Lesenswert?

Längere Quelltexte bitte als Anhang posten.

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.