www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik USART: Nur wirre Zeichen


Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

Ich bin noch totaler Anfänger in Sachen µCs und habe (wie wohl viele vor 
mir auch :-)) ein Problem mit dem USART: Es kommen statt des gesendeten 
"+" immer ein "j" an, dieses allerdings zuverlässig. Ich verwende einen 
ATMega8 mit 4MHz Oszillator. Ich bin langsam am verzweifeln... ich hab 
einfach keine Ahnung mehr woran das liegen könnte!!!

Meine Schnittstelle ist ok, die habe ich mit der hier beschriebenen 
Methode des "RXD an TXD" auch schon erfolgreich getestet.

Hier mein Code:
#include <avr/io.h>
#include <util/delay.h>                      //die Warteschleifen
#include <stdint.h>                        //die Datentypen
#ifndef F_CPU
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
#define F_CPU 4000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! 
#endif

#define UBRR_VAL 25                      //für Baudrate 9600 bps bei 4MHz
 


/*#define BAUD 9600L                            // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
 
// 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-1000)         // Fehler in Promille 
 
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif*/


void USART_Init( unsigned int ubrr)
{
UBRRH = (unsigned char)(ubrr>>8);                // Set baud rate
UBRRL = (unsigned char)ubrr;
UCSRB |= (1<<TXEN);                        // Enable transmitter
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);            // Set frame format: 8data, 2stop bit
}

 
void USART_Transmit( unsigned char data )
{
  while ( !( UCSRA & (1<<UDRE)) );              // Wait for empty transmit buffer
  UDR = data;                          // Put data into buffer, sends the data
}


int main( void )                        //Hauptfunktion
{
  USART_Init (UBRR_VAL);                    //USART initialisieren


  DDRC &= ~(1<<PC5);                      //Pin C5 auf Eingang
  PORTC = (1<<PC5);                      //Pull-up Widerstand Pin C5 ein
  

    while( 1 )                          //Endlosschleife
  {                
  if (!(PINC & (1<<PINC5)))                  //Wenn Pin C5 Low ist...
  {
    USART_Transmit ('+');                  //...ein + senden
  }
  _delay_ms(1000);
    }
 
    return 0;
}


Das ist teilweise selbst geschrieben, teilweise aus den sehr hilfreichen 
Tutorialen hier kopiert und aus dem Datenblatt.


Ich weiß einfach nicht woran es noch liegen könnte! Ich habe schon alles 
probiert... Der Oszillator läuft wohl auch korrekt (hab ne LED 
angeschlossen und Zeit gestoppt, kam ganz gut hin, Oszi hab ich leider 
nicht ;-)) Dann müssten die Fuses ja wohl auch richtig gesetzt sein, 
oder?

Wäre echt klasse, wenn ihr mir helfen könntet!!!

Autor: Markus B. (wolframator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Teste mal aus Spaß andere Baudraten in Deinem Terminal... Wenn wirre 
Zeichen ankommen dann ist das oft der Fall. Ich hatte z.B. den CKDIV8 
bei meinem AtMega644 übersehen und somit statt 1MHz 8Mhz angenommen -> 
Resultat: Statt 9600 Bau waren es nur 1200.

Autor: Bruno C. (bruno)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hatte schonmal ein ähnliches Problem, hat mich ebenfalls fast zur 
Verzweiflung getrieben. Letztendlich hat es daran gelegen, daß ich den 
Pegelwandler eingespart hatte und dann vergessen habe, daß das Signal 
invertiert werden muß... ;-)

Verwendest Du einen Pegelwandler (z.B. MAX 232)?
Bis dann,

Bruno

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Danke für die schnelle Antowort! Ich habs gleich ausporbiert.

Leider hat das auch nichts gebraucht. Bei manchen anderen Baudraten 
kriege ich zwar auch Zeichen, aber nie das gewünschte.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Nein, ich verwende das MsSmartUSB-Inteface von Conrad (Artikel-Nr.: 
191510 - 62)

Und wenn ich bei dem RXD mit TXD verbinde sehe ich auch, was ich 
schreibe.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Leider hat das auch nichts gebraucht. Bei manchen anderen Baudraten
>kriege ich zwar auch Zeichen, aber nie das gewünschte.

Aber auf jeden Fall wird was gesendet. Ergo: Baudrate falsch !
Sind die Fuses auch richtig gesetzt ?

Hier ist die Reihenfolge falsch

>#include <util/delay.h>                      //die Warteschleifen
>#ifndef F_CPU
>#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
>#define F_CPU 4000000L    // Systemtakt in Hz, das L am Ende ist wichtig, >#endif

#include <util/delay.h>
gehört hinter die Definition von F_CPU. Optimierung muss auch an sein.
Also mindestens -O1.

Als nächstes
  _delay_ms(1000);

Also meine Version vom Compiler mag keine 1000 für _delay_ms()
Dann bekommt man falsche Ergebnisse.

The maximal possible delay is 262.14 ms / F_CPU in MHz.
Sprich maximal 65ms für 4MHz.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);            // Set frame format: >8data, 
2stop bit

Igitt ! 2 Stop Bits. Schmeiss das mit USBS mal raus.

Autor: Peter Roth (gelb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Verwende einen Quarz. 2 bis 4% Fehler in der Frequenz reichen bereits, 
und es kommen falsche Daten an. Siehe auch die anderen ca. 150 Threads 
hier im Forum zu diesem Thema.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Danke für den Tipp mit der Reihenfolge.
Ich denke, dass die Fuses richtig sein müssten, da ich mit ner LED und 
Stoppuhr die Verzögerung nachgemessen hab und es ganz gut hinkam. Das 
müsste doch heißen, dass ich den Oszillator richtig eingesetzt habe und 
die Fuses auch richtig gesetzt sind, oder?

Zum Aufruf _delay_ms(1000): Im AVR-GCC-Tutorial steht unter 
Warteschleifen, dass mit einer avr-libc Version > 1.6 ein Aufruf der 
Schleife möglich ist, es nur zu Ungenauigkeiten kommt. Für meine Fälle 
dachte ich wäre das ok.

Ich hab noch mal nachgelesen, bei meinem Oszillator ist ne 
Frequenzstabilität von +0,003% bei 25°C angegeben. Also müsste das doch 
gehen, oder?

Auf jeden Fall noch mal danke für die vielen und schnellen Antworten.

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.