Forum: Mikrocontroller und Digitale Elektronik AVR UART Problem


von Martin (Gast)


Lesenswert?

Hallo,
ich versuche den String "Hello World" auszugeben, aber es wird immer nur 
der erste Buchstabe ausgegeben. Ich benutze übrigens einen 8515. Ich hab 
vorher gelessen, das es daran liegt, das der Stackpointer falsch 
initialisiert wird. Ich hab aber verschiedenen C COmpiler probiert und 
immer der selbe Fehler. Die sollten den Stack doch eigentlich richtig 
initialisieren, oder?
Woran könnte es noch liegen? Am Quarz?

Gruß
Martin

von Mark Hämmerling (Gast)


Lesenswert?

Salut,

hmm... checkst Du auch vorm Senden, ob das Byte in TX schon 
rausgeshiftet wurde? Keine Ahnung, ob das der C-Compiler macht. Hab UART 
bisher nur via ASM programmiert - und das auf nem 2313.

Google doch mal nach Beispiel-Programmen und teste die. Viel Erfolg!

Mark H. -- http://markh.de/avr/

von Jens Stolinski (Gast)


Lesenswert?

Mit dem C-Compiler der Firma IAR und den ATMega103 würde der Quellcode 
so aussehen:

//- iniUART ------------------------------------------------------
void uartIni(uchar baudrate)
{
  UBRR = baudrate; //Set the baud rate
  UCR = ( (1<<RXCIE) | (1<<RXEN) | (1<<TXEN) );
// Enable UART receiver and transmitter, and receive interrupt
}

//- uartTXByte --------------------------------------------------
void uartTXByte(uchar data)
{
  while ( !(USR & (1<<UDRE))); // Wait for empty transmit buffer
  UDR = data; // Start transmittion
}

Für die Ausgabe eines Strings wird die Funktion "uartTXByte" 
entsprechend der Länge das char-Arrays oft aufgerufen, wobei jeweils ein 
Byte übergeben wird.

Bis dann Jens

www.SynaSys.com

von Martin (Gast)


Lesenswert?

Hi,
danke für die schnelle Antwort!

Hier ist mein Code, der zwar etwas umständlich ausieht, aber logisch ist 
und in der simulation funktioniert.

void main(void)
{
volatile unsigned char i;
  //init UART
  UCR=0;
      UBRR=UART_BAUD_SELECT;
  UCR=0x08;

  DDRA = 0xFF;
  DDRB = 0xFF;
  DDRC = 0xFF;
  DDRD = 0xFF;

  PORTA=0;
  PORTB=0;
  PORTC=0;
  PORTD=0;

  i=0;
  while(i != 0x80)
  {

  PrintChar(0x1);
  PrintChar(0x2);
  PrintChar(0x3);
  i++;
  }
}


void PrintChar(unsigned char Val)
{
volatile unsigned char UARTDone = 0;

  while(UARTDone == 0)
  {  if ((USR && 0x20)) //prüft, ob UDRE Bit = 1
    {  UDR = Val; //wenn ja ausgeben und
      UARTDone=1;//while Schleife verlassen
    }
  }
}

Als Ausgabe erscheint immer wieder 0x10. Also funktioiert die Ausgabe, 
aber irgendwie funktioniert die Rückkehr aus der Routine nicht, da ja 
sonst als nächstes 0x02 ausgegeben werden müsste. Ich hab auch mal 
versucht den Stackpointer (ST) in main auf 0x100 zu setzen, hat aber 
nicht geholfen. Ich hoffe Ihr könnt mir helfen.

Danke
Martin

von Jens Stolinski (Gast)


Lesenswert?

Der oben beschriebene Algorithmus soll die Bytefolge "0x10,0x20,0x30" 
128 (0x80) mal über die UART-Schnittstelle senden.
Das Problem in der Funktion "PrintChar" ist, es wird geprüft ob das 
UDRE-Bit 1 ist, wenn nicht wird die Funktion verlassen. Das Funktioniert 
wunderbar mit dem ersten Aufruf, dass Byte "0x10" wird gesendet und das 
UDRE-Bit wird intern auf 0 gesetzt. Danach kommt es zum zweiten Aufruf 
der Funktion. Jetzt liegt aber die Situation vor, dass das Zeichen (Byte 
0x10) noch nicht vollständig von der UART-Hardware verarbeitet wurde und 
somit richtigerweise das UDRE-Bit noch 0 ist. Die Funktion wird 
demzufolge ohne das beschreiben des UDR-Registers verlassen.

Richtig währe es, wenn in einer while-Schleife so lange gewartet wird, 
bis ein Senden das vorangegangenen Byte erfolgte (Siehe meinen Quellcode 
- uartTXByte).

Noch eine Frage warum verwendest Du den Begriff "volatile = flüchtig, 
vergänglich"? In C werden alle Variablen die in einer Funktion 
initialisiert werden noch dem Verlassen wieder gelöscht, aus dem RAM 
entfernt.

Bis dann Jens

www.SynaSys.com

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.