Ich möchte in meinem MEGA128-Projekt einen zusätzlichen gepollten SW-UART implementieren, da die beiden HW-USARTS anderweitig benötigt werden, einen Interrupt für einen INT-gesteuerten SW-UART habe ich auch nicht zur Verfügung. Nun gibt es ja die ATMEL-AppNote 305, die genau so eine Funktion beschreibt, samt Beispielcode - allerdings für einen anderen Prozessor (sollte jedoch problemlos portierbar sein) und vor allem in Assembler. Da ich WINAVR einsetze und mich bislang mit Assembler kaum asueinandergesetzt habe, habe ich ehrlich gesagt keinen rechten Plan, wie ich den Code dieser AppNote direkt übernehmen könnte. Kann mir da jemand ein wenig auf die Sprünge helfen? Sollte der Code vorzugsweise als separate Library oder als Inlinestatement eingebunden werden?
Du weißt was pollen bedeutet ? Es bedeutet, Du rufst die Empfangsroutine auf und erst dann darf die Gegenstelle ein Startbit senden. Und Du bleibst solange in dieser Routine hängen, bis auch wirklich ein Startbit angekommen ist. Daher eignet sich SW-UART-Polling nur für sehr kleine Programme, die nichts weiter zu tun haben. Wenn aber nebenbei noch 2 andere UARTs rumquäken und womöglich noch gepuffert werden soll, gehts nur über den Timerinterrupt (siehe Codesammlung). Peter
Mir ist schon klar, was pollen bedeutet. Das Ganze soll ein RS485/422-Logger werden, der sowohl bei einer Vollduplexverbindung mitlauschen bzw. zwischengeschaltet Protokollinformationen umsetzen können soll (dafür habe ich die beiden HW-USARTS vorgesehen). Wenn hier nur Halpduplex vorkäme, hätte ich nicht beide USARTS verplant. Der SW-UART soll wirklich nur Daten, die gegebenenfalls aufgenommen wurden, zum PC übertragen bzw. eventuell abzusetzende Sequenzen vom PC erhalten. In diesem (nennen wir es mal "Offline"-) Betriebszustand soll keine weitere Aktion erfolgen. Das Gerät wird ansonsten mit einer kleinen Tastatur und einem Display ausgestattet.
Nochmal ich: Es muss natürlich Halbduplex und nicht Halpduplex heißen!
@Peter: Man kann doch auch in einem Timerinterrupt Pollen. Dann hat man eine Software Uart
@Simon "Man kann doch auch in einem Timerinterrupt Pollen" Dann hat man einen Jitter oder muß ein vielfaches der Baudrate pollen. Genauer gehts mit dem Capture-Interrupt und dann Compare für die nächsten Bits (siehe mein Beispiel in der Codesammlung). Wenn man keine 16Bit PWM braucht, ist T1 ideal für die SW-UART. Wichtig ist aber, alle anderen Interrupts schön kurz zu halten, da ja der AVR leider keine Interruptprioritäten hat. Peter
Vielen Dank für die bisherigen Kommentare. Das der von mir gewählte Weg absolut nicht das Optimum darstellt, ist mir klar. Aber erstens habe ich in meiner Schaltung keinen Capture-Input zur Verfügung und zweitens würde ich gern generell wissen, wie am besten Assembler-Code in einem C-Projekt eingebunden wird. Es muss doch prinzipiell möglich sein, so ähnlich wie bei den C-Includes, die per Makefile separat compiliert werden, per Assembler ein relozierbares Modul zu erstellen, das letztlich dazugelinkt wird, oder? Ich habe nur leider keine Idee, wie das zu bewerkstelligen ist.
"Aber erstens habe ich in meiner Schaltung keinen Capture-Input zur Verfügung" Meinst Du damit, daß Du die beiden Capture-Eingänge (IC1, IC3) für was anderes benötigst ? Wenn Du sagen könntest für was, dann könnte man überlegen, ob man einen freisetzen kann für die SW-UART. Peter
> Es muss doch prinzipiell möglich sein, so ähnlich wie bei den > C-Includes, die per Makefile separat compiliert werden, per > Assembler ein relozierbares Modul zu erstellen, das letztlich > dazugelinkt wird, oder? Na klar. > Ich habe nur leider keine Idee, wie das zu bewerkstelligen ist. Ein avr-libc-Demo dafür habe ich in Vorbereitung, ist aber noch nicht fertig. Du benennst die Datei auf .S endend (großes S) und nennst sie dem Compiler mit als Quelldatei. Falls du das WinAVR-Makefile-Template benutzt, müsste es wohl einen Makro ASRC oder sowas geben dafür. Anhand des großen S weiß der Compiler, dass er diese Datei nicht compilieren soll, sondern lediglich durch den Präprozessor schicken (damit #include und #define aufgelöst werden) und danach assemblieren lassen soll. Das Ergebnis ist dann ein Objektmodul. http://www.nongnu.org/avr-libc/user-manual/assembler.html kennst du schon, hoffe ich mal...
@Peter: dass dabei Jitter entsteht weiß ich auch, aber Pollen hat nicht zwangsläufig was mit der Main-Loop zu tun. PS: Man könnte doch auch einen Pinchange INT für solche Geschichten nehmen.
@Simon, "Man könnte doch auch einen Pinchange INT für solche Geschichten nehmen." ist aber umständlicher. Beim Capture-Interrupt hat man den genauen Zeitstempel gratis und sogar ne Störunterdrückung. Und das Capture wird in der Regel nur sehr selten benötigt. Daher wundert es mich, daß roboguy sogar beide Capture-Eingänge benötigt (wofür bloß ?). Der einzige Hinderungsgrund ist der, daß T1 und T3 in dem PWM-Modus laufen, wo sie auch rückwärts zählen, da dann das Capture keinen Sinn mehr macht. Peter
Dachte den PCINT als Alternative. Aber lassen wir uns doch erstmal die Beschaltung der beiden Capture-Eingänge sagen.
Also, um das kurz klarzustellen: Ich betreibe das Ganze nebenberuflich und mehr aus Interesse (um nicht einzurosten und etwas Neues kennenzu- und dazuzulernen), möchte aber auch ein wenig praktischen Nutzen daraus ziehen. Als ich die Schaltung entworfen habe, bin ich da ziemlich unbedarft drangegangen und habe mir über den SW-UART wenig Gedanken gemacht. Ursprünglich wollte ich alles mittels BASCOM erschlagen. BASCOM ermöglicht einen SW-UART, ohne dass (zwangsweise) ein Capture-Input verwendet werden muss. Bei BASCOM gibt es jedoch den einen oder anderen Punkt, der mir nicht so ganz gefällt. Deshalb mein Ansatz, das Ganze mittels C zu realisieren. Wenn ich das Projekt überarbeiten würde, gäbe es mit Sicherheit die Möglichkeit, ISR-gesteuert zu arbeiten. Aber da es diese AppNote nun einmal gibt (die zugegebenermaßen nicht das Gelbe vom Ei ist), und ich gern wissen und lernen möchte, ASM-Code auf diese Weise einzubinden ist dieses Posting entstanden, möchte ich diesen Ansatz erst einmal weiterverfolgen.
"BASCOM ermöglicht einen SW-UART" Bascom kann auch nur mit Wasser kochen. Entweder es pollt den Pin bis zum St. Nimmerleinstag in der Mainloop oder es braucht auch den Timer. "lernen möchte, ASM-Code auf diese Weise einzubinden" Allgemein sind Assemblerprogramme C-feindlich geschrieben. Z.B. sie verwenden erstmal alle Register, ehe sie auf SRAM auslagern (was ja auch sinnvoll ist) und plazieren alles an direkte Adressen. D.h. um ASM mit C zu verheiraten muß man das Programm schon komplett verstanden haben und auch in ASM und C Profi sein. Ich verheirate daher C mit ASM nur im äußersten Notfall, wenn es von der Laufzeit her nicht anders geht (schnelle Interrupts), sonst lohnt sich der Aufwand einfach nicht. Man hat schneller die Funktion in C umgeschrieben und das gute Gefühl sich kein faules Portabilitätsei ins Nest gelegt zu haben (Wartbarkeit, Erweiterbarkeit). Peter
Hallo Allerseits, kann mir jemand aus Erfahrung sagen, welche maximale Baudrate bei einem SWUART verlässliche Daten liefert? Das system läuft bereits mit einer Baudrate 1MHz, allerdings mit HWUART. Da die Signalübertragung über ein Spulensystem stattfindet und ich eine Spule umpolen sollte, negiert sich also auch mein Signal. Soweit mir bekannt ist, kann der ATmega48 beim HWUART das Signal nicht invertieren. Folglich bleibt mir nur der SWUART. Langsamer darf ich aber nicht werden. Falls ich mich in etwas irre oder jemand eine tolle Idee oder Lösung hat, wäre das toll. Danke Gruß Chris
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.