Hallo zusammen :) Entweder ist mein Ziel nur über einen Trick erreichbar, oder ich sehe den Wald vor lauter Bäumen nicht ;) Ich möchte an einem Atmega32 die Eingänge PA0 bis PA7 und PC0 bis PC6 als digitale Eingänge für einen Joystick mit mehreren Buttons nutzen. Bei den Eingängen PC0 bis PC6 ist das ja auch kein Problem. Aber bei PA0 bis PA7 (ADC0 bis ADC7) berechne ich derzeit immer die anliegende Spannung und wenn das Ergebnis größer 3V ist, dann ist der Eingang high. Das ist generell auch erst einmal so gewollt, da sich an diesen Eingängen 8 Feuerknöpfe befinden und ich so über die Spannung erkennen kann, ob ich zwischen 3V und 4V liege für Schnellfeuer oder über 4V für normales Feuer. Das hilft einem bei Spielen wie R-Type enorm weiter ;) Das kostet aber enorm rechenzeit und wenn es (wie in meinem Fall) Zeitkritisch wird, dann bekommt man ein Problem. Ich finde im Internet jedoch keine Anleitung, wie ich die ADCs deaktivieren kann. Eventuell suche ich auch einfach falsch. Und ohne diese zu deaktivieren ist die einzige Lösung, die mir einfällt, das höchste Bit auszulesen und wenn das gesetzt ist, dann ist das Signal high. Gibt es da noch einen eleganteren Weg? Danke vorab für eure Ideen :)
PORTA lässt sich doch ganz genau wie die anderen als digitaler I/O verwenden wie die anderen Ports? Oder verstehe ich dein Problem nicht?
Hallo, das sollte eigentlich nicht so sein, dann mußt du die ADCs ja aktiviert haben. Hast du jetzt vor, den eingang als reinen digitalen zu benutzen ? Oder soll er abwechselnd als AD und digitaler dienen ? Du kannst den ADC zur laufzeit auch wider ausmachen, dazu mußt du nur das register setzen. ist das register ADCSRA wichtig dort mußt du das ADEN flag löschen, dann sind die adc aus.
Gast
#4988349
> Du kannst den ADC zur laufzeit auch wider ausmachen Stimmt, ist jedoch nichtmal nötig. Alle Eingänge (auch die analogen) kann man bei AVR's jederzeit über die PIN Register abfragen, selbst wenn dort gerade Sonderfunktionen aktiviert sind.
Bei den alten ATmega32 lassen sich die Digitaleingänge noch nicht abschalten, d.h. sie sind immer parallel zu den Analogeingängen aktiv. Erst beim ATmega324 lassen sie sich abschalten.
Solange man die aber nicht explizit abschaltet, sind die Digitaleingänge aktiv. Digital high/low lässt sich daher immer über die PINn - Register abfragen. Oliver
@crazyhorse: Genau das dachte ich auch erst. Aber aus irgend einem Grund hat das nicht funktioniert. Auch wenn ich die internen Pull-Up-Resistors aktiviert habe, haben die Eingänge gemacht was sie wollten. @sharpals: Ich hatte sie im ursprünglichen Skript nicht explizit aktivert oder deaktiviert. Da ich zum ersten mal mit dem Atmega32 und diesen ADC-Eingängen arbeite dachte ich nun, dass die immer irgendwie als ADC genutzt werden müssen nachdem es ohne nicht funktioniert hat. Deshalb habe ich mir also einen Codeschnipsel aus dem Internet besorgt und diesen an meine Bedürfnisse angepasst und so lange damit rumgespielt bis ich diesen verstanden hatte. Ich mache später mal einen Rückbau des Codes und poste dann hier den Code wie er vor der Umstellung auf ADC war. Evtl. sieht ja einer den Fehler :) Danke für eure Zeit :)
Danke für eure Zeit @stefanus, @peda und @oliverso :)
Nein keine angst , du bist nicht verpflichtet, sie als ADC zu nutzen. Behandle sie als ganz normale eingänge und beseitige den codeteil und alles wird gut.
Frank N. schrieb: > Das kostet aber enorm rechenzeit und wenn es (wie in meinem Fall) > Zeitkritisch wird, dann bekommt man ein Problem. Ui ui ui, du kannst deinen Joystick schneller bedienen als ein AVR ein paar Messung macht und auswertet?!?
@corrtexx: gg Das nicht, aber der SNES und der MegaDrive geben ein sehr straffes Timing mit sehr knappen Reaktionszeiten vor ;) Ich hatte mittlerweile angefangen mit Interrupts zu arbeiten und entsprechend auf die Signale von den Konsolen zu reagieren. Aber auch da hatte ich das Problem, dass die Berechnungsdauer länger ist als die maximal zugelassene Reaktionszeit von den Konsolen. Darum versuche ich da zeit zu sparen um die Codestruktur nicht noch weiter verschachteln zu müssen ;)
Gast
#4988602
Hallo Das SNES verwendet AFAIK eine Shift-Register im Controller. Das kannst du mit SPI im slave mode simulieren. Das macht die Sache viel entspannter. Du kannst das nächste Byte schreiben während die Hardware gerade das aktuelle ausgibt. da1l6
Gast
#4989477
> Entweder ist mein Ziel nur über einen Trick erreichbar, oder ich > sehe den Wald vor lauter Bäumen nicht ;) Manchmal sieht man Vögel, die Mühsam eine lange Treppe herunter hoppeln. Und wenn sie dann unten angekommen sind, fliegen sie davon. Muss man nicht verstehen.
Gast
#4989496
Frank N. schrieb: > Ich hatte mittlerweile angefangen mit Interrupts zu arbeiten und > entsprechend auf die Signale von den Konsolen zu reagieren. Aber auch da > hatte ich das Problem, dass die Berechnungsdauer länger ist als die > maximal zugelassene Reaktionszeit von den Konsolen. dann wird deine Software wohl noch sehr suboptimal sein. Das sollte so ein Amtel bequem im Millisekundenbereich schaffen.
Frank N. schrieb: > Das kostet aber enorm rechenzeit und wenn es (wie in meinem Fall) > Zeitkritisch wird, dann bekommt man ein Problem. Dann machst Du was falsch. Nimm den ADC-Interrupt, lasse ihn das Ergebnis in ein Array schreiben und den MUX weiter schalten. Und für die Auswertung vergleichst Du einfach den Wert im Array mit der Schwelle (8Bit sollten reichen). Und natürlich rechnet man die ADC-Werte nicht in float Volts um, sondern läßt zur Compilezeit per #define die Volts in ADC-Schritte umrechnen.
1 | |
Dann dauert ein Vergleich <1µs und das ist nicht enorm.
Ist es mir gestattet eine dumme Frage zu stellen? Peter D. schrieb: > Und natürlich rechnet man die ADC-Werte nicht in float Volts um, sondern > läßt zur Compilezeit per #define die Volts in ADC-Schritte > umrechnen. > #define ADC_STEPS(volt) (uint8_t)(volt / 5.0 * 255) Durch den Define kopiert der Präprozessor den Code ja einfach nur, aber ausgeführt wird er doch zur Laufzeit. Sprich es findet eine Multiplikation und eine Division mit float Werten statt. Einzig der Wertevergleich ist dann auf Integerbasis und sollte schneller gehen. Das Rechnen mit float Werten spart man sich dadurch ja nicht. Oder meintest Du, dass damit das Rechnen mit float Werten in den Interrupt verlagert wird und in der Hauptschleife nur mit Integer Werten gerechnet/verglichen werden muß?
Clemens W. schrieb: > Durch den Define kopiert der Präprozessor den Code ja einfach nur, aber > ausgeführt wird er doch zur Laufzeit. Der Compiler ist faul. Wenn er einen konstanten Ausdruck sieht, rechnet er ihn sofort aus und fügt das Ergebnis ein, statt dafür noch umständlich Laufzeitcode zu erzeugen. Das Define dient nur der besseren Lesbarkeit für Dich. Schau einfach mal ins Assemblerlisting (*.lss).
Danke für Deine schnelle Antwort! Daran das der Ausdruck teilweise zur Kompilierzeit ausgewertet wird, hab ich nicht gedacht. Aber hab dann nochmal kurz darüber nachgedacht und bin darauf gekommen, dass der Vorteil auch in den kompletten späteren Zugriffen auf das Array und im Speicherverbrauch des Arrays selber liegen.
wird eigentlich der echte spannungsbereich gebraucht ? Wenn nicht reicht es doch aus den schwellwert , oder was sonst auf der basis von dem ADC zu ermitteln .. wenn also 4V gefordert werden, dann wäre es doch der wert 204 klassischer dreisatz : const wert = byte(geforderte_spannung / V_ref * 255) ; in diesem falle braucht die CPU garnichts ausrechnen;
Hallo zusammen :) Es tut mir Leid, dass es nun doch etwas länger gedauert hat, bis ich hier antworte. Ich habe keine Ahnung, was ich bei meinem ersten Versuch falsch gemacht hatte, da es nun auf Anhieb tadellos lief ... Hier mein Code und vielen Dank für eure Meinungen und eure Hilfe :)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.