Forum: Mikrocontroller und Digitale Elektronik Atmega - RS232 funktioniert nicht


von Egon M. (kpc)


Angehängte Dateien:

Lesenswert?

Hallo,
kann mir jemand schreiben, was ich an dem Code falsch gemacht habe?

Ich versuche, an einem Atmega16 die RS232-Schnittstelle einzurichten.

Wie der angefügte Code zeigt, habe ich aus dem AVR-Manual die Passagen 
übernommen, die das Senden betreffen und dann versucht, den AVR zu 
veranlassen, ein einzelnes Zeichen zu senden.

Bei Hyperterminal oder hterm kommt nichts an (senden kann man auch 
nichts).

Daraufhin habe ich mir mit dem Oszi angesehen, was an PORTD1 geschieht: 
regelmäßig sieht man einen ganz kurzen low-Impuls über den Schirm 
huschen. Ob das die vier Bits des 'b' sind oder nur ein Bit? (Wird nicht 
aufgelöst).

Am Eingang des MAX232N kommt das Signal an, aber am Ausgang sehe ich nur 
die negierte Linie, aber keine positiven Peaks!
Da vermutet man natürlich, der ist defekt. Ist aber nicht der Fall, denn 
wenn man den PORTD1 hin- und herschaltet, dann kommt das auf der anderen 
Seite des MAX232 an.

Nun bin ich ziemlich ratlos.
Könnte sich vielleicht jemand mal den Code ansehen, welcher Fehler sich 
darin verbirgt?

Viele Grüße
Egon

von Manni (Gast)


Lesenswert?

1. Warum nimmst du 2 stop bits ? Hast du das auch im hyperterminal so 
gesetzt ?

Typischerweise nimmt man 8N1 mit:
/*
** Set transmission type, Asynchron 8N1
*/
  UCSRC |= (1 << URSEL)|(3<<UCSZ0);

2. Warum gleich die volle Geschwindigkeit (Baudrate) mit 115200 ?
Versuch's erst mal mit 9600.

Verwende mal:
/*
** Set baud rate
*/
#define BAUD_RATE    9600
    UBRRH = (uint8_t) ((SYSCLOCK / (BAUD_RATE * 16L) - 1)>>8);
    UBRRL = (uint8_t) (SYSCLOCK / (BAUD_RATE * 16L) - 1);
/*

SYSCLOCK dann im AVR Studio auf Quarz Frequenz sezten oder z.B. mit:
#define SYSCLOCK    7370000

Manni

von Stefan E. (sternst)


Lesenswert?

Manni wrote:
> 1. Warum nimmst du 2 stop bits ? Hast du das auch im hyperterminal so
> gesetzt ?

Wenn der Sender 2 Stopbits sendet, ist es völlig wurscht, ob beim 
Empfänger 1 oder 2 Stopbits eingestellt sind. Nur umgekehrt ist es 
problematisch.

von SoLaLa (Gast)


Lesenswert?

war da nich mal was mit _delay_ms und daß das Argument ne bestimmte 
Größe nicht überschreiten darf?

von Stephan (Gast)


Lesenswert?

Ich kann mich jetzt auch irren aber musst nich noch die Interrupts 
anstellen damit
1
while (! (UCSRA & (1<<UDRE)))
 funktioniert? Ist auf jeden Fall beim MSP so der Fall. Kannst das ja 
mal ausprobieren.

greetz

von Johannes M. (johnny-m)


Lesenswert?

Stephan wrote:
> Ich kann mich jetzt auch irren aber musst nich noch die Interrupts
> anstellen damit
>
1
while (! (UCSRA & (1<<UDRE)))
> funktioniert?
Nö. Die Flags werden immer gesetzt. Auch wenn die 
Interrupt-Bearbeitung deaktiviert ist.

von Stefan E. (sternst)


Lesenswert?

Oder um es mal zusammenzufassen: der Code ist in Ordnung.
Entweder stimmt die Baudrate nicht (falscher Takt beim µC oder falsche 
Einstellung am PC), oder es ist ein Hardwareproblem. Da er gar nichts 
empfängt, ist es eher letzteres.

von Egon M. (kpc)


Lesenswert?

Hallo,
zwischendurch mal vielen Dank für Eure Antworten!

@Hi Manni,
ich werde mal versuchen, wie Du schreibst, die Baudrate etwas 
herunterzusetzen.
Das mit den zwei Stopbits ist mir auch zuwider, ich wollte nur eines.
Aber über Deiner Zeile
UCSRC |= (1 << URSEL)|(3<<UCSZ0);
steht in Manual S.148: 8 data, 2 stop.
Ich habe es erst mal so gelassen, weil es dem Oszi auf der Rückseite des 
MAX232 sicher egal ist.

@ hi SoLaLa
ich glaube auch, daß das früher mal so war, aber neuerdings 
funktionieren die  langen _delay-Schleifen problemlos

@ hi Johannes
while (! (UCSRA & (1<<UDRE))) ist doch eine ganz normale Schleife und 
wenn das Ereignis nicht eintritt, wartet man eben, notfalls tagelang. 
Dies geschieht z.B. bei meinen Exercitien, wenn ich den Code auf 
'empfangen' einrichte. Aber hier wird die Schleife immer wieder 
durchlaufen, da braucht man noch keinen Interrupt.

@hi Stefan

> Oder um es mal zusammenzufassen: der Code ist in Ordnung.
> Entweder stimmt die Baudrate nicht (falscher Takt beim µC oder falsche
> Einstellung am PC), oder es ist ein Hardwareproblem. Da er gar nichts
> empfängt, ist es eher letzteres.

Das hatte ich auch befürchtet.
Aber zunächst, unabhängig von Baudraten und PC, warum sehe ich denn 
jetzt am MAX232 nichts, während dieser doch Blinkschaltungen am PORTD1 
problemlos durchläßt?
Und sonstige Hardwareprobleme? Der gleiche Com2:-Port funktioniert, wenn 
ich etwas Anderes anschließe.
Ich stehe da wirklich auf dem Schlauch.

Viele Grüße
Egon

von Johannes M. (johnny-m)


Lesenswert?

Egon Müller wrote:
> @ hi Johannes
> while (! (UCSRA & (1<<UDRE))) ist doch eine ganz normale Schleife und
> wenn das Ereignis nicht eintritt, wartet man eben, notfalls tagelang.
> Dies geschieht z.B. bei meinen Exercitien, wenn ich den Code auf
> 'empfangen' einrichte. Aber hier wird die Schleife immer wieder
> durchlaufen, da braucht man keinen Interrupt.
Eben. Deshalb trifft das, was Stephan geschrieben hat, ja auch nicht 
zu... Mag sein, dass das bei dem MSP430 so ist (was mich ein klein wenig 
wundern würde), aber bei den AVRs ist das definitiv nicht so. Die 
Interrupt-Bearbeitung muss für eine Flag-Abfrage nicht aktiviert sein.

von Stefan E. (sternst)


Lesenswert?

@ Egon:

Hast du auch mcu richtig gesetzt?

von Egon M. (kpc)


Lesenswert?

Stefan Ernst wrote:
> @ Egon:
>
> Hast du auch mcu richtig gesetzt?

Hmm - was ist MCU?
Meinst Du den im Makefile? - Ja
Gibt es einen anderen? - Im Zweifeslfall nein

mfg

von Stefan E. (sternst)


Lesenswert?

An deiner Stelle würde ich mal die Delays rausnehmen, dann kannst du mit 
dem Oszilloskop besser sehen, was am Tx-Pin passiert.

von Egon M. (kpc)


Lesenswert?

Stefan Ernst wrote:
> An deiner Stelle würde ich mal die Delays rausnehmen, dann kannst du mit
> dem Oszilloskop besser sehen, was am Tx-Pin passiert.

Also, habe ich (wieder mal) gemacht. Jetzt kann ich am ATmega-Ausgang 
bzw. MAX232-Eingang ein stehendes Muster erkennen, das, glaube ich, mit 
den Bitwerten des übertragenen Zeichen korreliert.

Aber sonst ist es unerklärlich wie vorher: Am MAX-Eingang liegt das 
Signal an, am Ausgang kommt nichts an. Wenn ich im ATmega die 
USART-Geschichte weglasse, dann läßt der MAX232 die Signale durch, wie 
es sich gehört.

Ratlos wie bisher
Egon

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Sind µC und MAX232 richtig miteinander verbunden => Schaltplan? 
Platinenlayout? Detailfoto vom Aufbau?

von Stefan E. (sternst)


Lesenswert?

Egon Müller wrote:

> Wenn ich im ATmega die
> USART-Geschichte weglasse, dann läßt der MAX232 die Signale durch, wie
> es sich gehört.

Und was genau machst du dann? Toggelst du nur den Tx-Pin, oder gleich 
den ganzen Port? Hast du vielleicht am MAX Tx und Rx vertauscht?

von Egon M. (kpc)


Lesenswert?

Stefan Ernst wrote:
> Egon Müller wrote:
>
>> Wenn ich im ATmega die
>> USART-Geschichte weglasse, dann läßt der MAX232 die Signale durch, wie
>> es sich gehört.
>
> Und was genau machst du dann? Toggelst du nur den Tx-Pin, oder gleich
> den ganzen Port? Hast du vielleicht am MAX Tx und Rx vertauscht?

Ich schalte PORTD1 = PIN15 am Atmega mit einigen Millisekunden Delay aus 
und ein (so wie im geposteten Programmschnipsel den PORTB0). Dann sieht 
man auf den Oszi den Wechsel an PORTD1 (TX) oder am MAX-Ausgang das 
entsprechende Signal, invertiert (was man nicht sehen kann) und auf 
einem höheren Spannungslevel (allerdings 16,6V und nicht die lt. PC 
vorgesehenen 12 oderr 15 V). Die Schnittstelle ist allerdigs offen, ohne 
Verbindungzum PC.

von Egon M. (kpc)


Lesenswert?

Stefan "stefb" B. wrote:
> Sind µC und MAX232 richtig miteinander verbunden => Schaltplan?
> Platinenlayout? Detailfoto vom Aufbau?

Es handelt sich um ein AVR-P40-Board von Olimex, gekauft hier im Board 
und bis auf die USART-Exercitien noch ganz jungfräulich.
Sagt Dir das etwas - oder soll ich doch noch ein Photo machen?

Auf dem Board mußte man noch die PORTD 0 und 1 mit den entspr. 
markierten Eingängen des MAX232 verbinden, was ich getan habe.

Irgendwo habe ich mal einen Plan gesehen, da waren zur Verbindung 
ATmega/MAX232 noch einige Kondensatoren o.dgl. nötig. Auf meinem Board 
ist das so eng, daß ich nicht erkennen kann, ob da noch etwas fehlt. 
Aber ich erinnere mich an die Aussage von Andreas Schwarz, von dem ich 
vor vielen Jahren das erste Board gekauft habe, daß nur die beiden 
Drähte nötig seien.

von Stefan E. (sternst)


Lesenswert?

Egon Müller wrote:

> Ich schalte PORTD1 = PIN15 am Atmega mit einigen Millisekunden Delay aus
> und ein (so wie im geposteten Programmschnipsel den PORTB0).

Nein, im Programmbeispiel toggelst du den ganzen Port, nicht nur einen 
Pin. Und wenn du das bei dem Test auch machst, würde bei vertauschten 
Rx/Tx am anderen Ende vom MAX was rauskommen.

von Egon M. (kpc)


Lesenswert?

Stefan Ernst wrote:
> Egon Müller wrote:
>
>> Ich schalte PORTD1 = PIN15 am Atmega mit einigen Millisekunden Delay aus
>> und ein (so wie im geposteten Programmschnipsel den PORTB0).
>
> Nein, im Programmbeispiel toggelst du den ganzen Port, nicht nur einen
> Pin. Und wenn du das bei dem Test auch machst, würde bei vertauschten
> Rx/Tx am anderen Ende vom MAX was rauskommen.

Nun ja, ich habe nicht allein den TXD, sondern gleich auch noch den RXD 
geschaltet (hoffe ich wenigstens:
  DDRB |= 1;
  DDRD |= 3;

  while(1)
   {
  PORTB |= 1;           //    LED des Boards aus (aus, weil gegen plus 
geschaltet)
              //    PD0 = RXD = PIN 14
              //  PD1 = TXD = PIN 15
  PORTD |= 3;
  _delay_ms(1);
  PORTB &= 254;      //   Board-LED wieder ein
  PORTD &= 252;
  _delay_ms(1);
usw. usf.
Aber: an der Rückseite des MAX finde ich die 1-ms-Kurve wieder, 
entsprechend der Eingangsseite.
Und ausprobiert habe ich auch, zu dieser PORTD1-Oszillation die Zeile 
mit dem USART-init einzufügen: dann hört die Oszillation sofort auf, 
d.h. mein USART_init ist nicht ganz falsch, weil es immerhin die beiden 
D-Ports okkupiert.

von Stefan E. (sternst)


Lesenswert?

UART verwendet -> etwas vor dem MAX, aber nichts dahinter
Tx und Rx "von Hand" getoggelt -> etwas vor und hinter dem MAX
=> wahrscheinlich Rx und Tx vertauscht

von Egon M. (kpc)


Lesenswert?

Stefan Ernst wrote:
> UART verwendet -> etwas vor dem MAX, aber nichts dahinter
> Tx und Rx "von Hand" getoggelt -> etwas vor und hinter dem MAX
> => wahrscheinlich Rx und Tx vertauscht

Du hattest recht, Stefan, die beiden Drähte waren vertauscht.
Offensichtlich muß das cross over schon auf dem AVR-P40-Board
vorgenommen werden, man muß also den TXD-PIN (PORTD1) des ATmega mit 
derjenigen Stelle des MAX232 verbinden, wo RX steht.

Bin ich froh, daß es funktioniert!

Vielen Dank für die effektive Hilfe!

Viele Grüße
Egon

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.