Forum: Mikrocontroller und Digitale Elektronik Atmega128 USART sendet aber empfängt nicht


von Stefan H. (stefan0985)


Lesenswert?

Hallo
ich habe folgendermaßen meinen USART0 initialisiert:

void USART_Init( void)
{
UCSR0B|=(1<<TXEN0)|(1<<RXEN0);

UCSR0C |=(0<<UMSEL0)|(0<<UPM00)|(0<<UPM01)|(0<<USBS0)|
(1<<UCSZ00)|(1<<UCSZ01)|(0<<UCPOL0);//asynchronous mode; parity 
dissabled
            //1 stop bit; character size: 8bit
                  //clock polarity:0 (asynchr.mode)
    UBRR0H = UBRR_VAL >> 8;
    UBRR0L = UBRR_VAL & 0xFF;

}

wobei ich die Baudrate berechne wie es im Artikel zu UART beschrieben 
wird.

Weiterhin, habe ich diese Funktionen um zu senden/empfangen

int uart_putc(unsigned char c)
{
    while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
    {
    }

    UDR0 = c;                      /* sende Zeichen */
    return 0;
}
void uart_puts (char *s)
{
    while (*s)
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
        uart_putc(*s);
        s++;
    }
}

uint8_t uart_getc(void)
{

while(!(UCSR0A & (1<<RXC0)))
;
return UDR0;
}



int main (void)
{


USART_Init();



while(1)
{

uart_puts("Hallo");
NextChar=uart_getc();
while(NextChar !='\n')
{
NextChar=uart_getc();
}
uart_puts("Tschuess");

}//while
}//main

Senden funktioniert einwandfrei. Ich bekomme mein Hallo, aber meine 
Eingabe '\n' wird nie erkannt. Die Schleife müsste doch so passen?

Wär echt super wenn mir jemand helfen könnt. Ich habe echt schon viel 
probiert. Auch folgendes ging nicht:

void uart_gets(char* Buffer, uint8_t MaxLen)
{

  uint8_t NextChar;
  uint8_t StringLen=0;

  NextChar=uart_getc();

  while(NextChar !='\n' && StringLen<MaxLen-1)
  {
  *Buffer++=NextChar;
  StringLen++;
  NextChar=uart_getc();
  }

  *Buffer='\0';



}


char Line[40];

int main(void)
.
.
.
while(1)
{

  uart_gets( Line, sizeof( Line ) );
  uart_puts(Line);
}
}

Vielen Dank schon mal

von Karl H. (kbuchegg)


Lesenswert?

Stefan Haller schrieb:

> Senden funktioniert einwandfrei.

Gut. Das ist schon mal was.

> Wär echt super wenn mir jemand helfen könnt.

Wenn etwas nicht funktioniert, musst du dir Techniken überlegen, wie du 
überprüfen kannst, warum es nicht funktioniert. Dazu muss man sich 
überlegen, ws eigentlich schief gehen kann.
In deinem Fall gibt es 2 Möglichkeiten
* es wird überhaupt nichts empfangen
* das, was empfangen wird, ist falsch.

Also solltest du dir überlegen, wie du dein Programm so verändern 
kannst, das du feststellen kannst, was passiert und welchen Fall du 
vorliegen hast.

Eine Möglichkeit besteht darin, dass du nach dem uart_getc() etwas 
machst, was dir verrät
* das ein Zeichen empfangen wurde
* welches Zeichen empfangen wurde

ob ein Zeichen empfangen wurde oder nicht, könnt man zb anzeigen, indem 
man nach dem getc eine LED einschaltet.

Ein Programmlauf sieht dann so aus:
Das Programm sendet "Hallo". Die LED ist dabei aus. Dann geht dein 
Programm in den uart_getc und wartet auf ein Zeichen. Du drückst auf 
deinem Terminal eine Taste und da uart_getc() etwas empfängt, wird die 
LED eingeschaltet.

Das ist das Szenario. Das ist das was man erwarten würde, wenn getc 
überhaupt etwas empfängt.

Dazu veränderst du dein Programm zb so
1
int main (void)
2
{
3
  DDR....    für LED auf Ausgang stellen
4
  USART_Init();
5
6
  while(1)
7
  {
8
    uart_puts( "Hallo" );
9
    NextChar = uart_getc();
10
11
    PORT...     LED einschalten
und siehtst nach, ob sich alles tatsächlich so abspielt.

Die einfache Frage lautet nun: Kommt die LED oder kommt sie nicht.
Kommt sie, ist der erste Punkt abgehakt, uart_getc() empfängt irgend 
etwas. Kommt sie nicht, dann muss man zu suchen anfangen, warum kein 
Zeichen empfangen werden kann. Konfigurationsregister absuchen und wenn 
sich dort nichts zeigt auch mal die Hardware untersuchen.

Angenommen du bist jetzt soweit, dass du mit Sicherheit (wegen der LED) 
weißt, dass etwas empfangen wird. Nur was?
Überleg dir, wie du dein Programm so erweitern kannst, dass dir das 
Programm zeigt, was es empfangen hat (Hinweis: Du hast eine bereits 
getestete, funktioniertende Sende-Funktion!) (Hinweis2: Ich werf jetzt 
einfach mal die Frage im Raum: Kannst du anstelle der LED auch die 
Sendefunktion benutzen, um die Fragestellung "Wird überhaupt etwas 
empfangen" abzuklären?)

> Ich habe echt schon viel
> probiert.

Du musst zielgerichtet probieren. Wenn du etwas ausprobierst, dann 
überleg dir vorher was du probierst, warum du es probierst, was die 
Aussage deiner Probieraktion ist, was testest du damit, was erwartest du 
das passiert, welchen Wert hat der Test, welche Fragestellung kann man 
mit diesem Test abklären, welche Fragestellungen gibt es noch und wie 
kann man die testen.

Einfach ins blaue hinein ein Programm zu verändern, hat keinen Sinn. Du 
musst systematisch vorgehen.

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.