Wenn ich deinen Code im Simulator laufen lasse, dann brauchen die beiden If-Abfragen schon jeweils 28 Takte.
Ein GetADC(0) dagegen nur 27.
Falls dies auch in Hardware so ist, solltest du vielleicht doch den Standard-Befehl nehmen.
Hallo,
um meinen timingkritischen Code zu schonen, will ich weder einen Interrupt bei fertiger AD-Wandlung setzen, noch auf eine einzelne Wandlung warten. Deshalb habe ich folgendes ausgeknobelt:
Ich möchte ADC0 und ADC1 abfragen, deshalb setze ich abwechselnd die Register. Je nach gesetztem Register und ob das Readyflag gesetzt ist, fülle ich eine Variable.
Im Datasheet steht zum löschen des Adcsra.adif ich solle 1 reinschreiben!?!
Ich frage nach 1 ab und setze dann 1 !?!
Stimmt das so oder ist das kompletter Rossmist?
GünterCode:If Admux = &B01000000 And Adcsra.adif = 1 Then Adcsra.adif = 1 Data_array(6) = Adcl Admux = &B01000001 'ADC1 setzen Data_array(5) = Adch Elseif Admux = &B01000001 And Adcsra.adif = 1 Then Adcsra.adif = 1 Data_array(8) = Adcl Admux = &B01000000 'ADC0 setzen Data_array(7) = Adch End If
Wenn ich deinen Code im Simulator laufen lasse, dann brauchen die beiden If-Abfragen schon jeweils 28 Takte.
Ein GetADC(0) dagegen nur 27.
Falls dies auch in Hardware so ist, solltest du vielleicht doch den Standard-Befehl nehmen.
Das leuchtet ein!
Also Rossmist
Sehr ressourcenintensiv sind Arrays, ohne die sollte das nicht mehr Rossmist sein.
mfg
Wenn doch schon die IF's so lang brauchen...
Das mit GetADC kann man so nicht ganz stehen lassen.
GetADC würde 28 Zyklen brauchen, wenn die Wandlung selbst nicht auch noch dauern würde. In Deinem Code steht leider nix von wegen Prozessortakt oder ADC Prescaler, aber mal angenommen 8MHz CPU Takt, bei 10Bit Genauigkeit gehen laut Datenblatt maximal 200kHz ADC Clock, macht einen möglichen ADC Prescaler von 64. Eine normale Wandlung dauert 13 ADC Takte, also 13 * 64 = 832 CPU Takte.
GetADC(Ch) macht zur Sicherheit immer 2 Wandlungen hintereinander, also ist die Ausführungsdauer 28 + 2 * (64*13) = 1692 CPU Takte, da musst Du Dir wegen 28 Takten für die If's nun wirklich keine Gedanken machen
Das eigentliche Problem aber ist, daß GetADC den Ablauf blockiert, bis die Wandlung abgeschlossen ist.
Den Vorteil, den man beim manuellen Starten des ADC gewinnen kann, ist daß man Hauptcode ausführen kann, während der ADC im Hintergrund wandelt. Das ADIF abzufragen ist unnötig und aufwändiger, da man es rücksetzen muss, nimm lieber den Einzelwandlungsmode und starte immer wieder eine Wandlung, nachdem die vorige Wandlung beendet wurde.
Das geschieht mit ADCSRA.ADSC = 1, wenn ADSC wieder 0 ist, dann wurde die Wandlung beendet.
Beim Umschalten des Mux darauf achten, die erste Wandlung zu verwerfen.
Mist rein, Mist raus, also was denn nun?
Also ich baue das jetztmal auf und schalte einen Ausgangspin um.
Dann kann ich das mit dem Oszi nachmessen.
Außerdem lasse ich in einem Interrupt einen Pin Toggeln, dann sehe ich inwieweit Interrupts beeinflusst werden.
Dann haben wir Klarheit.
Günter
Probier's aus, dann wirst Du sehen, daß GetADC schon ein bisserl braucht. Lies auch mal ADCSRA aus, damit Du siehst, welchen ADC Prescaler von Bascom gewählt wird, ich nehm' an Du hast "Auto" in Config ADC eingestellt.Zitat von guenter1604
Interrupts werden nicht beeinflusst, da diese die Warteschleife unterbrechen, in der GetADC während einer Wandlung läuft.
Bau so etwas in Deinen Code rein, dann wird im Hintergrund gewandelt, darin musst Du Dich auch noch um die Mux Umschaltung, bzw. Verwerfen des ersten Ergebnisses nach der Umschaltung kümmern.
Code:If ADCSRA.ADSC = 0 Then ADC_result = ADC ... ADCSRA.ADSC = 1 End If
Lesezeichen