Hallo,
Zitat Zitat von Klebwax Beitrag anzeigen
Was soll in 500ns (in Worten Nanosekunden) wohl sinnvolles passieren? Da kann man kaum einen Call, ein Return und das Retten von einem Register unterbringen.
Er bekommt in die 500ns immerhin 37 NOPs rein @72MHz.

Je nach CPU kann man in dieser Zeit schon einiges rechnen.

- - - Aktualisiert - - -

Zitat Zitat von HaWe Beitrag anzeigen
ich verwende für solche "Probleme" grundsätzlich Multitasking, und zwar
Auch bei 72MHz reichen die 500ns nicht einmal für einen Taskswitch des Schedulers aus. Hier ist dann meist die Anzahl CPU-Register das Problem.
Bei 32 Registern und einem PUSH/POP ALL-Befehl kommt man für den Wechsel auf mindestens ein Äquivalent von etwa 100 NOPs. Dann nochmals zurück, sind dann 200 NOPs, wo 37 reichen würden. Wenn die Busbreite nur die Hälfte der Registerbreite beträgt ist es gleich mal das Doppelte.

500ns sind einfach eine doofe Zeit für dieses Problem

Eine Möglichkeit habe ich noch vergessen, meist hat man so etwas:
Code:
put_LCD(char c)
{
  Daten ausgeben
  Delay(500ns)
  Strobe setzen
  Strobe rücksetzen
}

LCD_Out(char *s)
  {
    while (*s)
     {
        put_LCD(*s);
        s++;
        // evtl. noch weiteres.
     }
  }
Wenn man jetzt eben nicht streng strukturiert programmiert, kann man "s++:" und weiteres in das delay(500ns); verlegen.
Code:
put_LCD(char c)
{
  c ausgeben
  Delay(500ns)
  Strobe setzen
  Strobe rücksetzen
}

LCD_Out(char *s)
  {
    while (*s)
     {
       c ausgeben
       s++;
       // evtl. noch weiteres.
      Delay(Restzeit)
      Strobe setzen
      Strobe rücksetzen
     }
  }
Ist dann halt nicht so übersichtlich, aber sogar schneller, weil der Overhead für den Aufruf von put_LCD() wegfällt.
Allerdings muss man sehen, dass man die Optimierung des Compiler ausschaltet, sonst weiss man nicht was ab geht.
Sinnvoll kann auch der Einsatz von Inline Assembler an dieser Stelle sein, das kann der Compiler dann nicht optimieren und man hat immer den selben Code.
Allerdings trägt man dann selber die Verantwortung, wenn sich die CPU-Frequenz ändert. Das lässt sich aber teilweise mit Macros automatisieren.
Besonders bei CISC-CPUs muss man dann aber noch aufpassen, dass kompatible CPU-Versionen nicht unbedingt die selbe Zyklenzahl für die Befehle benötigen.
Bei RISC-CPUs ändert die Zyklenzahl meistens nicht, da sie meistens der Anzahl Speicherzyklen entspricht.
In beiden Fällen spielt dann aber noch das Pipelining und vorhandener Cache ins Timing mit rein.
Hier kann es auch hilfreich sein, JMPs an Stelle der NOPs zu verwenden.

Ach, früher war das alles einfacher

MfG Peter(TOO)