Go Down

Topic: Frage: Direkte Port Manipulation (Read 1 time) previous topic - next topic

mkl0815

Ich vermute mal das es knapp wird. Allerdings nicht wegen der Bitschieberei, die sollte schnell genug sein. Allerdings laufen außerhalb von loop() im eigentlich main() noch einige Serial-Event Abfragen die evtl. vom Compiler nicht wegoptimiert werden, jenachdem was sonst so im Sketch steht und damit wird dann Zeit zwischen den loop() Durchläufen verbraten.
Siehe main.cpp :

Code: [Select]
#include <Arduino.h>

int main(void)
{
        init();

#if defined(USBCON)
        USBDevice.attach();
#endif

        setup();

        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }

        return 0;
}

MaFu

Habs grad mal zwei Versionen getestet.
Code: [Select]
unsigned long i;
unsigned long zeit;

void setup()
{
  DDRB = DDRB & B11111101;
  DDRC = DDRC | B00000010;

  Serial.print("\nTeste 1000000x direct port mapping\n");
  i = 0;
  zeit = micros();
}

void loop()
{
  if (i >= 1000000)
  {
    zeit = micros() - zeit;
    Serial.print("Dauer: ");
    Serial.print(zeit);
    Serial.print(" Mikrosekunden = ");
    Serial.print(zeit / 1000);
    Serial.print(" Millisekunden\n");
    while (1);
  }
  // Lese Pin 15 und Schreibe den Wert nach Pin 3
  PORTC = (PORTC & B11111101) | (PINB & B00000010);
  i++;
}

Wenn loop() immer wieder neu durchlaufen wird dauert es für 1 Million Lese/Schreib-Zugriffe 4904704 Mikrosekunden, also fast 5 Sekunden.

Code: [Select]
unsigned long i;
unsigned long zeit;

void setup()
{
  DDRB = DDRB & B11111101;
  DDRC = DDRC | B00000010;
}

void loop()
{
  Serial.print("\nTeste 1000000x direct port mapping\n");
  i = 0;
  zeit = micros();
  for (;;)
  {
    if (i >= 1000000)
    {
      zeit = micros() - zeit;
      Serial.print("Dauer: ");
      Serial.print(zeit);
      Serial.print(" Mikrosekunden = ");
      Serial.print(zeit / 1000);
      Serial.print(" Millisekunden\n");
      while (1);
    }
    // Lese Pin 15 und Schreibe den Wert nach Pin 3
    PORTC = (PORTC & B11111101) | (PINB & B00000010);
    i++;
  }
}

Fast der gleiche Code, allerdings wird loop() nicht mehr verlassen, sondern eine eigene Endlosschleife verwendet.
Dauer für 1 Million Lese/Schreib-Zugriffe ist nun 1383620 Mikrosekunden, also knapp 1,4 Sekunden.
_______
Manfred

DANINO24

Danke für die tolle Hilfe. Leider ist mein Mega 2560 definitiv zu langsam!

Jetzt überlege ich das Arduino Due mit 84 MHz zu kaufen.
Gibt es hier auch Quellen für die "direkte Port Manipulation" bzw. kann ich das obere Programm leicht umschreiben, um es auf dem Due auszuführen?

MfG

MaFu

#13
Jan 23, 2013, 10:50 am Last Edit: Jan 23, 2013, 10:53 am by MaFu Reason: 1
Ich befürchte, da sieht es mit Informationen noch mau aus. Zumindest hier im Deutschen Teil hab ich noch nirgends gelesen, dass einer schon den Due hätte.
Rein theoretisch müsste es beim Due auch so gehen und der sollte nach den Spezifikationen mehr als schnell genug dafür sein.

Darf man fragen, was eigentlich das Ziel des Projektes ist? Weil nur das Signal durchschleifen macht ja nicht gerade viel Sinn.  :D
_______
Manfred

voithian

#14
Jan 23, 2013, 11:12 am Last Edit: Jan 23, 2013, 11:16 am by voithian Reason: 1

Danke für die tolle Hilfe. Leider ist mein Mega 2560 definitiv zu langsam!


Quote from: DANINO24

Jetzt zum Hintergrund:

Ich habe als Input ein Taktsignal, das ca. 1,5 MHz schnell ist. Jetzt wollte ich schauen ob mein Arduino Board schnell genug ist dieses Signal zu verarbeiten. Sprich Taktsignal lesen und auf einen anderen Pin schreiben. Den Pin dann mit einem Oszilloskop betrachten und schauen, ob ich da auch 1,5 MHz erhalten.


Für mich erschließt sich noch nicht der Sinn der ganzen Aktion mit dem Lesen und Schreiben der Port-Bits. Geht es nur um das Prinzip, ob man ein 1,5 MHz-Eingangssignal  mit einem mit 16 MHz betriebenen 8-Bit Mikrocontroller softwaremäßig verarbeiten kann oder steckt da noch etwas "sinnvolles" dahinter, was du uns noch nicht verraten hast (wobei natürlich auch der Lerneffekt und das Wissen sinnvoll sein kann)  ;)

Ich denke, auch wenn du einen schnelleren Controller verwendest und das Lesen und Schreiben der Port-Bits damit halbwegs funktionieren sollte, wirst du spätestens bei einer etwas umfangreicheren Verarbeitung des Eingangssignals an die Grenzen eines Mikrocontollers stoßen.

Das sollte dann meiner Meinung nach der Zeitpunkt sein, über das Konzept generell nachzudenken.

Ich sehe gerade, nachdem ich diesen Beitrag gepostet hatte, dass sich MaFu im Beitrag vorher die gleiche Frage gestellt hat ;)

Wolfgang





Go Up