Forum: Mikrocontroller und Digitale Elektronik UART funzt nicht so wirklich


von Sissi (Gast)


Lesenswert?

Hallo alle zusammen,

ich habe gestern einen Atmega16 versucht zu programmieren. Nachfolgenden 
Code habe ich draufgespielt und das Ganze mit dem Windows Hyperterminal 
getestet.

putch('>') funktionert, d. h. wenn ich den Controller restete, erscheint 
das Zeichen im Bildschirm des PC's.

Leider kann ich jedoch kein Zeichen vom PC zum Controller senden. Lt. 
Code müsste über "Echo" das gesendete Zeichen wieder am Schirm angezeigt 
werden, was nicht der Fall ist.

Einstellungen stimmen überein: Baud: 9600; 1 Start; 8 Daten; 1 Stop.

Findet jemand einen Fehler im Code:

#include <avr/io.h>          //Deklarationen
#include <avr/signal.h>
#include <avr/interrupt.h>      //für Interrupt

#define TAKT 8000000UL        //Controllertakt 8MHz
#define PRESET 40000UL        //Taktteiler für Vorteiler
#define BAUD 9600UL          //Baudrate

//Festlegung unabhängiger Typennamen:
typedef unsigned int uint16;
typedef signed int sint16;
typedef unsigned short uint8;
typedef signed short sint8;

//Prototypen von Funktionen
void initusart (void);
void putch (uint8);
uint8 getch (void);
uint8 getche (void);
uint8 kbhit (void);




int main (void)
{


  initusart();
  putch('>');
  while(1)
  {
    if (UDR = 'x')
    {
      putch('j');
    }
  }

   return 0;

}




//Nachfolgend Funktionen für USART-Kommunikation


//USART bzw. UART initialisieren
void initusart (void)
{
  uint8 x;              //lokale Hilfsvariable

  #ifdef UBRRL            //USART-Schnittstelle
  UBRRL = (TAKT / (16ul * BAUD)) - 1;  //Baudrate mit TAKT und BAUD
  UCSRB |= (1<<TXEN) | (1<<RXEN);    //Sender und Empränger ein
  UCSRC |= (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);  //async 8bit

  #else
  UBRR = (TAKT / (16ul * BAUD)) - 1;  //Baudrate
  UCR |= (1<<TXEN) | (1<<RXEN);    //Sender und Empfänger ein

  #endif
  x = UDR;              //Empfänger leeren
}



//warten und Zeichen senden
void putch (uint8 x)
{
  #ifdef UCSRA            //USART
  while (!(UCSRA & (1<<UDRE)));    //warte, solange Sender besetzt

  #else                //UART
  while (!(USR & (1<<UDRE)));      //warte, solange Sender besetzt

  #endif
  UDR = x;              //Zeichen nach Sender
}


//warten und Zeichen abholen
uint8 getch (void)
{
  #ifdef UCSRA            //USART
  while (!(UCSRA & (1<<RXC)));    //warte, bis Zeichen da

  #else                 //UART
  while (!(USR & (1<<RXC)));      //warte, bis Zeichen da

  #endif
  return UDR;              //Zeichen abholen
}


//warten und Zeichen abholen mit Echo
uint8 getche (void)
{
  int x;                //Hilfsvariable

  #ifdef UCSRA            //USART
  while (!(UCSRA & (1<<RXC)));    //warte, bis Zeichen da
  x = UDR;              //abholen und speichern
  while (!(UCSRA & (1<<UDRE)));    //warte, solange Sender besetzt

  #else                //UART
  while (!(UCSRA & (1<<RXC)));    //warte, bis Zeichen da
  x = UDR;              //abholen und speichern
  while (!(UCSRA & (1<<UDRE)));    //warte, solange Sender besetzt

  #endif
  UDR = x;              //Echo senden

  return x;              //Zeichen zurückgeben
}


//Empfänger testen
uint8 kbhit (void)
{
  #ifdef UCSRA            //USART
  if (UCSRA & (1<<RXC)) return UDR; else return 0;

  #else                //UART
  iv (USR & (1<<RXC)) return UDR; else return 0;

  #endif
}


Gruß

Sissi

von Tom (Gast)


Lesenswert?

Berichtigung:

in der while-Schleife in der Hauptfunktion steht natürlich folgendes:

gechte();

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Welchen Taktgeber benutzt Du für Deinen Mikrocontroller?

von Tom (Gast)


Lesenswert?

einen externen Oszillator

von Niels H. (monarch35)


Lesenswert?

> if (UDR = 'x')

Das sollte doch bestimmt UDR=='x' heissen, oder?

von Tom (Gast)


Lesenswert?

Da hast Du natürlich recht.

Aber wie gesagt, die Hauptfunktion sieht folgendermaßen aus:

int main (void)
{
  initusart();
  putch('>');
  while(1)
  {
    getche();
  }

   return 0;

}

Es sollte ja nur das gesendete Zeichen am Bildschirm sichtbar werden.

von Niels H. (monarch35)


Lesenswert?

Okey, offensichtlich bleibt die ausführung in irgendeiner der 
while-schleifen hängen. Ich würde mal versuchen mit ein paar 
Debug-signalen an irgendeinem Port versuchen herrauszufinden, welche 
while-schleife das ist, die sich da querstellt....

Besser wäre es natürlich mit einem laufzeit debugger, aber ich gehe mal 
davon aus, das der nicht vorhanden ist...

von Karl H. (kbuchegg)


Lesenswert?

Hast du schon mit einem Multimeter (oder einer LED) überprüft,
ob der PC überhaupt was rausgibt?

Wenn vom PC gar nichts rausgeht, dann könnte es sein, dass
Hardware-Handshake aktiviert ist. Wenn dann das Kabel, bzw.
die Anbindung auf µC-Seite nicht richtig beschaltet ist,
dann wartet der PC bis zum St. Nimmerleinstag auf die
Sendefreigabe.

Also: Im Hyperterminal mal die Einstellung für das
Handshake überprüfen und auf 'None' stellen.

von Patrick (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Tom (oder Sissi?)

Hast Du schon mal ein anderes Terminal-Programm ausprobiert? Ich hab Dir 
ein komfortables angehängt. Bei mir hat UART mit dem Windows 
HyperTerminal auch nie richtig funktioniert. Probiers einfach mal aus.

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.