www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Beim Senden mit USART werden die Zeichen zweimal ausgegeben


Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich beschäftige mich grad damit vom USART an ne Konsole aufm PC etwas zu 
senden. Funzt auch soweit, nur erhalte ich jedes Zeichen das ich schicke 
doppelt in der Ausgabezeile. Änder ich das zeichen, wird das zuvor 
gesendete Zeichen zuerst geschickt. Muss ich irgendwie den Datenpuffer 
nach dem senden löschen? Könnte jemand mal bitte über meinen 
Programmcode drüber schauen ? das wäre sehr nett.

Gruß Sven
//***************************************
// Test der USART Schnittstelle, ATMEGA88
//***************************************
/* 
  UART-Init: 
Berechnung des Wertes für das Baudratenregister 
aus Taktrate und gewünschter Baudrate
*/
 // defines
//*************************
#define FCPU 18432000
#define FOSC 18432000// Clock Speed
#define F_CPU 18432000UL  // Systemtakt in Hz - Definition als unsigned long beachten 
                         // Ohne ergeben sich unten Fehler in der Berechnung
#define BAUD 9600UL      // Baudrate
#define MYUBRR FOSC/16/BAUD-1 
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
 
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif 

// includes
//*************************
#include <inttypes.h>
#include <avr/io.h>

// function prototypes
//*************************
void USART_Init(unsigned int ubrr);
void USART_Transmit(unsigned char data);

// main
//*************************
 
int main(void)
{
  USART_Init(MYUBRR);
  
  
  USART_Transmit(0x23);
  
}

// USART initialization
//*************************
void USART_Init(unsigned int ubrr)
{
   // Set baude rate  
  UBRR0H = (unsigned char)(ubrr>>8);
     UBRR0L = (unsigned char)ubrr;
   
   // enable transmittler TXD0
    UCSR0B |= (1<<TXEN0);                         
   
   // set frame format: 8data, 2stop bits
  UCSR0C |= (1<<USBS0)|(1<<UCSZ00)|(1<<UCSZ01);  
}
 

// USART Transmit
//*************************
void USART_Transmit(unsigned char data)
{
  
  // Wait for empty transmit buffer
  while(!(UCSR0A & (1<<UDRE0)))
  {
  
  }
  
  // Put data ito buffer, sends the data
  UDR0 = data;
}

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir den wirklich keiner weiterhelfen?

Autor: OhneGlaskugel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Programm gibt ein 0x23 aus, sonst nix. Wo ist denn die Verarbeitung 
der eigehenden Zeichen?

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sende bisher keine Daten zurück. Ich sende lediglich ein Zeichen 
also 0x23 an den PC. Mich interessiert nur warum ich auf meiner 
PC-Konsole ## angezeigt bekomm. Weshalb werden zwei Zeichen gesendet?

Autor: XXX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Lokales Echo an/aus??

Gruß
Joachim

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mach mal sowas rein wie..
while (1)
{
   _delay_ms(1000);
   USART_Transmit('x');
}
und schau dann, ob die Zeichen noch immer paarig kommen.

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe eben festgestellt dass die Zeichen nicht doppelt gesendet 
werden sondern immer das zuvor gesendete Zeichen nochmal mitgeschickt 
wird. Habe ich beispielsweise zuerst 0x23 (#) gesendet und anschließend 
im Programmcode auf 0x25 (%) umgeschrieben, compiliert und geflasht so 
erhalte ich auf der Konsole #%. Also es hat den Anschein dass sich das 
vorige Zeichen noch in irgendeinem Zwischenspeicher befindet und mit 
gesendet wird.

Jetz hab ich noch folgendes versucht:
while(1)
  {
    USART_Transmit(0x23);
    USART_Transmit(0x25);
  }

und ich bekomme schön aufeinanderfolgende Zeichen mit #%#%#% usw.
Prima!

Lasse ich nun beispielsweise die while(1) wieder weg und sende quasi nur 
zwei Zeichen erhalte ich folgenden Murx auf der Konsole #\xe5#%

Hier mal die Schnitsttelle die ich zwischen Controller und PC verwende
--> http://www.chip45.com/download/Infosheet_littleUSB...

Was hat es mit dem lokalen Echo auf sich?

Sorry ich bin blutiger Anfänger auf dem Gebiet und wäre dankbar über 
jegliche Hilfe. An dieser Stelle schon mla Danke für die bisherigen 
Antworten.

Gruß Sven

Autor: Clair Grube (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven schrieb:
> Was hat es mit dem lokalen Echo auf sich?

Das kommt aus der Konsolen-Zeit.
Die hatten eine Tastatur und einen Monitor
Die Tastatur sendete Zeichen an den Konsolenserver
Der Monitor empfing Zeichen vom Konsolenserver.

Aber die Zeichen von der Tastatur wurden nicht an den Monitor geschickt. 
Dafür war der Konsolenserver verantwortlich.
Schickt der Konsolenserver die Tastenanschläge nicht automatisch auch 
wieder an den Monitor so konnte mann zwar tippen, sah aber nix am 
Monitor.
Das automatische zurückschicken der Zeichen an den Monitor nennt man 
Echo.

Macht der Server das aber nicht, so war sah man nicht, was man gerade 
getippt hat. Irgendwie unpraktisch. Deshalb konnte man Terminals so 
einstellen, dass sie selber die getippten Zeichen gleich anzeigten, ohne 
dass der Server diese zurückschicken musste. Lokakes Echo genannt.

Autor: Heiko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sven,

das mit der While Schleife ist deshalb angegeben worden, da Dein 
Programm nicht in DOS aufgerufen wird und nach einer Abarbeitung beendet 
wird. Im MC-Bereich wird ein main() nur einmal aufgerufen, durchlaufen 
und am Ende (ohne Rücksprung) natürlich auch beendet, was eigentlich im 
MC-Bereich nicht passieren darf. Wenn am Ende des Programmes nur noch 
NULL(en) stehen, wird der komplette Speicher mit NOP durlaufen und der 
Programmcounter fängt irgendwann bei 0 wieder an. Dann könnte es sein, 
das main() nochmals durchlaufen wird und Dein Zeichen nochmals gesendet 
wird, bis der Prozessor in irgenwelchen Schleifen oder Interrupts hängt.
Wahrscheinlich liegt Dein UART_Init und Dein UART_Transmit aber im 
Adressraum hinter main() und deshalb passiert die Ausgabe zwei mal.
Verhindere einfach die Beendigung von main() und schon wird die Ausgabe 
nur einfach passieren.

Heiko

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.