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
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
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.
war da nich mal was mit _delay_ms und daß das Argument ne bestimmte Größe nicht überschreiten darf?
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
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.
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.
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
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.
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
An deiner Stelle würde ich mal die Delays rausnehmen, dann kannst du mit dem Oszilloskop besser sehen, was am Tx-Pin passiert.
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
Sind µC und MAX232 richtig miteinander verbunden => Schaltplan? Platinenlayout? Detailfoto vom Aufbau?
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?
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.
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.
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.
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.