Forum: Mikrocontroller und Digitale Elektronik USART: Nur wirre Zeichen


von Anfänger (Gast)


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:
1
#include <avr/io.h>
2
#include <util/delay.h>                      //die Warteschleifen
3
#include <stdint.h>                        //die Datentypen
4
#ifndef F_CPU
5
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
6
#define F_CPU 4000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! 
7
#endif
8
9
#define UBRR_VAL 25                      //für Baudrate 9600 bps bei 4MHz
10
 
11
12
13
/*#define BAUD 9600L                            // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
14
 
15
// Berechnungen
16
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)           // clever runden
17
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))             // Reale Baudrate
18
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000)         // Fehler in Promille 
19
 
20
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
21
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
22
#endif*/
23
24
25
void USART_Init( unsigned int ubrr)
26
{
27
UBRRH = (unsigned char)(ubrr>>8);                // Set baud rate
28
UBRRL = (unsigned char)ubrr;
29
UCSRB |= (1<<TXEN);                        // Enable transmitter
30
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);            // Set frame format: 8data, 2stop bit
31
}
32
33
 
34
void USART_Transmit( unsigned char data )
35
{
36
  while ( !( UCSRA & (1<<UDRE)) );              // Wait for empty transmit buffer
37
  UDR = data;                          // Put data into buffer, sends the data
38
}
39
40
41
int main( void )                        //Hauptfunktion
42
{
43
  USART_Init (UBRR_VAL);                    //USART initialisieren
44
45
46
  DDRC &= ~(1<<PC5);                      //Pin C5 auf Eingang
47
  PORTC = (1<<PC5);                      //Pull-up Widerstand Pin C5 ein
48
  
49
50
    while( 1 )                          //Endlosschleife
51
  {                
52
  if (!(PINC & (1<<PINC5)))                  //Wenn Pin C5 Low ist...
53
  {
54
    USART_Transmit ('+');                  //...ein + senden
55
  }
56
  _delay_ms(1000);
57
    }
58
 
59
    return 0;
60
}

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!!!

von Markus B. (wolframator)


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.

von Bruno C. (bruno)


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

von Anfänger (Gast)


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.

von Anfänger (Gast)


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.

von holger (Gast)


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.

von holger (Gast)


Lesenswert?

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

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

von Peter R. (gelb)


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.

von Anfänger (Gast)


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.

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.