mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega 8515/USART empfängt nicht schneller als 9600 Baud


Autor: Tom74 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen!

Vorab die Umgebung:

- ATmega8515 auf STK500 @ 8MHz, Jumper im Auslieferungszustand. Kein 
externes Quarz. µC Takt über Fuse SUT_CKSEL: Int. RC OSc. 8 MHz; 
Start-up time: 6 CK + 64ms, sowie in den den Project Options 
eingestellt.
- AvrStudio 4.17
- WinAVR20090913
- 2x USB to serial converter @ 115200 Baud
- Winamp 5.56 ;D

Ich arbeite mich gerade in die USART-Thematik ein und habe zu diesem 
Zweck  2 Testprogramme geschrieben um die Übertragungsraten zu messen.

Das 1. Programm in Visual Basic .net macht nichts anderes, als zu einer 
einstellbaren Baudrate 1000 Bytes zu senden und die dafür benötigte Zeit 
zu messen.

Das 2. Programm ist auf dem µC und nimmt die gesendeten Bytes entgegen.

Bis zu einer Baudrate von 9600 ist soweit alles schlüssig und die 
gemessenen Zeiten stimmen in etwa mit den theoretische Übertragungsraten 
überein:

BAUD  gemessen    rechnerisch(1 Start, 8 Daten, 2 Stopbits)
2400  4,58s       4,58s
4800  2,30s       2,29s
9600  1,18s       1,15s

Ab 9600 bringt eine höhere Baudrate aber keine Steigerung der 
Übertragungszeit mehr...

Es sieht also so aus, als würde irgendetwas die Baudrate auf ca. 9600 
limitieren.
Mache ich etwas bei der USART-Initialisierung falsch, oder wo könnte der 
Fehler liegen?

Hier die 2 Programme:

VB.net (Baudrate über ComboBox von 2400-115200 einstellbar)
Public Class Form1

    Public baud As Integer
    

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Label1.Text = "Time:"
        ComboBox1.SelectedIndex = 0
        
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Label1.Text = "Time:"

        Dim diffzeit As Date = DateTime.Now
        Dim dummybyte(1) As Byte

        SP.PortName = "COM3"
        SP.BaudRate = baud
        SP.StopBits = 2
        SP.DataBits = 8

        SP.Open()
        For x As Integer = 0 To 999
            SP.Write(dummybyte, 0, 1)
        Next
        Label1.Text = "Time: " & ((DateTime.Now - diffzeit).ToString)
        SP.Close()
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
        baud = CInt(ComboBox1.Text)
    End Sub
End Class

µC:
#include <avr/io.h>

void USART_init(unsigned int);

int main (void)
{  
  uint8_t dummy;  
  unsigned int baudrate = 115200;  

  USART_init(baudrate);  

  while(1)
    {  
    while(!(UCSRA & (1<<RXC))) {}  
    dummy = UDR;  
    }
  return 0; //never reached
}

void USART_init(unsigned int baud)
{

UBRRH = (unsigned char)(baud>>8);      //Baud rate MSB  
UBRRL = (unsigned char)baud;        //Baud rate LSB
UCSRB = (1<<RXEN)|(1<<TXEN);        // Enable RCV and TX
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);  // Set frame format: 8data, 2stop bit
  
}

Autor: geb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also dein AVR Programm macht ja gar nichts, außer Zeichen von der ser. 
Schnittstelle zu lesen.Da solltest du einen Test einbauen, der die 
empfangenen Daten Verifiziert. Du mißt eigentlich nur die Zeit, die dein 
PC braucht,egal ob die Daten ankommen oder nicht.Bytes einzeln zu 
schicken dauert womöglich recht lange, Gibts da nicht eine Funktion für 
das Senden eines Buffers?

Autor: Tom74 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir ist bewusst, dass das µC nichts tut, ausser die Bytes in eine 
Dummy-Variable zu schreiben. Aber das sollte ja nicht ursächlich für die 
limitierte Übertragungsrate sein, oder irre ich mich?

Autor: geb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, es ist in deinem Fall sogar völlig egal ob überhaupt was am PC 
angesteckt ist. Dein Problem ist das VB bzw. Windows, möglicherweise 
funkt da eine Flußsteuerung hinein.Hast du keine Möglichkeit das TX 
Signal deines PC mit einem Oszi zu messen?

Autor: Tom74 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe das µC Programm mal etwas erweitert. Es prüft nun, ob tatsächlich 
1000 Bytes ankommen und bestätigt das durch ein kurzes Blinken der LEDs.

Und die Bytes kommen tatsächlich alle an.
#include <avr/io.h>
#include <util/delay.h>

void USART_init(unsigned int);

int main (void)
{  
  DDRB = 0xff;
  PORTB = 0xff;
  
  uint8_t dummy;  
  unsigned int baudrate = 57600;  
  int count = 0;  

  USART_init(baudrate);  

  while(1)
    {  
    while(!(UCSRA & (1<<RXC))) {}  
    
    count++;
    if (count == 1000)
      {
        PORTB = 0x00;
        _delay_ms(500);
        PORTB = 0xff;
        count = 0;      
      }
    dummy = UDR;  
    }
  return 0; //never reached
}

void USART_init(unsigned int baud)
{

UBRRH = (unsigned char)(baud>>8);      //Baud rate MSB  
UBRRL = (unsigned char)baud;        //Baud rate LSB
UCSRB = (1<<RXEN)|(1<<TXEN);        // Enable RCV and TX
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);  // Set frame format: 8data, 2stop bit
  
}

Autor: Tom74 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und nein, ein Oszi habe ich leider nicht.

Autor: geb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
probier mal mit dem Hyperterminal eine textdatei zu senden ev. so 1MB, 
dann kannst du auch mit der Eieruhr die Datenrate bestimmen.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Kein externes Quarz. µC Takt über Fuse SUT_CKSEL: Int. RC OSc. 8 MHz;

Was erwartest du damit eigentlich? Der interne RC-Oszillator ist für 
solche Baudraten nicht geeignet.

MfG Spess

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@spess53
> Was erwartest du damit eigentlich? Der interne RC-Oszillator ist für
> solche Baudraten nicht geeignet.
das spiel hier überhaupt keine rolle, weil er nur die Sende-Zeit stoppt. 
Er kann auch den µC vom PC Trennen und kommt auf die gleichen werte. 
Hier spiel als NUR der PC mit dem vb.net programm eine rolle.

Autor: Tom74 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe mal alles abgehängt und das VB Programm so laufen lassen.
Keine Änderung.
Mit einem Hyper-Terminal Programm ist die (vermeindliche) Übertragung 
noch langsamer.

Der Hund liegt wohl tatsächlich in Windows oder den USB auf 
Seriell-Adaptern begraben. Werde dieser Spur mal weiter nachgehen.

Damit gehört die Sache aber dann wohl nicht mehr in dieses Forum. *g
Werde nochmal posten, wenn ich eine Lösung habe...

Danke für die Tips!

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so langsam ist windows nun auch wieder nicht das es nicht über 9600baud 
kommt. Steck mal den USB-Serial adapter an ein anere USB-Port nicht da 
noch ein andere gerät dran hängt.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Der Hund liegt wohl tatsächlich in Windows oder den USB auf
>Seriell-Adaptern begraben. Werde dieser Spur mal weiter nachgehen.

Schon mal die COM-Port-Einstellungen überprüft?

>Ab 9600 bringt eine höhere Baudrate aber keine Steigerung der
>Übertragungszeit mehr...

>Es sieht also so aus, als würde irgendetwas die Baudrate auf ca. 9600
>limitieren.

Das sind zwei Paar Schuhe.

MfG Spess

Autor: Tom74 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die (virtuellen) Com-Ports sind so eingestellt:

Bits/s: 115200
Datenbits: 8
Parität: keine
Stoppbits: 2
Flusssteuerung: keine

Unter "erweitert":

FIFO-Puffer verwenden: aktiviert
Empfangspuffer: 14
Übertragungspuffer: 16

Habe jetzt auch nur noch 1 USB-Seriell Adapter angeschlossen und den 
USB-Port getauscht. Alle anderen USB-Geräte (ausser Tastatur) sind 
abgehängt.

Autor: Tom74 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nach ein wenig herumprobieren funktioniert das Ganze nun.
Die gemessenen Zeiten passen nun auch gut zu den theoretischen Werten.
Habe zwar leider keine Erklärung dafür, aber sei's drum...

- Die Baudrate im µC ist immer auf 115200 eingesellt, unabhängig von der 
tatsächlichen Geschwindigkeit, mit der gesendet wird.
- Im VB Programm benutze ich nun einen Befehl, der die 1000 Bytes "en 
block" als array sendet, anstatt 1000 einzelne Zeichen in einer for/next 
Schleife.
SP.Write(dummybyte, 0, 1000)

Ich vermute, dass das Senden einzelner Bytes in der Schleife wohl ein 
gewisses Delay mit sich bringt, was die Geschwindigkeit nach Oben 
begrenzt hat.

Danke für Eure 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.