- Labornetzteil AliExpress         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Problem mit Ausführungszeit bzw. micros() und delayMicroseconds()

  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645

    Problem mit Ausführungszeit bzw. micros() und delayMicroseconds()

    Anzeige

    Praxistest und DIY Projekte
    Hallo,

    ich habe folgenden Testcode für den Arduino Uno.
    Code:
    void setup() {
      Serial.begin(115200);
      while(!Serial){}
    
      pinMode(3,INPUT);
    }
    
    void loop() {
      int a = micros();
    
    
      int c = digitalRead(3);
      delayMicroseconds(1);
      
    
      int b = micros();
      b=(b-a)*4;
      Serial.println(b);
      delay(2000);
    }
    Ich will wissen, wieviel Zeit der Befehlsblock
    Code:
    int c = digitalRead(3);
      delayMicroseconds(1);
    in Anspruch nimmt. Ich erhalte eine Ausgabe, die sehr wechselhaft ist:
    Code:
    32
    16
    16
    32
    16
    32
    16
    16
    32
    16
    16
    16
    32
    16
    32
    16
    So weit ich das verstanden habe ist es doch auf dem UNO so, das micros() ein Vielfaches von 4 zurückgibt. Also multipliziere ich das Ergebnis mit 4. Dennoch braucht er einmal dann die doppelte Zeit zur Ausführung des Befehlsblocks? Ich denke:
    - dass der Controller hier entweder zwischendurch dann was anderes macht, was Zeit benötigt
    - der Mikrosekundenzähler eine relative Abweichung hat

    Vielleicht weiß jemand besser darüber bescheid und kann mal eine Erläuterung dazu geben, was diese Schwankungen hervorruft?

    Gruß, Moppi

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Hallo,

    also was micros() zurück gibt sind schon Mikrosekunden. Sie werden nur nicht im Mikrosekundentakt weitergezählt, weil die Leistung der Hardware das nicht hergibt.
    Letzteres kann auch ein Grund dafür sein, dass man eine Verzögerung von einer Mikrosekunde so eventuell nicht so hinkriegt.

    digitalRead ist eine ziemlich fette Funktion, die macht eine Menge Sachen. Das dauert sicher viel länger, als das Warten danach. Wenn man so schnell mit IOs arbeiten will, sollte man direkt mit den Ports arbeiten, oder ein entsprechendes Gegenstück zu digitalReadFast auf dem Teensy verwenden, da kenne ich mich mit den verfügbaren Libs für den Uno nicht aus.

    Zumindest theoretisch sollten bei digitalRead zeitliche Abweichungen entstehen, wenn da der Interrupt dazwischenfunkt, der die millis weiterzählt.

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645
    Ja das ist ja die Frage: was zwischendurch passiert.

    Ich habe jetzt eigentlich nicht gedacht, dass er anfängt über einen Interrupt die Microsekunden zu zählen. Gibt es dafür keinen Zähler, der nebenbei herläuft?

    Aufgrund dieser Sache mit der Auflösung von 4 Microsekunden pro Zählerwert, müsste dann als Minimum bei delayMicroseconds() eine 4 stehen, also eigentlich müsste man so schreiben: delayMicroseconds(1*4), was dann immer ein Vielfaches von 4 Microsekunden wäre.

    Nachtrag:

    Wenn ich mit dem Wert von 4 arbeite delayMicroseconds(4), dann habe ich immer denselben Wert von 32. Wenn ich delayMicroseconds() weg lasse dann erhalte ich immer wechselnde Werte von 16 und 32. Dasselbe, wenn ich delayMicroseconds(1) schreibe. Dauert das vielleicht mit dem Auslesen der Microsekunden via micros() unterschiedlich lange?
    Geändert von Moppi (19.09.2018 um 09:01 Uhr)

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Er zählt die Millisekunden über einen Interrupt. digitalRead ist so groß, dass es da gelegentlich eine Unterbrechung geben kann.

    Ich kenne nur die micros() Implementierung für die 32 Bit Teensys, um die für AVR zu suchen habe ich weder Lust noch Zeit.

    Reduziert aufs wesentliche sieht der Code für micros() auf dem Teensy so aus:
    Code:
    uint32_t micros(void)
    {
    	uint32_t count, current;
    
    	__disable_irq();
    
    	current = SYST_CVR;
    	count = systick_millis_count;
    
    	__enable_irq();
    
    	current = ((F_CPU / 1000) - 1) - current;
    
    	return count * 1000 + current / (F_CPU / 1000000);
    }
    Wird also aus millis und einem schnell laufenden Zähler berechnet.

    Geht wahrscheinlich auf einem AVR ähnlich.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645
    Das mit dem Multiplizieren mit 4 beim UNO Rev3 ist jedenfalls irgendwie Quatsch. Wenn ich micros auslese gibt er ganz normal micros zurück (nix mit 4 oder so) - wenn ich das mit millis vergleiche. Wenn ich millis auslese, soll er ja auch millis zurückgeben.

    Na ja, entscheidend für mich ist, dass ich immer dieselbe Messeinheit dort auslese, um Verarbeitungszeiten untereinander zu beurteilen.

    Danke für Deine Hilfe mxt!

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Moppi Beitrag anzeigen
    Das mit dem Multiplizieren mit 4 beim UNO Rev3 ist jedenfalls irgendwie Quatsch.
    Hast du schon mal 3 oder 5 oder 6 oder 7 als Ergebniss bekommen?

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Wie man hier lesen kann, ist micros() bei den Arduino 8-Bittern mit einem Zähler implementiert, der alle 4 us weiterzählt
    https://ucexperiment.wordpress.com/2...cros-function/
    Die Einheit ist also Mikrosekunden aber die Auflösung nur 4 Mikrosekunden. Zu multiplizieren gibt es da nichts, das macht micros schon intern.

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645
    Danke für den Hinweis!




    Um aber nicht wieder einen neuen Thread aufzumachen:

    Nachdem ich nun gestern ATmega328 ohne Bootloader bekommen habe, war ich gezwungen, mich den halben Tag damit auseinanderzusetzen, inkl. Beschaltung und Quarz.

    Ich habe mal im Datenblatt geschaut, wegen Geschwindigkeit:

    Speed Grade:
    ̶ 0 - 4MHz@1.8 - 5.5V, 0 - 10MHz@2.7 - 5.5.V, 0 - 20MHz @ 4.5 - 5.5V

    Mal gucken, ob ich das richtig denke, zum 328P:

    Man kann den mit max. 10 MHz bei 3.3V betreiben?
    Man kann den mit max. 20 MHz an 5V betreiben?
    Die unterste Grenze liegt bei 0 Hz? - Dann tut er nichts mehr.

    Den 328P findet man immer mit 16MHz@5V betrieben. Warum nicht mit 18MHz oder 20MHz?
    Weniger MHz = geringere Geschwindigkeit = geringerer Stromverbrauch?

    Und wenn ich schon beim Fragen bin:

    Der interne Taktgeber, so habe ich im Netz gelesen, kann auch benutzt werden. Das muss aber über diese Fuse-Bits eingestellt werden. Wo ändert man die? - Wohl beim Bootlader aufspielen. Aber wo stehen die im Sketch ArduinoISP? - Dort müssten die doch zu finden sein. Oder stehen die in einer extra Datei, die man ändern muss?

    Noch was zu einem externen Takt: muss das ein Quarz sein oder kann das auch was anderes sein? Wie ein Takt am Digitalausgang eines anderen Mikrokontrollers? - Dann könnte man auch an einem andern ein PWM-Pin abgreifen.
    Geändert von Moppi (20.09.2018 um 05:39 Uhr)

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Ich versuche mal einen Teil zu beantworten, den Rest werden ggf. Leute erklären, die sich mehr mit den AVRs auskennen.

    Den 328P findet man immer mit 16MHz@5V betrieben.
    Das stimmt nicht, ich kenne z.B. Displays, wo er als Controller verbaut ist, die arbeiten mit 10,... oder 14,... MHz. Das braucht man auch, um bestimmte Baudraten bei der seriellen Schnittstelle exakt hinzubekommen, die werden nämlich durch ganzzahlige Teilung aus dem Takt erzeugt.
    Und ich bin sicher, hier im Forum gibt es Leute, die verwenden ihn bei 20 MHz.

    Weniger MHz = geringere Geschwindigkeit = geringerer Stromverbrauch?
    Das gilt für den Prozessor, aber nicht für Bauteile drum herum, wie z.B. Spannungsregler.

    Aber wo stehen die im Sketch ArduinoISP?
    Wenn der Sketch aus der IDE gemeint ist: Gar nicht. Dieser Sketch dient dazu aus einem Arduino einen Programmer zu machen. Das ist nicht der Code für einen Bootloader.

    muss das ein Quarz sein oder kann das auch was anderes sein?
    Bei einem normalen Uno ist das kein Quarz, sondern aus Kostengründen ein Keramikresonator. Der ist billiger, hat aber einer größere Toleranz bei der Frequenz.
    Digitalausgang statt Quarz glaube ich nicht.
    Auch darf die Frequenz eher nicht variabel sein, die Teilerverhältnisse für millis, Serial, I2C, SPI, PWM usw. sind bei den Dingern ja meist fest eingestellt.
    Geändert von Mxt (20.09.2018 um 07:59 Uhr)

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645
    Zitat Zitat von Mxt Beitrag anzeigen
    Auch darf die Frequenz eher nicht variabel sein, die Teilerverhältnisse für millis, Serial, I2C, SPI, PWM usw. sind bei den Dingern ja meist fest eingestellt.
    So etwas habe ich mir auch gedacht. Weswegen die UNOs wohl dann immer mit 16MHz betrieben werden - dazu habe ich gerade das hier gefunden: https://www.mikrocontroller.net/topic/341298

    ZU den Fuse-Bits habe ich auch was passendes gefunden:

    Geändert von Moppi (20.09.2018 um 09:15 Uhr)

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Antworten: 48
    Letzter Beitrag: 16.11.2014, 07:46
  2. Antworten: 2
    Letzter Beitrag: 01.11.2012, 15:21
  3. ATMega32 UART problem --> Problem gelöst
    Von ChristophB im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 12.03.2010, 18:45
  4. Problem mit Atmega644P Erkennung (Bascom-Versions-Problem)
    Von Rohbotiker im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 11.08.2008, 18:52
  5. [ERLEDIGT] Wie am einfachsten Ausführungszeit Unterprogramms messen?
    Von PICture im Forum PIC Controller
    Antworten: 11
    Letzter Beitrag: 06.05.2006, 23:50

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen