Hallo,
ich habe mit einem Atmega 328p ein Problem mit dem senden per UART. Ich
habe mittlerweile viel herumprobiert und komme einfach nicht zu einer
Lösung bzw. Eingrenzung des Problems.
Wenn ich das folgende Programm (modifiziert aus dem Tutorial) nehme,
kann ich per hterm Zeichen senden und diese werden auch korrekt
zurückgesendet.
=> Es wird immer AA empfangen.
Das Problem tritt also nur auf, wenn ich Daten sende. Wenn ich Daten per
hterm an den mc sende, werden diese richtig zurückgesendet. Ein
Baudratenproblem schließe ich deshalb aus.
Ich bin für jeden Tip dankbar
Bastler87
Das liegt daran, dass UDR ein Doublebuffer Feature hat. Wenn Du UDRE
testest, wird dieses gleich wieder 1, wenn das erste Byte von UDR in das
Ausgaberegister übernommen wurde. Daher kann ein 2. Byte in UDR
platziert werden, wodurch UDRE dann für eine Bytelaufzeit 0 wird.
Im oberen Codesegment wird das durch das Warten auf RXC abgefangen,
wodurch das Ganze funktioniert. Wenn Du nur ein Byte senden willst,
musst Du auf TXC warten, bevor Du ein neues Byte scheibst. Wenn man
ganze Arrays sendet, stört das Doublebuffering nicht, im Gegenteil. Es
ermöglicht einen lückenlosen Datenstrom.
Wenn das zweite Codebeispiel tatsächlich das getestete Programm ist, ist
das Verhalten nicht erklärbar. Denn da wird exakt einmal etwas in UDR0
geschrieben.
Ein Blick ins .lss File könnte noch einen Hinweis liefern. Schau dir mal
an, was an Assemblercode generiert wurde. In diesem sollten die
C-Quellcodezeilen als Kommentare stehen, womit die entsprechende Stelle
des Sendens identifizierbar sein sollte.
Knut B. schrieb:> Das liegt daran, dass UDR ein Doublebuffer Feature hat. Wenn Du UDRE> testest, wird dieses gleich wieder 1, wenn das erste Byte von UDR in das> Ausgaberegister übernommen wurde. Daher kann ein 2. Byte in UDR> platziert werden, wodurch UDRE dann für eine Bytelaufzeit 0 wird.
Hallo,
ich teste in der ersten while Schleife lediglich ob das Register frei
ist, und schreibe dann buffer dort hinen. Es kann doch eigentlich kein
zweites Byte geschrieben werden, da das Programm dann in der nächsten
while Schleife endlos hängt...
1
while(!(UCSR0A&(1<<UDRE0)));
2
UDR0=buffer;
3
4
while(1);
Felix schrieb:> Ein Blick ins .lss File könnte noch einen Hinweis liefern.
Ich kann leider kein Assembler, deshalb hier die main.lss
Irgendiwe habe ich das Gefühl, dass das Problem an meinem billigen
USB-UART Adapter mit ch340G Chip liegt. Ich habe ihn allerding unter
Archlinux und Win10 mit gleichem Ergebnis getestet.
Sende ich A, wird AA angezeigt.
Sende ich AB, wird ABAB angezeigt.
Auffallend ist auch, dass die Wiederholung der Zeichen mit einer kurzen
Verzögerung angezeigt wird.
Es wird also AB_Verzögerung_AB empfangen...
Welche Hardware nutzt du denn zum Debuggen/ Programmieren?
Kann es sein, dass geflasht wird, und der Prozessor kurz danach resettet
wird?
Probiere doch mal, in der while-Schleife Zeichen zu senden, vielleicht
noch ein Delay mit rein. Passiert es dann immernoch?
Ziemlich sicher wird ein Reset ausgelöst.
Die Reset-Ursache (watchdog, Versorgung...) findest Du im MCU Status
Register MCUSR. Siehe Datenblatt "Reset sources".
Beachte, dass der CH340 über einen C mit dem Reset-Pin verbunden ist,
damit der PC einen Neustart auslösen kann.
eProfi schrieb:> Ziemlich sicher wird ein Reset ausgelöst.
Hallo,
ich programmiere über ISP mit einem AVRDragon. Ich versorge den
Controller auch über den Dragon und hatte ihn zum Resett immer aus dem
USB-Port gezogen...
Der Dragon hat dann nach ein paar Sekunden den Mega328p resettet.
Wenn ich den Dragon an der Spannung lasse und lediglich den M328p
resette funktioniert alles wie erwartet...
Vielen Dank für eure Hilfe ihr habt mir den Sonntag gerettet :-)
Bastler87 schrieb:> Controller auch über den Dragon und hatte ihn zum Resett immer aus dem> USB-Port gezogen...
AFAIK ist das eine ziemlich sichere Methode den Dragon zu töten, wenn
das Target selbstversorgt ist.
Dabei raucht dann der Pegelwander ab, und das ist so ein besch... SMD
Teil das man nur mit Rework-Station ordentlich verarbeiten kann...
> Der Dragon hat dann nach ein paar Sekunden den Mega328p resettet.
Deshalb gebe ich nach dem Init der Seriellen ein kurzes Lebenszeichen
oder Willkommensmeldung aus, auch wenn es nur ein 'r' ist.
So weiß man gleich: Reset wurde ausgelöst, Verbindung steht, Baudrate
stimmt.
Mein Programmieradapter schickt noch einen zweiten Reset Impuls
hinterher, wenn ich am Target den reset-Taster drücke.
Das ist mir zum ersten mal aufgefallen, als ich eine LED blitzen liess,
um den Programmstart anzuzeigen.