Forum: Mikrocontroller und Digitale Elektronik Atmega8 USART


von Hua G. (hua)


Lesenswert?

Vorher habe ich in AtmegaMiniModul (mit Atmega8 16AI) den Transport über
RS232 zum PC implementiert. Aber jetzt ich kann in Robo008 (mit
Atmega8-16PU) die Daten über RS232 zum PC nicht richtig transportieren.
In Computer kann ich nur immer 0 bekommen. Ich denke, alle sind Atmega8,
nur verschiedenes packaging, deshalb benutze ich die gleichen Code. Und
ich habe die Schaltungen verglichen, es gibt auch kein großes
Unterschied, nur Treiberbaustein in AtmegaMiniModul ist MAX202CSE,
während in Robo008 MAX232, alle andere Verbindungen sind gleich.
Ich habe die TXD und RXD Porte von Atmega8 16AI und ATmega8-16PU
jeweils mit ein RS422 Treiberbaustein angeschloßen, und auch den
gleichen Ergebnis. Atmega8 16AI transportiert richtig, Atmega8-16PU
transportiert immer 0, immer falsch.
Hat jemand den gleiche Fall mal getroffen? Hat jemand eine Idee
darüber?
Vielen Dank!

von Hubert.G (Gast)


Lesenswert?

Ich auch die Quarzfrequenz auf beiden Boards gleich?

von Hua G. (hua)


Lesenswert?

Nein, eine ist 16Mhz, andere ist 14,7456Mhz. aber ich habe sie in
Makefile bei 'Processor frequency' geändert.

von Rahul (Gast)


Lesenswert?

Vermutlich ist das Timing im Programm-Code aber noch auf eine der beiden
Taktfrequenzen festgelegt. Die Baudrate u.ä. wird meist per Makro im
Programm (vom Preprozessor) berechnet.
Damit hat das Makefile IMHO nichts zutun.

von Hua G. (hua)


Lesenswert?

Mein Programm ist so einfach wie folgend:
void USART_Init( unsigned int baud )
{

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

  UBRRH = (unsigned char)(ubrr>>8);
  UBRRL = (unsigned char)ubrr;
//  UBRRH=0x00;
//  UBRRL=0x67;
  /* Enable Receiver and Transmitter */
  UCSRB = (1<<RXEN)|(1<<TXEN);
  /* Set frame format: 8data, 2stop bit */
  UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}
void USART_Transmit( unsigned char data )
{
  /* Wait for empty transmit buffer */
  while ( !( UCSRA & (1<<UDRE)) )
    ;
  /* Put data into buffer, sends the data */
  UDR = data;
}

In main Programm:
  USART_Init(9600);
  for(int i =0; i< 10; i++)
  {
  USART_Transmit(0xa0);
  }

Ich kann niergendwo für Einstellung des Timing finden.

von Rahul (Gast)


Lesenswert?

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

UBRR berechnent sich nämlich so:
UBRR = fosc / (16*baud) - 1
Und wenn man 16MHz durch 16 teilt, kommt man auf 1000000...

von Hua G. (hua)


Lesenswert?

Ja, du hast Recht. Das habe ich nicht bemerkt.
Aber nachdem ich das korregiert habe, transportiert es noch nicht
richtig.

von Nanobot (Gast)


Lesenswert?

weil es eigentlich so richtig wäre:

UBRR = fosc / ( (16*baud) - 1 )

Beachte die Klammern...

von Rahul (Gast)


Lesenswert?

>weil es eigentlich so richtig wäre:

UBRR = fosc / ( (16*baud) - 1 )

nö, ist es nicht.

von Rahul (Gast)


Lesenswert?

Begründung: Siehe Table 52 auf Seite 133 des Complete-Datasheet

von Nanobot (Gast)


Lesenswert?

>weil es eigentlich so richtig wäre:

UBRR = fosc / ( (16*baud) - 1 )

>nö, ist es nicht.

Wieso funktioniert das dann bei mir?
Verwende auch einen mega8 bei 4800 Baud...

von Hua G. (hua)


Lesenswert?

Nein, es soll UBRR = fosc / (16*baud) - 1, ohne klamma.
Weil BAUD = fosc / (16*(UBRR +1)).
Aber warum geht es noch nicht?
(Ich habe UBRR = fosc / ( (16*baud) - 1 ) auch probiert, es geht auch
nicht. :))

von Hua G. (hua)


Lesenswert?

4800 Baud geht es auch nicht.
seltsam!

von Rahul (Gast)


Lesenswert?

@Nanobot: Dann berechne doch einfach mal beide Werte...

@Hua: Welche Werte hast du denn für UBRR raus?

von Nanobot (Gast)


Lesenswert?

Ihr habt recht, im Datasheet steht es so drin:

UBRR = fosc / (16*baud) - 1

von Rahul (Gast)


Lesenswert?

Welcher der beiden überträgt die Daten denn richtig? Der mit 16MHz oder
der mit 14,7456MHz?

von Hua G. (hua)


Lesenswert?

Ich habe so geschrieben:

#define fosc 14745600

....
  unsigned int ubrr = fosc / (16 * baud) - 1;

  UBRRH = (unsigned char)(ubrr>>8);
  UBRRL = (unsigned char)ubrr;

Dann kann es die Werte für UBRR automatisch rechnen.

Wenn du fragst, rechne ich selbst.
wenn baud = 9600, dann soll UBRRH = 0x00, UBRRL = 0x5f sein.

von Hua G. (hua)


Lesenswert?

Atmega8 16AI ist mit 16MHz, es funktioniert richtig.
Atmega8-16PU ist mit 14,7456MHz, es funktioniert nicht richtig.

von Rahul (Gast)


Lesenswert?

Hast du die Möglichkeit die Signale zu messen?

von Hua G. (hua)


Lesenswert?

Ich habe nur mit Voltmesser an zwei Stelle gemessen. Eine ist am Outport
von Mega8, nämlich am PortD0 und PortD1. Die andere ist am Outport des
Treiberbausteins. Beide Stelle haben die beide Mega8 gleichen
Spannungen.

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.