ich weis nicht wieso aber, es lässt sich irgendwie nicht machen, dass
ich per ADEN den ADC ausschalte
die Unterprogramme habe ich der Textdatei beschrieben
> .include "m16def.inc" ;Definitionsdatei des Mega8
Da ist entweder der Kommentar oder der Filename falsch. Die beiden
genannten Prozessoren sind sich aber tatsächlich sehr ähnlich, so dass
das noch nicht der gesuchte Fehler sein muss.
Was aber der Fehler ist, hast Du weder genau genug beschrieben noch hast
Du den nötigen Code geliefert. Wenn man nach dem sucht, finden sich nur
ein paar .include-Direktiven.
Hallo,
in Inhalt.txt steht:
> DisableADC:> cbi ADMUX, ADEN> ret> EnableADC:> sbi ADMUX, ADEN> ret
Hast du nicht ins Datenblatt geschaut? Das Bit ADEN ist nicht im ADMUX,
sondern im ADCSRA-Register zu finden ...
>Hast du nicht ins Datenblatt geschaut? Das Bit ADEN ist nicht im ADMUX,>sondern im ADCSRA-Register zu finden ..
hah danke, natürlich habe ich im Datenblatt nachgeschaut, jedoch merke
ich mir die Register nie und habe hier wahrscheinlich irrtümlich das
falsche genommen
lg andy
Ah, den Code hast Du nachgeliefert, das hat sich mit meiner Antwort
überschnitten.
Und der Fehler äüßert sich nun genau worin?
Übrigens: StartADC wartet nicht, bis der ADC fertig ist, sondern kehrt
in diesem Fall sofort zurück. Das kann vielleicht noch gewünscht sein.
Aber für den Fall, dass der ADC 'fertig' meldet, läuft es in die Wüste
(in den hier nicht beschriebenen Code danach).
Hi
Hat es einen bestimmten Grund, das du dein Programm auf zig, fast leere,
Dateien verteilst?
Ebenfalls ist es recht sinnfrei, Programmteile, die nur einmal benötigt
werden, (z.B. Stackinitialisierung) in Unterprogramme zu packen.
Sinnvoller ist es, z.B. die Umschaltung der Kanäle in einem
Unterprogramm zu machen. Die Kanalnummer wird einfach in einem Register
übergeben.
Im Datenblatt findest du übrigens ein Codebeispiel aus dem du ersehen
kannst, wie man eine ADC-Wandlung startet und auf das Ergebnis wartet.
MfG Spess
> Hat es einen bestimmten Grund, das du dein Programm auf zig, fast leere,> Dateien verteilst?
Ich mach's auch manchmal, weil Blättern zum anderen Editorfenster
schneller geht als Scrollen und Zurückscrollen im längeren Quältext. Und
ich muss (dank Alzheimer Light) oft nachschaun, wie ich denn nun meine
Labels auf Konstanten, Register, RAM-Bereiche und Routinen genannt habe.
Daher rechnet sich das Aufsplitten des Quältextes gelegentlich. Meist
kopiere ich die Teile aber später wieder zusammen.
Bei den restlichen Punkten stimme ich Dir zu.
Ich kann mir aber gut vorstellen, dass man versucht, modular zu
programmieren und wie bei einer Hochsprache alles in "Funktionen" zu
packen. Das täuscht Übersichtlichkeit vor, verbraucht aber aufgrund
unnötiger Sprünge und Rücksprünge unnötig Ressourcen. Dieselbe
Übersichtlichkeit erreicht man auch mit ein paar Kommentaren. ;-)
...
Anstatt Dich tot zupushen, definier Dir lieber ein paar
Scratchpadregister, die jede Funktion zerstören darf.
Und nenn die Programme wie es sich gehört *.asm.
*.txt ist für Prosa (Liebesbriefe usw.) reserviert.
Peter
Hannes Lux schrieb:> Ich kann mir aber gut vorstellen, dass man versucht, modular zu> programmieren und wie bei einer Hochsprache alles in "Funktionen" zu> packen. Das täuscht Übersichtlichkeit vor, verbraucht aber aufgrund> unnötiger Sprünge und Rücksprünge unnötig Ressourcen.
Das ist einer der Vorteile einer Hochsprache, sie kann beim Optimieren
alle nur einmal aufgerufene Funktionen inlinen.
Peter
spess53 schrieb:> Hi>>>Anstatt Dich tot zupushen, definier Dir lieber ein paar>>Scratchpadregister, die jede Funktion zerstören darf.>> Dann lieber push/pop.
Wenn man unbedingt deutlich größeren und langsameren Code als jeder
C-Compiler produzieren will.
Peter
Hi
>Wenn man unbedingt deutlich größeren und langsameren Code als jeder>C-Compiler produzieren will.
Das gleicht der Compiler mit seinen Registerkonventionen wieder aus.
MfG Spess
hat der Programmierer schon ein wenig übertrieben. Das ist zwar (aus
Registersicht) alles abgesichert, jedoch stehen die Chancen, dass dieser
Code in einer tief verschatelten Aufrufhierarchie aufgerufen wird, nicht
besonders gut. Benutzt man, wie Peter meint, ein paar Scratchpad
Register, die jeder nach Gutdünken verändern darf (in dem Fall r16),
dann ist man ds 'Problem' erst mal los.
Der Programmierer wollte eben Universalroutinen haben, die er überall
einsetzen kann ohne sich grossartig Gedanken zu machen. Dagegen ist
erstmal nicht viel zu sagen, ausser: Machs dann wenigstens richtig! Wenn
die Funktion nur einen bestimmten Kanal einstellen soll, dann soll sie
auch nur das tun! D.h. die restlichen Bits in ADMUX sind für die
Funktion tabu und dürfen nicht verändert werden.
So wie sie jetzt ist, ist diese Funktion nicht Fisch und nicht Fleisch.
>Übrigens: StartADC wartet nicht, bis der ADC fertig ist, sondern kehrt>in diesem Fall sofort zurück.
wie lässt es sich denn anders schreiben?
>So wie sie jetzt ist, ist diese Funktion nicht Fisch und nicht Fleisch.
Soweit ich weiss gibt man bei sbr cbr genauso wie bei sbi cbi als
zweiten Operanden die Bitnummer an.
D.h.:
cbr r16, 3
entspricht:
ori r16, 1<<3
Also wäre "sbr r16, 0" => "ori r16, 1". Damit würde man Kanal 1 setzen
nicht 0.
Hi
>Soweit ich weiss gibt man bei sbr cbr genauso wie bei sbi cbi als>zweiten Operanden die Bitnummer an.
Soweit das Instruction Set richtig ist, kann der 2.Operant einen Wert
von 0..$FF annehmen.
Entspricht einem ANDI mir dem Komplement des Operanten.
MfG Spess
Karl heinz Buchegger schrieb im Beitrag #1665879
> ...> Wenn> die Funktion nur einen bestimmten Kanal einstellen soll, dann soll sie> auch nur das tun! D.h. die restlichen Bits in ADMUX sind für die> Funktion tabu und dürfen nicht verändert werden.
Das ist generell erstmal richtig und wird von mir nicht angezweifelt.
Bei ADMUX sehe ich das aber anders. Da gehören die Bits einfach
zusammen. Zu jedem ADC-Kanal gehört auch die Referenzeinstellung und
auch (sofern es auch in ADMUX liegt) die Formatierung (links/rechts) des
Ergebnisses (ADLAR). Hier sehe ich Referenz und Resultatformat als
Bestandteil (Zusatzparameter) des Kanals. Somit ziehe ich das direkte
Zuweisen des ganzen Bytes vor. Ich bevorzuge dabei ein temporäres
Register, das nicht gesichert werden muss und undeutsch
"Scratchregister" genannt werden könnte.
Ich generiere dafür aber keine extra "Funktion". Ist nur ein Kanal
abzufragen, so wird das im Ini-Bereich eingestellt, sind mehrere Kanäle
abzufragen, so wird das Setzen von ADMUX Bestandteil der zyklisch
aufgerufenen Ausleseroutine (ADC-Interrupt oder durch Timer
synchronisiertes Auslesen).
Dieser zyklisch aufgerufene Job legt das geholte ADC-Ergebnis in ein
Array (mit oder ohne Mittelwertbildung), zählt den Index hoch (oder
runter) und begrenzt ihn, holt aus einem weiteren Array (mit demselben
Index, in ASM durch Zugriff über LDD) den ADMUX-Wert für die nächste
Wandlung und startet den ADC wieder. Somit erfolgt im Hintergrund reihum
die Wandlung aller Kanäle mit den zugehörigen Parametern (Referenz,
Format), ohne dass man sich weiter darum kümmern muss.
Die Mainloop holt sich die Werte dann aus dem Array, da liegt dann immer
der letzte Wert bzw. der Mittelwert der letzten Messungen. Und das zu
jeder Zeit für jeden Kanal.
...
>Soweit ich weiss gibt man bei sbr cbr genauso wie bei sbi cbi als>zweiten Operanden die Bitnummer an.>D.h.:>cbr r16, 3>entspricht:>ori r16, 1<<3>Also wäre "sbr r16, 0" => "ori r16, 1". Damit würde man Kanal 1 setzen>nicht 0.
ich habs schon ausgetestet, was ich stehen habe passt
>Ich generiere dafür aber keine extra "Funktion". Ist nur ein Kanal>abzufragen, so wird das im Ini-Bereich eingestellt, sind mehrere Kanäle>abzufragen, so wird das Setzen von ADMUX Bestandteil der zyklisch>aufgerufenen Ausleseroutine (ADC-Interrupt oder durch Timer>synchronisiertes Auslesen).>Dieser zyklisch aufgerufene Job legt das geholte ADC-Ergebnis in ein>Array (mit oder ohne Mittelwertbildung), zählt den Index hoch (oder>runter) und begrenzt ihn, holt aus einem weiteren Array (mit demselben>Index, in ASM durch Zugriff über LDD) den ADMUX-Wert für die nächste>Wandlung und startet den ADC wieder. Somit erfolgt im Hintergrund reihum>die Wandlung aller Kanäle mit den zugehörigen Parametern (Referenz,>Format), ohne dass man sich weiter darum kümmern muss.>Die Mainloop holt sich die Werte dann aus dem Array, da liegt dann immer>der letzte Wert bzw. der Mittelwert der letzten Messungen. Und das zu>jeder Zeit für jeden Kanal.
sry is mir im Moment viel zu hoch