INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
TimerOne Speed
09.08.2016, 16:51 (Dieser Beitrag wurde zuletzt bearbeitet: 09.08.2016 16:57 von Mathias.)
Beitrag #1
TimerOne Speed
Bei diesem Code schaltet die LED-Array zwischen Pin 0 und Pin 7 alle ca. 10 Sekunden um.
Code:
void multiplex()
{
    PORTD = (PORTD << 1) | (PORTD >> 7);
}

void setup() {
    DDRD=255;
    PORTD=0B10001000;

    Timer1.initialize(1000 * 100);
    Timer1.attachInterrupt(multiplex);
}

void loop() {

}

Ersetze ich in dieser Zeile die 100 durch 10, müsste der Timer eigentlich 10x schneller werden.
Code:
Timer1.initialize(1000 * 10);
Aber es wird nicht 10x schneller, sondern gefühlt etwa 500x schneller.

Wieso ?

Nachtrag:

Komischerweise machen auch diese beiden Zeilen nicht das gleiche, obwohl 1'000 x 100, das selbe ist wie 100'000 .
Code:
    Timer1.initialize(1000*100);
    Timer1.initialize(100000);
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.08.2016, 17:24
Beitrag #2
RE: TimerOne Speed
Hallo Mathias,

irgendwo habe ich mal gelesen, dass es nicht wirklich ratsam ist in der ISR (multiplex) die Ports zu schalten.
Alternativ lieber eine globale Variable benutzen und diese in der ISR setzen.
Im loop() dann die Variable auswerten, die Ports schalten und die Variable zurücksetzen.
Wäre nett zu erfahren ob das was bringt.
Grüße Ricardo

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.08.2016, 19:20 (Dieser Beitrag wurde zuletzt bearbeitet: 09.08.2016 19:21 von Mathias.)
Beitrag #3
RE: TimerOne Speed
Zitat:Im loop() dann die Variable auswerten, die Ports schalten und die Variable zurücksetzen.
Genau, dies will ich verhindern, weil in der loop verschiedene Berechnung hinkommen und diese dauern natürlich unterschiedlich lange und dann würde die LED-Matrix flackern.
Bei einem Timer bin ich sicher, das die Bild-Wiederholfrequenz immer gleich hoch ist und somit ein stabiles Bild habe.

Ich noch etwas zum eigentlich Problem heraus gefunden.

Code:
    Serial.println(100000);
    Serial.println(10000 * 10);
    Serial.println(1000 * 100);
gibt folgendes:
Code:
100000
-31072
-31072
So wie es aussieht gibt es ein Problem mit den Integern.
Code:
../Blink.ino:40:25: warning: integer overflow in expression [-Woverflow]
  Serial.println(10000 * 10);
                         ^
../Blink.ino:41:24: warning: integer overflow in expression [-Woverflow]
  Serial.println(1000 * 100);
Ich denke, das Problem liegt an den 16Bit-Integern vom Atmege328.

Timer1.initialize verlangt einen unsigned long

So wie es scheint, muss ich bei C++ den long erzwingen:
Code:
    Serial.println(100000);
    Serial.println(10000L * 10);
    Serial.println(1000L * 100);
Jetzt kommt bei allen 3 Zeilen 100'000 .
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.08.2016, 23:35
Beitrag #4
RE: TimerOne Speed
Hey!

Hast dus ja selbst rausgefunden, aber nur generell:
Wird die Zahl im signed int Bereich (+- ~32k) angegeben (direkt) werden sie auch als diese angenommen. Wird danach dann eine Operation durchgeführt, gilt dann natürlich auch nur der signed int Bereich (außer die 2. Variable is außerhalb des Bereichs). Ein einfache Denkprobe durchführen ob's drüber oder drunter liegt - hilft oft.
Da ein UNSIGNED noch erwartet wird, kannst du auch "1000UL* 100" schreiben (UL = unsigned long).

@rkhuele: Beziehst du das Port-Schalten in ISR nur auf Multiplex-Anwendungen? Ich wüsste nicht wieso das "schlecht" sein soll?
Aufpassen muss man nur, damit man nicht andere Ports währenddessen schaltet, dh. meist "PORTx |= (1 << DDBx);" anstatt "PORTx = (1 << DDBx);" verwenden (nicht bezogen auf dieses Thema).

mfg Scheams
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
10.08.2016, 18:43
Beitrag #5
RE: TimerOne Speed
Zitat:Da ein UNSIGNED noch erwartet wird, kannst du auch "1000UL* 100" schreiben (UL = unsigned long).
Gibt es noch mehrer solche Kürzel, wie L, UL, F, etc.
Ich habe schon gegooget, habe aber keine Zusammenstellung gefunden.

Aber irgendwie ist dies
traurig, das der Kompiler 1000 * 100 nicht automatisch einen Long macht.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Mega: Hardware i2c bus speed (Wire.) verändern? HaWe 10 2.915 14.07.2016 20:09
Letzter Beitrag: Mathias

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste