Forum: Mikrocontroller und Digitale Elektronik USART Band-Problem


von Hua (Gast)


Lesenswert?

Jetzt programmiere ich mit Atmega128 und benutze HTerm als Anzeiger im
Computer.
Aber ich kann nicht mit Band 38400 über USART daten transportieren. Auf
dem Hterm zeigen immer 0x00.
Mit niedriger Band gibt es kein Problem.

Jemand weißt es warum?
Vielen Dank

Hua

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Baudratenquarz verwendet?

von Hua (Gast)


Lesenswert?

In meiner ganzen Platine habe ich nur eine Quarz (16MHz) benutzt.

von TravelRec. (Gast)


Lesenswert?

Für 38,4kBaud ist ein passender Baudratenquarz aber nötig. Schau mal in
die Tabelle zu Baudratenermittlung des ATMega128 und sieh Dir die
Fehlerraten bei entsprechenden Quazen an. Sie sollte unter 1,5%
bleiben, um eine sichere Verbindung zu haben.

von Hua (Gast)


Lesenswert?

Es gibt nur 0,2%

von TravelRec. (Gast)


Lesenswert?

Das ist okay - muß eigentlich gehen. Hast Du die Stop-und Parity-Bits im
AVR richtig eingestellt?

von Hua (Gast)


Lesenswert?

Ja, ich habe sie richtig eingestellt.

von TravelRec. (Gast)


Lesenswert?

Dann versteh´ ich´s nicht. Poste mal Deinen Code, sonst wird das hier
nix!

von Hua (Gast)


Lesenswert?

Jetzt geht's!
Wenn ich UBRRH=0 und UBRRL=51 direkt gebe, sonder nicht wie früher
durch 1600000/(16*baud)-1 rechnen lassen. Dann geht's!
Aber es ist nicht universal, wenn ich ein neu Bandrate benutzen möchte,
brauche ich die Tabell wieder ablesen.

von Hua (Gast)


Lesenswert?

Jetzt ist es so!
void USART_Init0( )
{

  /* Set baud rate */

  UBRR0H=0;
  UBRR0L=51;

  /*Double Speed*/
  UCSR0A = (1<<U2X0);

  /* Enable Receiver and Transmitter */
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);

  /* Set frame format: 8data, 1stop bit */
  UCSR0C = (0<<USBS0)|(3<<UCSZ00);

}

früher ist es so!
void USART_Init0( unsigned int baud )
{

  /* Set baud rate */
  unsigned int ubrr = 1000000/baud-1;

  UBRR0H = (unsigned char)(ubrr>>8);
  UBRR0L = (unsigned char)ubrr;

  /*Double Speed*/
  UCSR0A = (1<<U2X0);

  /* Enable Receiver and Transmitter */
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);

  /* Set frame format: 8data, 1stop bit */
  UCSR0C = (0<<USBS0)|(3<<UCSZ00);

}

Aber warum kann es nicht selbst rechnen?

von Hua (Gast)


Lesenswert?

früher ist so. Vorner habe ich falsch gekopiert.
void USART_Init0( unsigned int baud )
{

  /* Set baud rate */
  unsigned int ubrr = 1000000/baud-1;

  UBRR0H = (unsigned char)(ubrr>>8);
  UBRR0L = (unsigned char)ubrr;

  /* Enable Receiver and Transmitter */
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);

  /* Set frame format: 8data, 1stop bit */
  UCSR0C = (0<<USBS0)|(3<<UCSZ00);

}

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>1000000/baud-1;

Sollten es nicht eigentlich 16MHz sein?

von Hua (Gast)


Lesenswert?

Doch
wenn U2x = 0; Asynchronous Normal Mode
UBRR = fosc/(16*BAUD) -1;
16M/16 ist 1M
Und ich habe auch von 9600 zum 28800Hz probiert, alle funktionieren
gut. Ab 38800 geht es nicht mehr.

von Karl H. (kbuchegg)


Lesenswert?

> 1000000/baud-1

Probier mal
  1000000L / baud - 1
Man beachte das L hinter 1000000.

von Philipp B. (philipp_burch)


Lesenswert?

Wär' vlt. nicht verkehrt, du würdest den Compiler die Formel ausrechnen
lassen und dann so zuweisen. Ist erstens schneller und zweitens
übersichtlicher als deine Variante mit Bitschieberei usw. Und hast du
es mal ohne U2X mit einer passenden Baud-Rate versucht?

von Holger K. (krulli) Benutzerseite


Lesenswert?

Hua wrote:
> Jetzt geht's!
> Wenn ich UBRRH=0 und UBRRL=51 direkt gebe, sonder nicht wie früher
> durch 1600000/(16*baud)-1 rechnen lassen. Dann geht's!
> Aber es ist nicht universal, wenn ich ein neu Bandrate benutzen möchte,
> brauche ich die Tabell wieder ablesen.

in Deinen 1600000 (=1,6MHz) fehlt eine 0. Richtig wäre 16000000

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.