Das .lst sieht allerdings im nicht funktionierenden Fall o.k. aus (alles
vorhanden, was hinein gehört).
Die verwendeten uart.c und uart.h sind im Anhang.
Weis hier irgendjemand, woher das oben beschriebene Verhalten kommt?
Hans schrieb:> Ich finde diese Bedingung ziemlich schräg:>>> while (*s)
Was soll daran schräg sein? Ganz normales Stringhandling. Was eher
schräg, wenn auch nicht unbedingt falsch ist, ist das:
Sebastian Götte schrieb:> *(s++);
Wozu dereferenzieren, wenn das Ergebnis eh nicht benutzt wird? Aber
vermutlich ist das einfach nur copy/paste beim Experimentieren.
Ich sehe eigentlich keinen Grund, warum eine der Varianten nicht
funktionieren sollte, wenn die anderen tun. Alle Varianten auf dem
selben Prozessor getestest, auch mehrfach? Vielleicht ist einfach beim
Flashen was schiefgegangen?
Sebastian Götte schrieb:> Der folgende Code geht (Geflacker auf PD1/TX):
Hast du nur eine LED oder überprüfst du auch die ankommenden Zeichen?
Im ersten Fall könnte ich mit vorstellen, das '\n' einfach zu kurz (zu
wenig Bits gesetzt) ist, um es an einer LED zu erkennen.
Und um dem auch gleich (nochmal) den Wind aus den Segeln zu nehmen:
Die ersten beiden C Programme sind absolut gleichwertig. Es gibt keinen
ersichtlichen Grund für unterschiedliches externes Verhalten.
Thomas F. schrieb:> Das macht bestimmt nicht das, was du willst:char* s = "foobar\n"
Das macht seit Tag 0 der Erfindung von C das, was du willst, und wurde
bisher aus Kompatibilitätsgründen mit alten Programmen aus dieser Zeit
auch nie abgeschafft. Schöner ist allerdings heutzutage wirklich
>char s[] = "foobar\n"
Oliver
Sebastian Götte schrieb:> //Serial port setup> DDRD = 0x02;
Lass das mal weg. Wahrscheinlich ist TX ein input pin in open collector
Beschaltung. Die Leitung wird auf GND gezogen, um ein Startbit
anzukündigen.
Thomas F. schrieb:> Das macht bestimmt nicht das, was du willst:> char* s = "foobar\n">> Versuch mal dies:> char s[] = "foobar\n"Peter II schrieb:> doch macht es, ist ist beides das gleiche.
Es ist nicht das gleiche; es hat in dem Programm oben lediglich die
gleiche Wirkung.
Die erste Variante definiert ein char* Obkekt und initialisiert dies mit
der Adresse eines String-Lietrals wie .LC0.
Die zweite Variante legt ein Array an un initialisiert dies.
Programmierer schrieb:> Sebastian Götte schrieb:>> //Serial port setup>> DDRD = 0x02;>> Lass das mal weg.
Schaden kanns nicht. Ändern wirds nix.
Sobald die UART eingeschaltet wird, krallt sich diese die beiden Pins
und übernimmt die Kontrolle über die Datenrichtung.
Floh schrieb:> Hast du nur eine LED oder überprüfst du auch die ankommenden Zeichen?> Im ersten Fall könnte ich mit vorstellen, das '\n' einfach zu kurz (zu> wenig Bits gesetzt) ist, um es an einer LED zu erkennen.
Ich teste den Code auf einem Arduino-Board (benutze aber nicht die
Arduino-"Entwicklungsumgebung"). Dort flackert weder die tx-led (die in
Software auch bei einzelnen Zeichen auf wahrnehmbare Pulsweiten
gestreckt wird) noch sehe ich auf dem Computer irgendwas.
Thomas F. schrieb:> Das macht bestimmt nicht das, was du willst:char* s = "foobar\n"
Kurioserweise macht der Code, in dem das nicht dristeht Probleme, der
Code mit dieser unmodernen Formulierung funktioniert. Ich werd's aber
gleich nochmal anders probieren.
Rolf Magnus schrieb:> Wozu dereferenzieren, wenn das Ergebnis eh nicht benutzt wird? Aber> vermutlich ist das einfach nur copy/paste beim Experimentieren.
Ursprünglich war das "*(s++)" Argument vom uart_putc in der Schleife.
Der Code ist direkt aus der uart_puts-Funktion aus uart.c kopiert.
Bei mir geht Dein Code. Wie Du das Led-Flackern sehen willst ist mir
schleierhaft.
>Dort flackert weder die tx-led (die in Software auch bei einzelnen Zeichen>auf wahrnehmbare Pulsweiten gestreckt wird)
Wo wird in Deinem Code irgendwas gestreckt?
Benutzt Du HTerm oder ein Terminal dass Dir die Newlines wegschluckt und
nicht anzeigt?
Xenu schrieb:> Wo wird in Deinem Code irgendwas gestreckt?> Benutzt Du HTerm oder ein Terminal dass Dir die Newlines wegschluckt und> nicht anzeigt?
Auf dem Arduino Uno, den ich verwende wird ein ATMega16u2 als
USB-Seriell-Wandler missbraucht. Dessen Firmware lässt die LEDs blinken.
Hier der letzte Testcode (geht auch nicht, ob mit oder ohne delays):
> USB-Seriell-Wandler missbraucht. Dessen Firmware lässt die LEDs blinken.
Dann würde ich mich allerdings nicht auf das Flackern verlassen. Was
immer die Firmware macht, du hast es nicht unter Kontrolle.
Wenn schon, dann eine LED+220 Ohm an die Tx Leitung. Damit kannst du
eine Aussage treffen, aber auf irgendwelche Wandler, die irgendwie
flackern und keiner weiß wie genau, würde ich nicht setzen.
Das Problem könnte der Python-Dreizeiler sein.
Das "nicht" funktionierende Programm gibt ja nur Leerzeilen aus. Was
macht jetzt das Pythonprogramm beim Empfang von Leerzeilen?
Das Pythonprogramm gibt dann "\n\n" aus. Also zwei Leerzeilen. Es
funktioniert aber auch nicht, wenn ich wie im letzten Post beschrieben
außer '\n' noch Buchstaben auf die Leitung spamme.
Johann L. schrieb:> Thomas F. schrieb:>> Das macht bestimmt nicht das, was du willst:>> char* s = "foobar\n">>>> Versuch mal dies:>> char s[] = "foobar\n">> Peter II schrieb:>> doch macht es, ist ist beides das gleiche.>> Es ist nicht das gleiche; es hat in dem Programm oben lediglich die> gleiche Wirkung.
Genau, eine sehr kluge Aussage! Da hat jemand das Pointer-Konzept bis in
die Tiefe verstanden. Das muss man doch mal explizit loben. :)
> Die erste Variante definiert ein char* Obkekt und initialisiert dies mit> der Adresse eines String-Lietrals wie .LC0.
Abhängig vom Compiler und der System-Architektur kann diese
String-Konstante an unterschiedlichen Stellen im Speicher liegen. Häufig
wird sie am Ende des Programm-Codes mit eingebunden, wo alle Konstanten
liegen und befindet sich daher folglich im Speicherbereich für den Code.
Sie ist daher u.U. nicht änderbar.
> Die zweite Variante legt ein Array an un initialisiert dies.
Da dieses Array dann eine Variable ist (und keine Konstante wie beim
ersten Beispiel), liegt sie in dem Bereich, der für Variablen vorgesehen
ist, also z.B. im Stack und ist daher auch stets änderbar.
Die Unterschiede in der Wirkung der beiden Definitionen können in der
Praxis also ganz erheblich sein.
ronny, malte und jaqueline schrieb:> Typischer Anfängerfehler. Nimm doch statt diesem fehleranfälligen C> Gefrickel eine richtige Programmiersprache.
Würde eher sagen typisch dämliche, arrogante Anfängerbemerkung.
Naja, wenn man das Konzept von C (noch) nicht richtig verstanden hat,
kann man zu solchen Aussagen kommen. Ich erinnere mich noch lebhaft an
die Zeit Ende der 80er, in der ich angefangen habe, mit dem
Kernighan&Ritchie C zu lernen. Zuerst fand ich es super, als ich dann
etwas mehr verstanden hatte, habe ich es verflucht und das Buch in die
Ecke geworfen. Etwa ein Jahr später habe ich es dann wieder vorgeholt
und ab dann erst begann das echte Verstehen. Das Konzept von C muss sich
wirklich erst "setzen". Einige Jahre später erst begann die Begeisterung
für die Sprache, weil man merkt, was man damit alles machen kann und wie
extrem hoch sie sich aufgrund ihrer Architektur optimieren lässt.
Da C so völlig offen ist, kann man natürlich durch defines auch so viel
vermurksen, dass es tatsächlich unübersichtlich und scheinbar unlogisch
wird. Das hängt aber dann nicht mit der Sprache zusammen. Natürlich ist
ein System, das sehr stark beschränkt ist, immer konsistenter und
logischer. Ein Apple ist auch konsistenter als ein PC, aber auch nicht
so flexibel. Es ist immer eine Frage der Philosophie und des
Einsatzzwecks.
Ich habe schon von vielen gehört, dass das Erlernen von C in diesen drei
oben genannten Phasen abläuft. Es gibt sogar Leute die sagen "Wer diese
Phasen nicht durchlaufen und C nicht mindestens einmal verflucht hat,
der hat die Sprache nicht wirklich verstanden" ;-).
Volker U. schrieb:> Die Unterschiede in der Wirkung der beiden Definitionen können in der> Praxis also ganz erheblich sein.
Schon.
Aber nicht auf einem AVR mit avr-gcc.
So gesehen, war dieser Rat in der konkreten Situation nichts wert, weil
irrelevant.
Karl Heinz Buchegger schrieb:> Volker U. schrieb:>>> Die Unterschiede in der Wirkung der beiden Definitionen können in der>> Praxis also ganz erheblich sein.>> Schon.> Aber nicht auf einem AVR mit avr-gcc.
Deshalb schrieb ich auch "können" und "unter Umständen" sowie "Abhängig
vom Compiler und der System-Architektur".
> So gesehen, war dieser Rat in der konkreten Situation nichts wert, weil> irrelevant.
Ich fand es keineswegs irrelevant, darauf hinzuweisen. Auch wenn man mit
avr-gcc arbeitet, sollte man sich über die Bedeutung und Hintergründe
bestimmter Arten der Definitionen im Klaren sein. Selbst dann, wenn es
im konkreten Fall keine praktische Bedeutung hat. Wechselt man den
Compiler oder die Plattform, kann es plötzlich sehr bedeutungsvoll sein.
Im Hinblick auf Portabilität und universelle Verwendbarkeit sollte man
sich immer darüber im Klaren sein, was man tut.
Ich erinnere gern mal an das von Brian W. Kernighan (einem der
Mitentwickler der Sprache C) 1999 veröffentlichte Buch "The Practice of
Programming" (deutsch: Programmierpraxis). Dort werden die Prinzipien
"Simplicity, Clarity und Generality" als grundlegend für die
Programmierung dargestellt. Dazu gehört, dass man immer genau weiß, was
man tut und nicht nach dem Prinzip "Trial and Error" verfährt.
Volker U. schrieb:>> So gesehen, war dieser Rat in der konkreten Situation nichts wert, weil>> irrelevant.>> Ich fand es keineswegs irrelevant, darauf hinzuweisen. Auch wenn man mit> avr-gcc arbeitet, sollte man sich über die Bedeutung und Hintergründe> bestimmter Arten der Definitionen im Klaren sein. Selbst dann, wenn es> im konkreten Fall keine praktische Bedeutung hat. Wechselt man den> Compiler oder die Plattform, kann es plötzlich sehr bedeutungsvoll sein.> Im Hinblick auf Portabilität und universelle Verwendbarkeit sollte man> sich immer darüber im Klaren sein, was man tut.>> Ich erinnere gern mal an das von Brian W. Kernighan (einem der> Mitentwickler der Sprache C) 1999 veröffentlichte Buch "The Practice of> Programming" (deutsch: Programmierpraxis). Dort werden die Prinzipien> "Simplicity, Clarity und Generality" als grundlegend für die> Programmierung dargestellt. Dazu gehört, dass man immer genau weiß, was> man tut und nicht nach dem Prinzip "Trial and Error" verfährt.
Alles richtig.
Aber in der konkreten Situation hat der Rat
"Ändere das mal so um, vielleicht ist ja ...."
keine Bedeutung gehabt. Denn daran ist es ganz sicher in dieser
konkreten Situation nicht gelegen.
Wenn ein Audi-Fahrer nachfrägt, wie man beim A80 das Waschwasser
nachfüllt, macht es keine Sinn, ihm einen Vortrag über die allgemeinen
Gefahren beim Nachfüllen von Flüssigkeiten in allen Automarken zu
halten. Damit ist ihm nicht geholfen.
Und nein. Ich hab auch keine Idee, warum das eine präsentierten
Programme sich wie beschrieben verhält. Eigentlich dürften es das nicht.
Sebastian Götte schrieb:> Karl Heinz Buchegger schrieb:>> Dann würde ich mich allerdings nicht auf das Flackern verlassen. Was>> immer die Firmware macht, du hast es nicht unter Kontrolle.>> Ich vertrau dem schon, hier ist der Code:> https://github.com/arduino/Arduino/blob/master/hardware/arduino/firmwares/arduino-usbserial/Arduino-usbserial.c
An das Teil komm ich nicht ran, kann dahr auch nicht sagen, ob an dieser
Stelle in der Kette µC - Serial - USB - PC irgendwas passiert.
Allerdings ist es ja auch nicht gerade Raketentechnik, an einen Mega328
Pin mal eine LED+330Ohm drannzuhalten um zu sehen ob dort was flackert.
Der Test dauert keine 5 Sekunden und dann weißt du, ob beim fraglichen
Programm der 328 überhaupt etwas von sich gibt und der Mega16 in seiner
Eigenschaft als RS232/USB Wandler die Sache verbockt.
Karl Heinz Buchegger schrieb:> Aber in der konkreten Situation hat der Rat> "Ändere das mal so um, vielleicht ist ja ...."> keine Bedeutung gehabt. Denn daran ist es ganz sicher in dieser> konkreten Situation nicht gelegen.
Da sind wir uns einig.
> Wenn ein Audi-Fahrer nachfrägt, wie man beim A80 das Waschwasser> nachfüllt, macht es keine Sinn, ihm einen Vortrag über die allgemeinen> Gefahren beim Nachfüllen von Flüssigkeiten in allen Automarken zu> halten. Damit ist ihm nicht geholfen.
Der Vergleich hinkt aber etwas. Es ging ja darum, dass die beiden
Definitionen grundsätzlich nicht identisch sind. Man konnte die Aussage
"die sind gleich" so verstehen. Sie sind im vorliegenden, speziellen
Fall gleichwertig, aber nicht identisch. Und ich fand es daher schon
richtig, dies klarzustellen.
> Und nein. Ich hab auch keine Idee, warum das eine präsentierten> Programme sich wie beschrieben verhält. Eigentlich dürften es das nicht.
Deshalb denke ich auch, dass das Problem eher in uart.c oder der
Testumgebung zu suchen ist.