Hallo zusammen,
bin auf neuen µC umgestiegen und damit mit einigen Herausforderungen,
konkret: der USART (einer von beiden)
Habe in dem Beitrag meinen Code angehangen, wenn ich Daten an den µC
sende sollte ich die gleichen Daten zurueck erhalten. Leider empfaengt
er sie nicht oder sendet "Muell" zurueck.
Was ich probiert habe: Quarz 4Mhz betrieben - war aber aus irgendeinem
Grund zu langsam, die LED 2 an/aus...warum?
Getauscht gegen 16Mhz und 20Mhz, mit und ohne den 2 27pF Kondensatoren
getestet - LED blinkt nun im Sekundentakt. Sowie den internen Oszillator
verwendet - keine Chance den kann man nicht so einfach programmieren wie
den Mega8 (kann mir eingr erklaeren wie man den in 8Mhz betreiben
kann?). Im Anfangteil vom Programm lasse ich eine LED blinken um mich zu
vergewissern, dass der Takt der richtige ist. Am Terminal eingestellt:
9600;N;1
-Mehrere Controller probiert
-Verschiedene USB-RS232 Konverter probiert
-verschiedene Quarze probiert
-verschiedene PC´s probiert
-verschiedene Terminals probiert
-verschiedene FUSE Bits probiert
-CKDIV8 auf High (deaktiviert)
-verschiedene Baudraten probiert
Ich verstehe das ueberhaupt nicht... wer es weiss oder mir hilfreichen
Tipp gibt der bekommt von mir ein Doener gezahlt, versprochen!
ja stimmt er schreibt ins UCSRnC Register. Kann ich den weglassen oder
besser:
ldi r16,((0<<UMSEL00)|(0<<UMSEL01)|(1<<UCSZ01)|(1<<UCSZ00))
-> Asynchron
H.Joachim S. schrieb:> funktioniert.
Sieht gut aus, konnte es kompilieren und die Funktion ist besser, leider
aber nicht perfekt es wird mehr Muell zurueckgesendet als den String den
ich zum µC sende
S. Landolt schrieb:> Also da hat's noch zwei Fehler (sowie Ungereimtheiten):>>> lds r16, (1<<RXEN0)|(1<<TXEN0)> 'lds'?
bei neuen µC´s funktioniert in nicht, fuer out muss sts verwendet werden
>>> sts UDRE0,r16> 'UDRE0'?
was sonst?
S. Landolt schrieb:>>was sonst?> 'ldi' sowie 'UDR0'
Kommt nach dem Kompilieren immer das selbe bei raus, habe ich bereits
100 mal getestet wenn es reicht..
H.Joachim S. schrieb:> UCSR0A=(0<<RXC0) | (0<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0) |> (0<<UPE0) | (0<<U2X0) | (0<<MPCM0);
Ich habe das setzen in das UCSR0A ausgelassen - nun bekomme ich nach
jedem senden etwas zurueck, das ist schonmal gut. Was fehlt noch?
Ist momentan getaktet von einem 20Mhz Quarz ohne Kondensatoren.
S. Landolt schrieb:> Etwas zäh das Ganze, oder? Also hier das komplette Programm mit> den drei> korrigierten Fehlern:.include "m324pdef.inc"
Ich bin seid 15 Stunden mit dem Thema liiert... zaeh waere mir lieber.
Wenn ich den Code flashe und etwas sende, dann antwortet mit der 324p
mit dem Alphabet von a-z, dann A-Z und anschließend mit Sonderzeichen
??
Genau das was ich sehe
S. Landolt schrieb:> Ja ist doch prima! Genau das sehe ich hier auch, oder was hatten> Sie> erwartet von Ihrem Programm?
Genau das was ich sehe, ich kann nicht glauben das ich soviel Zeit damit
verbracht habe um bit im UCSR0C Register zu setzen...
Das bedeutet im Lerneffekt: Das setzen von RXEN0 und TXEN0 im UCSR0B
Register reicht aus um USART0 fuer 9600bps und einem Stoppbit zu
initialisieren?
Das Datenblatt hat mich komplett in die Irre schwarze Materie gefuehrt.
Ich meine: es wird zwar 'receive' aktiviert, aber es gibt keinen
Programmteil, welcher empfängt; es wird ausschließlich gesendet, und
zwar beginnend mit
> ldi r16, 'A' ; Sollte gesendet werden
und dann wird im ASCII-Code hochgezählt
> inc r16
Aha, jetzt verstehe ich.
Ja, nach dem Reset steht (beim ATmega324) der USART auf dem Format 8N1,
und nein, die Baudrate muss gesetzt werden, da ist der 'initial value'
für UBRR ja 0.
Herr Landolt,
vielen Dank!! Die Baudrate habe ich jetzt falsch herangezogen, ich
meinte 8N1.
Haben Sie eine gueltige PP Mail fuer mich, ich verschulde mich bei Ihnen
um einen Doener!
S. Landolt schrieb:> PS:> Auch der ATmega8 steht zu Beginn auf 8N1, man muss nur die Finger von> UCSR0C lassen (das gilt wohl für alle Controller der Familie).
Vielen Dank fuer die Tipp´s!
Sollte man umgehend aus dem Tutorial entfernen, meinen Einstig habe ich
uéber diese Seite begangen und seid dem davon ausgegangen das UCSR0C
muss unbedingt gesetzt sein..
https://www.mikrocontroller.net/articles/AVR-Tutorial:_UART
Wenn es solche Leute wie Sie gibt, macht es viel mehr Spaß!
Wuensche auch schoenes Restwochenende.
Darf ich nochmal stoeren?
Versuche seid Stunden den Interrupt fuer USART0 zu initialisieren,
richte mich dabei an das Datasheet nur funktioniert es nicht richtig (es
werden wirre Zeichen gesendet). Der Interrupt wird ausgeloest da der
Prozesor sich in der Schleife "OTP" ohne "" befindet, was fehlt noch?
Laut Datasheet:
Bit 7 – RXCIEn: RX Complete Interrupt Enable nWriting this bit to one
enables interrupt on the RXCn Flag. A USART Receive Complete interrupt
will be generated only if the RXCIEn bit is written to one, the Global
Interrupt Flag in SREG is written to one and the RXCn bit in UCSRnA is
set.
BaeumeKommunizierenElektromagnetisch schrieb:> [avrasm]> .include "m324pdef.inc"
Hier fehlt was, nämlich der Sprung zu init/main. also ungefähr hierhin:
> ;Stackpointer>> ldi r16, high(RAMEND)> out SPH, r16> ldi r16, low(RAMEND)> out SPL, r16
[...]
BaeumeKommunizierenElektromagnetisch schrieb:> ok habe ich eingepflegt, Resultat ist das selbe.
Dann stimmt der Takt und/oder die UART-Initialisierung nicht.
Was ist die Taktquelle des µC?
c-hater schrieb:> BaeumeKommunizierenElektromagnetisch schrieb:>>> ok habe ich eingepflegt, Resultat ist das selbe.>> Dann stimmt der Takt und/oder die UART-Initialisierung nicht.>> Was ist die Taktquelle des µC?
20Mhz,
Ohne Interrupt funktioniert es wunderbar..
S. Landolt schrieb:> Dies hier ist auch nicht richtig: ldi r16, RXC0> sts UCSR0A, r16
Das Datenblatt besagt bit 7 vom UCSR0A muss gesetzt sein.. Setze ich es
nicht ist das Resultat das selbe.
Nein, ist es nicht. Du hast erstens definitiv nicht den Unterschied
zwischen Entwurfszeit und Laufzeit verstanden und zweitens nicht, wie
man zur Laufzeit dasselbe (nämlich eine logische OR-Verknüpfung)
bewerkstelligt...
Etwa so:
ldi r16, (1<<RXEN0)|(1<<TXEN0)
sts UCSR0B, r16
[... und später irgendwann]
lds r16, UCSR0B
ori r16,1<<RXCIE0 ;oder auch: sbr ...
sts UCSR0B, r16
Jammerer schrieb:> S. Landolt schrieb:>> hier wird der USART gleich wieder abgeschaltet:>> Da sieht man es wieder: Assembler ist einfach scheisse.
Pardon, aber: wäre in C genauso bei 'UCSR0B = RXCIE0;'.
Jammerer schrieb:> S. Landolt schrieb:>> hier wird der USART gleich wieder abgeschaltet:>> Da sieht man es wieder: Assembler ist einfach scheisse.
Quatsch mit Soße. Du kannst exakt denselben Schwachsinn genausogut in C
programmieren, wenn du so wenig Ahnung hast, wie du hast...
S. Landolt schrieb:> Pardon, aber: wäre in C genauso bei 'UCSR0B = RXCIE0;'.
Da sieht man die Scheisse aber besser ...
Wenn ich da kein &= oder |= sehe schellen bei mir schon
die Alarmglocken.
Jammerer schrieb:> S. Landolt schrieb:>> Pardon, aber: wäre in C genauso bei 'UCSR0B = RXCIE0;'.>> Da sieht man die Scheisse aber besser ...>> Wenn ich da kein &= oder |= sehe schellen bei mir schon> die Alarmglocken.
Siehst du, bei gelernten Assemblerprogrammierern schrillen sie halt
ebenfalls, wenn jemand einem IO-Register etwas zuweist, ohne es mit dem
vorherigen Inhalt in irgendeiner Form zu verknüpfen.
Wo genau ist nun der Unterschied oder der Vorteil von C?
> Nein, ist es nicht. Du hast erstens definitiv nicht den Unterschied> zwischen Entwurfszeit und Laufzeit verstanden und zweitens nicht, wie> man zur Laufzeit dasselbe (nämlich eine logische OR-Verknüpfung)> bewerkstelligt...
Nicht verstanden ist die falsche Ausdrucksweise, ich habe mich damit
noch nicht in der notwendigen ausfuehrlichen Form damit befasst.
Habe es nun folgendermassen gemacht und es funktioniert nun, danke euch
beiden..!
Okay, Sie sind wieder ein Stück weiter, und die hinlänglich bekannte,
unsägliche Diskussion hat ein rasches Ende gefunden - beides ein Grund,
sich zu freuen.
BaeumeKommunizierenElektromagnetisch schrieb:> ldi r16, (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0)|(1<<RXCIE0)
Das kann nur Schwachsinn sein. Es macht keinen Sinn, ein und dasselbe
Flag zweimal zu verodern...
In KEINER Sprache...
> ldi r16, (1<<RXC0)> sts UCSR0A, r16
Und das ist ebenfalls sinnlos. Wenn dieses Flag gesetzt ist, läßt es
sich nur durch Lesen von UDR0 löschen.
> ... RXC0 ...
Nun ja, ist sicher nicht die letzte Wissenslücke; Rom wurde auch nicht
an einem Tag erbaut.
Aber zur Vollständigkeit sei das Datenblatt zitiert: "This flag bit is
set when there are unread data in the receive buffer and cleared when
the receive buffer is empty".
> Das kann nur Schwachsinn sein. Es macht keinen Sinn, ein und dasselbe> Flag zweimal zu verodern...
ist ein Kopierfehler.. setze das Flag nur einmal
>> In KEINER Sprache...>>> ldi r16, (1<<RXC0)>> sts UCSR0A, r16>> Und das ist ebenfalls sinnlos. Wenn dieses Flag gesetzt ist, läßt es> sich nur durch Lesen von UDR0 löschen.
Inwiefern sinnlos, koennen Sie es mir genauer erklaeren? Das Datenblatt
gibt es vor und die Funktion ist gegeben.
S. Landolt schrieb:> Aber zur Vollständigkeit sei das Datenblatt zitiert: "This flag bit is> set when there are unread data in the receive buffer and cleared when> the receive buffer is empty".
Was allerdings nicht wirklich hilfreich ist, wenn man das Konzept der
UART nicht kennt. In anderen Datenblättern ist das etwas hilfreicher
formuliert. Nämlich ungefähr so, wie ich schrieb...
Aber um den Kreis zu schließen: Das Lesen von UDR0 sorgt dafür, dass der
Empfangspuffer leer(er) wird. Aber nicht notwendigerweise leer. Denn er
kann bis zu drei Stufen haben, beim 324A hat er sie. Genau genommen muss
man also dreimal UDR lesen, bis man vollkomen sicher sein kann, dass das
Flag nicht mehr gesetzt ist. Oder (i.d.R. deutlich sinnvoller) RXEN mal
kurz löschen...