Hallo! Hab mich entschlossen von Bascom auf Assembler umzusteigen, und schon steh ich vor einem kleinem Problem: Ich möchte ein kleines Oszi mit dem ATMega 8 bastelln (gab's glaub ich schon öfter). Als Auflösung nehm ich wegen der Datenmenge 8Bit. Diese möchte ich z.B. in Register R16 laden und immer wenn UDR leer ist (also wieder ein Byte übertragen werden kann) an den PC übertragen. Ohne den Interrupt (also mit ständigem abfragen des UDRE-Bits) funktioniert alles prima! Wenn ich das jetzt allerdings mit dem Interrupt für das UDRE-Register machen will kommt nix am PC an. Brauche ich da einen anderen Interrupt (Transmit Complete statt UDR-Empty)? Wäre auch toll wenn ihr mir noch Tips zur Optimierung geben könntet (den ADC wollte ich irgendwann auch noch per Interrupt ansprechen, nicht in einer Schleife). Ich will das die Datenrate (Baudrate wird noch erhöht) möglichst hoch ist...also die vollen 9600Baud ausgenutzt werden! MfG BastiK
Hallo Basti, also den Assembler kannst Du Dir noch sparen - ich denke der Flaschenhals ist bei Dir die serielle Schnittstelle. Ich hoffe, Du hast zum Übertragen nicht den Print-Befehl verwendet, der kostet nämlich viel Zeit. Seriell senden in Bascom (Schnittstelle vorher initialisieren natürlich): '------------------------------------------------- 'hier den ADC starten XXX 'während der ADC mißt - Wert der letzten Messung senden UDR=myByte 'Byte in den Sendepuffer schreiben Do:Loop Until UCSRA.UDRE=1 'Warten bis Senden fertig ist 'hier den ADC auslesen myByte = XXX '------------------------------------------------- Bei 9600 Baud kannst Du maximal etwa bis 500 Hz sinnvoll messen. Wenn der Prozessor nebenbei noch was anderes tun soll, kannst Du die Schleife da oben in eine Timer-Interrupt-Routine einbinden, die Baudrate erhöhen und testen, wie weit Du den Timer beschleunigen kannst, ohne Interrupts zu verlieren. Optimieren kann man nch mit der Reihenfolge der Befehle und dem ADC-Modus. Viel Spaß beim Basteln!
Hallo! Ich denke das dieses Projekt gut zum "Eingewöhnen" in den Assembler ist. In Bascom ist das alles für mich kein Problem (da alles Vorgekaut ist), aber in Assembler schon! Die 9600Baud sind ja eigentlich nur am Anfang zum ausprobieren, mit dem angeschlossenen 3,6864MHz Quarz kann ich ja bis 230400 Baud gehen! Ggf. wird das ganze nochmal seperat aufgebaut mit kleinerem AVR und schnellerem Takt. Da ist dann eine Schleife etwas blöd, da ich ja noch ein paar Takte benötige um die neuen Werte in ein Register zu laden und wieder auszugeben! Weisst du vielleicht trotzdem wie ich das in Assembler mit dem Interrupt drehen muss? MfG Basti
In Assembler mußt Du u.a. Interrupt-Vektoren beschreiben usw. Ein gutes Tutoial dafür fand ich hier: http://www.avr-asm-tutorial.net/avr_de/index.html Also ich habe gute Ergebnisse beim Tuning erreicht (und das ist sicher auch für Deinen geplanten "Umstieg" ganz lehrreich und weniger frustrierend), indem ich Assembler und Bascom erstmal gemixt habe - so kannst Du z.B. weiter in Bascom die ISR mit der Option NoSave deklarieren ("On UTXC myISR NoSave") und dann in der ISR Assembler verwenden - das ist sehr schnell. Wenn Du wissen willst wie schnell genau (oder vergleichen Basic/Assembler), kannst Du sehr schön im Bascom-Simulator an den Clocks sehen, daß z.B. ein Do:loop until.. mindestens 14 Takte braucht, währenddessen das gleiche in Assembler nur 4-5 Takte dauert.
Hallo. Es gibt eine nette kleine Falle, wenn Du mit Int bei UDRE arbeitest. Wenn Du das erste Byte in das UDR geschrieben hast, ist es ratzfatz schon wieder leer, weil es ja nur zum Senderegisterc durchgereicht wird, und der zweite Int folgt unmittelbar hinterher. Erst danach geht alles seinen geregelten Gang. Eine zweite Falle ist, dass der Int bei nicht vorhandenen Daten nicht einfach verlassen werden darf, weil dann der UDRE-Int dauernd weiter zuschlägt. Das Int-Bit wird nicht wie bei anderen Ints durch das Ausführen der Service Routine rückgesetzt. Wenn also der Int erfolgt, aber gerade kein Byte gesendet werden soll, muss das gesetzte Int-Bit explizit zurückgesetzt werden. Im data sheet steht dazu: "When interrupt-driven data transmission is used, the Data Register empty Interrupt routine must either write new data to UDR in order to clear UDRE or disable the Data Register". Das ist gar nicht schön, weil "disable the data register" soviel heißt wie "setze UDRE zurück". Damit ist der Int dann auch gleich mit abgeschaltet. Und muss dann zur Auslösung eines Int einmalig manuell wieder gesetzt werden. Hier ist es Atmel gelungen, die Maximalverwirrung anzurichten. Ich finde, wenn Du eine feste Datenrate einstellen willst, dann mache die Datenrate nicht vom USART abhängig. Nimm lieber eine feste Rate (z.B. Timer- oder ADC-gesteuert), wähle eine Baudrate, die groß genug ist und sende das Ergebnis blind ab. Damit gibt es keine Konflikte mit dem Int. Ansonsten wünsche ich Dir viel Erfolg mit Assembler. Wenn Du erst mal richtig merkst, wie rasch und einfach die Mehrzahl der Aufgaben in Assembler zu lösen sind, wirst Du wahrscheinlich süchtig danach. mfg gerd
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.