Florian schrieb:
> Hallo zusammen,
> ich möchte einen analogen Joystick mit 2 Achsen auswerten. Dazu benutze
> ich
> bei meinem ATmega8 den AD Wandler.
> Da ich eine konstante Durchlaufzeit des Programms will (für spätere
> Regelung), nutze ich keine Interrupts.
gerade für den Teil, der eine gleichbleibende Aufrufsequenz benötigt,
solltest du dann Interrupts nehmen. Einen Timer der regelmässig eine ISR
aufruft und schon hast du deinen gleichbleibenden Takt, in den du die
Regelschleife packst. Das bischen Jitter, das du in den ISR Aufrufen
hast, wird wohl die Regelung nicht ausser Tritt bringen.
> Werte nur "updaten", wenn der AD Wandler fertig ist mit seiner Wandlung,
> ansonsten möchte ich die alten Werte benutzen:
um ehrlich zu sein:
Das hier
>
> old_Kanal = Kanal;
> Kanal = (((~(ADCSRA & (1<<ADSC))>>ADSC) & ~Kanal)) & 1; // Kanal
> ändern, wenn
> // Wandlung abgeschlossen
hab ich nicht wirklich verstanden. (Habs aber auch nicht großartig
analysiert)
Kommt mir ehrlich gesagt auch übermässig kompliziert vor:
1 | void GetJoystick(uint8_t* JoyStick)
|
2 | {
|
3 | static uint8_t kanal = 0;
|
4 |
|
5 | if( ADCSRA & ( 1 << ADSC ) ) // Wandlung läuft noch?
|
6 | return; // yep: das wars
|
7 |
|
8 | Joystick[kanal] = ADC; // Nö Wandlung ist fertig. Ergebnis abholen
|
9 |
|
10 | kanal = 1 - kanal; // der andere Kanal ist drann
|
11 |
|
12 | // Neue Wandlung starten. Das Ergebnis
|
13 | // wird im nächsten Aufruf abgeholt, wenn es
|
14 | // dann schon fertig ist.
|
15 | ADMUX = (ADMUX & ~(0x1F)) | (kanal & 0x1f);
|
16 | ADCSRA |= (1<<ADSC);
|
17 | }
|
so würde ich das machen.
Und da ich den Teil, der ein exaktes Timing benötigt, in eine ISR
verbannt habe, macht es mir auch nichts aus, wenn die Durchlaufzeit
durch die ADC Funktion nicht in allen Fällen gleich ist.