Forum: Mikrocontroller und Digitale Elektronik STM32: Prozessortakte (Zeit) herausfinden für delay routine (hd44780)


von Alex (Gast)


Lesenswert?

Hi
ich verwende das STM32F407 discovery board und möchte damit das hd44780 
display ansteuern. Ich verwende den internen Oszillator und betreibe 
meinen uC mit 16MHz.

Die LCD Routinen hier auf uC.net basieren auf die _delay_us() Funktion 
aus der AVR-Bibliothek.

Ich möchte mir meine eigene delay Routine schreiben, weiß aber nicht so 
recht, wie viel Zeit in meiner for-Loop vergeht.

Ist das aus dem übersetzten Code ablesbar?

Aus meiner main Funktion:
1
  for(;;)
2
  {
3
    int i = 0;
4
    for(i;i<1000;i++)
5
    {
6
      // Do nothing
7
    }
8
  }

Der übersetzte Code, in der sich die for Schleife befindet:
1
 45         funcGPIOInit();
2
0800021e:   bl      0x800024a <funcGPIOInit>
3
 46         funcIntInit();
4
08000222:   bl      0x8000266 <funcIntInit>
5
 50           int i = 0;
6
08000226:   movs    r3, #0
7
08000228:   str     r3, [r7, #4]
8
 51           for(i;i<1000;i++)
9
0800022a:   b.n     0x8000232 <main+30>
10
0800022c:   ldr     r3, [r7, #4]
11
0800022e:   adds    r3, #1
12
08000230:   str     r3, [r7, #4]
13
08000232:   ldr     r3, [r7, #4]
14
08000234:   cmp.w   r3, #1000       ; 0x3e8
15
08000238:   blt.n   0x800022c <main+24>

Allerdings weiß ich nicht, ob dieser Ansatz zielführend ist.

Danke für eure Hilfe.

Gruß,

von Guest (Gast)


Lesenswert?

Alex schrieb:
> und betreibe meinen uC mit 16MHz.

Eine Schande :(

Alex schrieb:
> Ich möchte mir meine eigene delay Routine schreiben, weiß aber nicht so
> recht, wie viel Zeit in meiner for-Loop vergeht.

Delay ist Murks, das geht schöner. Ansonsten wenn du HAL benutzt gibt es 
die HAL delay Funktion. Wenn nicht benutz den Systick counter oder einen 
Timer.

von Wolfgang (Gast)


Lesenswert?

Alex schrieb:
> Ich möchte mir meine eigene delay Routine schreiben, weiß aber nicht so
> recht, wie viel Zeit in meiner for-Loop vergeht.

Notfalls kannst du es mit einem LA oder Oszi nachmessen. Oder du 
verwendest eine Entwicklungsumgebung mit Debugger, der in der Lage ist 
Programmlaufzeiten und/oder Taktzyklen zu messen.

> // Do nothing
Und pass auf, dass dir nicht irgendeine Compileroptimierung das "// Do 
nothing" mitsamt der Schleife rausschmeißt ;-)

von Jim M. (turboj)


Lesenswert?

Alex schrieb:
> wie viel Zeit in meiner for-Loop vergeht.

Gar keine, wenn der Optimizer angeschaltet ist.

von Klaus S. (skibby)


Lesenswert?

Ich benutze folgende Routinen:
1
volatile unsigned int *DWT_CYCCNT     = (volatile unsigned int *)0xE0001004; //address of the register
2
volatile unsigned int *DWT_CONTROL    = (volatile unsigned int *)0xE0001000; //address of the register
3
volatile unsigned int *SCB_DEMCR      = (volatile unsigned int *)0xE000EDFC; //address of the register
4
5
void init_cycle_counter()
6
{
7
  // Init cycle counter
8
  *SCB_DEMCR = *SCB_DEMCR | 0x01000000;
9
  *DWT_CYCCNT = 0; // reset the counter
10
  *DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter
11
}
12
13
uint32_t read_cycle_counter()
14
{
15
  return *DWT_CYCCNT;
16
}
17
18
void delay_us(uint32_t time_us)
19
{
20
  uint32_t cyc1 = *DWT_CYCCNT;
21
  if (time_us>0)
22
  {
23
    while ((*DWT_CYCCNT-cyc1)<=(SystemCoreClock/1000000)*(time_us-1)){};
24
  }
25
}

von PittyJ (Gast)


Lesenswert?

Das erste, was ich bei meinen Prozessoren machen, ist irgendein Timer in 
Gang bringen. Oft einen im Sekundenbereich (für externe Synchronisation) 
, und einen im Millisekundenbereich (mehr für interne Zwecke).

Gibts es auf einem STM32F407 keine Timer?? Schwache Architektur.

Obwohl ich bei
https://www.st.com/en/microcontrollers-microprocessors/stm32f407-417.html
lese: Up to 17 timers: 16- and 32-bit running at up to 168 MHz

Wohl eher schwacher Programmierer?

von Alex (Gast)


Lesenswert?

Hi,
PittyJ schrieb:
> Wohl eher schwacher Programmierer?

Ja, sogar sehr schwacher Programmierer. :)
Da ich aber neu im Bereich uC bin (ein paar Wochen), erlaube ich mir 
diese Unschönheiten für den Anfang.

Obwohl...

Timer und Interrupts habe ich bereits erfolgreich programmiert, und die 
delays über Timer funktionieren super im Bereich 20us bis hin zu 15ms, 
also in dem Bereich, den ich für meine LCD Ansteuerung benötige.

Ich dachte allerdings bis dato, dass ein dedizierter Timer für eine LCD 
Initialisierung mit Kanonen auf Spatzen geschossen ist, auch wenn man 
bis zu 17 Timer zu verfügung hat.

Guest schrieb:
> Alex schrieb:
>> und betreibe meinen uC mit 16MHz.
>
> Eine Schande :(
Ja, mit PLL habe ich mich noch nicht auseinander gesetzt. Das kommt 
später dran. Schritt für Schritt. :)


Klaus S. schrieb:
> Ich benutze folgende Routinen:

Hi Klaus,
den SysTick Timer kannte ich noch gar nicht - mein Reference manual 
schreibt darüber nichts, und Google weist mich auf die CMSIS Bibliothek 
hin. Da werde ich mich mal einlesen. Das wäre in der Tat eine elegante 
Lösung, ohne dafür extra einen Timer zu opfern (auch wenn es genug Timer 
zur Verfügung gibt).

Wieder etwas Neues dazu gelernt, danke. :)

Wolfgang schrieb:
> Oder du
> verwendest eine Entwicklungsumgebung mit Debugger, der in der Lage ist
> Programmlaufzeiten und/oder Taktzyklen zu messen.

Rein aus Neugier (auch für spätere/andere Zwecke):
Ich verwende STM32CubeIDE und kann meinen STM32F407 sogar debuggen. 
Aber... wie genau finde ich die Zeit heraus, die für die Ausführung 
bestimmter Code Passagen benötigt wird? Ich verwende den Debugger bis 
jetzt meist, um Funktionsaufrufe etc. zu überprüfen. 
Zeit/Zyklusmessungen habe ich damit noch nicht durchgeführt.

Danke und Gruß,

von Johannes S. (Gast)


Lesenswert?

Alex schrieb:
> Ich verwende STM32CubeIDE

da bekommst du doch ein HAL_Delay() geschenkt.

Zyklenzähler war doch schon genannt, DWT.
Zeiten mit HAL_GetTick() wenn es gröber auch ok ist.

von Alex (Gast)


Lesenswert?

Johannes S. schrieb:
> da bekommst du doch ein HAL_Delay() geschenkt.

Ja, aber HAL möchte ich (noch) nicht verwenden. Ich habe die Ambition, 
die ersten Schritte ohne HAL zu gehen, um die Hardware besser kennen zu 
lernen.

Gruß,

von Guest (Gast)


Lesenswert?

Dann nimm einen Timer und gut ist. Du wirst mich andere Timing Aufgaben 
haben und meistens lassen die sich mehr oder weniger alle mit einem 
Timer erschlagen. Dazu sind die schließlich gemacht, der hat die ja 
nicht eingebaut damit sie gut aussehen sondern damit man sie benutzt. Du 
kaufst dir ja auch meinen uC mit FPU wenn du dann doch alles mit 
integern berechnest. Und keiner geht hin und macht Software SPI wenn er 
3 oder 4 hardware controller dafür hat...

von Johannes S. (Gast)


Lesenswert?

Man kann in HAL bzw. LL Funktionen ja abgucken, da wird der SysTick 
benutzt und das sind nur ein paar Zeilen den zu aktivieren. Im SysTick 
Interrupt wird nur ein Zähler hochgezählt. Das HAL_Delay merkt sich dann 
nur den aktuellen Stand und wartet solange Zähler < Soll ist.
Init ist in LL_InitTick in _ll_utils.h Und die ISR im Startupcode 
setzen.

von Stefan F. (Gast)


Lesenswert?

Alex schrieb:
> Aber... wie genau finde ich die Zeit heraus, die für die Ausführung
> bestimmter Code Passagen benötigt wird?

Der Weg über den Assembler Code war schon richtig. In der Doku des 
Befehlssatzes steht für jeden Befehl, wie viele CPU Takte er benötigt. 
Teilweise hängt die Anzahl von Bedingungen ab.

Bei höheren Taktfrequenzen wirst du die allerdings mit zusätzlichen 
Verzögerungen wegen Flash Wait States herumschlagen müssen, die 
größtenteils aber nicht komplett durch eine Prefetch Cache ausgeglichen 
werden.

Um das Ganze zu vereinfachen: Messe die Zeit einfach mit einer Stoppuhr 
und passe die Zahl so lange an, bis es stimmt. Fange mal damit an:
1
void delay(uint32_t msec)
2
{
3
    for (uint32_t j=0; j < 4000UL * msec; j++)
4
    {
5
        __NOP();
6
    }
7
}
8
9
int main()
10
{
11
    ...
12
    delay(10000);

Die 4000 habe ich geraten.

von Alex (Gast)


Lesenswert?

Ich merke: Ihr seid Ingenieure/ITler und keine Pädagogen :)

Auch wenn ich mich geschlagen gebe, für die LCD Initialisierung nun 
einen Timer zu verwenden, bin ich mir sicher, dass man aus dem 
übersetzten Maschinencode (indirekt) ablesen kann, wie viele Zyklen für 
einen Codeauschnitt verwendet werden.

Hier ein Beispiel, dass es möglich sein sollte:
https://ucexperiment.wordpress.com/2013/06/15/the-lost-art-of-cycle-counting/

Gruß,

von Johannes S. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Der Weg über den Assembler Code war schon richtig.

aber umständlich und fehleranfällig, warum nicht den Zyklenzähler nutzen 
wenn er schon vorhanden ist? Der Code wurde doch auch schon geliefert:
Beitrag "Re: STM32: Prozessortakte (Zeit) herausfinden für delay routine (hd44780)"

von Christopher J. (christopher_j23)


Lesenswert?

Alex schrieb:
> Auch wenn ich mich geschlagen gebe, für die LCD Initialisierung nun
> einen Timer zu verwenden, bin ich mir sicher, dass man aus dem
> übersetzten Maschinencode (indirekt) ablesen kann, wie viele Zyklen für
> einen Codeauschnitt verwendet werden.

Aus dem Maschinencode die Zeit herauszulesen, die für die Abarbeitung 
der Befehle benötigt wird ist prinzipiell möglich (mit ein paar 
Ausnahmen mit unbestimmter Zyklendauer, z.B. Division). Die Frage ist 
nur ob das Sinnvoll ist, schließlich willst du ja nicht in Assembler 
programmieren und ob der Compiler mit unterschiedlichen 
Optimierungsstufen dann immer den selben Maschinencode generiert, das 
steht auf einem ganz anderen Blatt. Zusätzliche Fallstricke, die oben 
schon erwähnt wurden sind dann Flash-Watestates, Prefetch-Buffer und bei 
größeren Controllern (z.B. Cortex-M7) dann noch zusätzliche Caches.

Kurzum, nimm einen Timer bzw. den CYCCNT. Der Grund warum das in dem 
AVR-Tutorial anders gemacht wurde ist schlicht und einfach, dass der AVR 
vergleichsweise wenige Timer hat, so etwas wie einen Cycle-Counter nicht 
kennt und man sich beim AVR um Flash-Watestates und Caches keine Sorgen 
machen braucht.

: Bearbeitet durch User
von Alex (Gast)


Lesenswert?

Vielen Dank an euch alle :)

Gruß,

von leo (Gast)


Lesenswert?

Alex schrieb:
> Hier ein Beispiel, dass es möglich sein sollte:
> https://ucexperiment.wordpress.com/2013/06/15/the-lost-art-of-cycle-counting/

Der Artikel ist alt, das Thema verliert immer mehr an Aktualitaet. 
Moderne Prozessoren habe keine fixen Ausfuehungszeiten pro Befehl wegen:
- Pipelining
- Out-Of-Order Execution
- variablen Takt, Drosselung, Hitzemanagment
- Interruptroutinen
- Speicherzugriffszonen
- Codealignment
usw.

D.h. ist es sicher nuetzlich das simple Cycle-Zaehlen durch Besseres zu 
ersetzen.

leo

von leo (Gast)


Lesenswert?

leo schrieb:
> D.h. ist es sicher nuetzlich das simple Cycle-Zaehlen durch Besseres zu
> ersetzen.

Und nicht unwichtig: vielleicht soll der Prozessor noch mehr was 
arbeiten, als nur stumpf zu zaehlen.

leo

von Stefan F. (Gast)


Lesenswert?

Blöderweise kann man den Zyklenzähler auf einem Cortex M0 nicht so 
einfach verwenden. Beim F4 ist das aber sicher eine gute Idee.

von Alex (Gast)


Lesenswert?

leo schrieb:
> Moderne Prozessoren habe keine fixen Ausfuehungszeiten pro Befehl wegen:
> - Pipelining
> - Out-Of-Order Execution
> - variablen Takt, Drosselung, Hitzemanagment
> - Interruptroutinen
> - Speicherzugriffszonen
> - Codealignment
> usw.

Okay, das war mir nicht so ganz klar. Vielen Dank für den Hinweis. Damit 
schließe ich das Kapitel Zykelzählen nun endgültig ab.

Dann gehe ich mit der Zeit und verwende einen Timer für meine delays und 
wenn ich Zykel zählen muss, werde ich es über den SysTick machen. :)

Vielen Dank an alle.

Spoiler alert:
Dies wird sicherlich nicht der letzte Thread dieser Art sein :D

Schönes Wochenende.

Gruß,

von Bauform B. (bauformb)


Lesenswert?

Alex schrieb:
> Auch wenn ich mich geschlagen gebe, für die LCD Initialisierung nun
> einen Timer zu verwenden, bin ich mir sicher, dass man aus dem
> übersetzten Maschinencode (indirekt) ablesen kann, wie viele Zyklen für
> einen Codeauschnitt verwendet werden.

Du verwendest den Timer nicht für die LCD Initialisierung sondern für 
die delay_us() Funktion. Und die kannst du überall verwenden. Der Timer 
wird ja nur einmal initialisiert und dann nur noch gelesen.

Praktischerweise initialisiert man den Prescaler passend zum Systemtakt. 
Dann muss sich die delay_us() nicht darum kümmern, die kann immer mit us 
arbeiten.

Natürlich kann man beim Cortex-M4 genau wie beim AVR die Befehlszyklen 
zählen. Es ist nur sehr viel Fleißarbeit weil man viele Sonderfälle 
berücksichtigen muss (siehe oben). Das Hauptproblem ist, in der 
Dokumentation von ARM die Tabelle zu finden ;) Es lohnt sich aber nicht, 
weil heutzutage auch der Linker die Befehle ändern kann, sogar dann, 
wenn man in einem ganz anderen Programmteil etwas geändert hat. Man 
müsste die Zyklen nach jedem Übersetzen neu ausrechnen.

von auweia (Gast)


Lesenswert?

Wer nur mit/auf den Timer wartet, kann auch Zyklen zaehlen.
Auf genaue Werte kommt es bei LCD sowieso nicht an.
Man kann natuerlich auch auf Systick warten.

Richtig waere eine Queue in die "kuenftige" Ereignisse einsortiert
werden, und erst dann abgearbeitet werden, wenn der Zeitpunkt
erreicht ist.

von Alex (Gast)


Lesenswert?

auweia schrieb:
> Wer nur mit/auf den Timer wartet, kann auch Zyklen zaehlen.
> Auf genaue Werte kommt es bei LCD sowieso nicht an.
> Man kann natuerlich auch auf Systick warten.
>
> Richtig waere eine Queue in die "kuenftige" Ereignisse einsortiert
> werden, und erst dann abgearbeitet werden, wenn der Zeitpunkt
> erreicht ist.

Magst du das näher erläutern? Ich verstehe deinen Beitrag so, dass du 
eine Art House keeping machen würdest, bei der die entsprechenden Pins 
fürs LCD dann mit hereinkommen und nach bestimmten Zeitpunkten 
schlichtweg gesetzt oder gelöscht werden.

Das ginge wahrscheinlich in die Richtung state machine, oder 
missverstehe ich dich nun völlig?

von Nop (Gast)


Lesenswert?

PittyJ schrieb:
> Oft einen im Sekundenbereich (für externe Synchronisation)
> , und einen im Millisekundenbereich (mehr für interne Zwecke).

Für diese Anwendung bräuchtest Du einen Timer mit einer Auflösung von 
1µS (bzw 10µs für andere Befehle), und das ist Blödsinn. Zumal man ein 
Display auch nicht zigmal pro Sekunde ändert, weil das gar nicht lesbar 
wäre.

Busy-wait mit CYCCNT ist da ein sehr guter Weg. Man könnte natürlich 
auch das busy-Flag des Displays abfragen, wäre aber mehr Aufwand ohne 
realen Gegenwert. Zumal man dann bei 5V-toleranten Displays auch noch 
einen Levelshifter verwenden müßte.

von PittyJ (Gast)


Lesenswert?

Nop schrieb:
> Für diese Anwendung bräuchtest Du einen Timer mit einer Auflösung von
> 1µS (bzw 10µs für andere Befehle), und das ist Blödsinn. Zumal man ein

Ich habe ein 44780 vor Jahren mal per FPGA bedient. Und ich kann mich an 
sehr lange Delays erinnern:

Wait for 15ms, nach Power on
wait for 4.1ms, nach ...
von daher passt ein Millisekunden Timer noch ganz gut.

Der OP wollte bei 16Mhz auch schon mindestens 1000 Takte warten, also 
auch schon auf 16Khz = 62 usec gehen.

Ich kann da nichts im Mikrosekundenbereich finden.

von W.S. (Gast)


Lesenswert?

Alex schrieb:
> Die LCD Routinen hier auf uC.net basieren auf die _delay_us() Funktion
> aus der AVR-Bibliothek.
>
> Ich möchte mir meine eigene delay Routine schreiben, weiß aber nicht so
> recht, wie viel Zeit in meiner for-Loop vergeht.

Und was soll das?

Schreib dir lieber deinen eigenen Displaytreiber. Und zuvor richtest du 
dir in deiner Firmware eine Systemuhr ein. Normalerweise reicht dafür 
ein Zeit-Takt von 10 ms völlig aus. Und für die wenigen Momente, wo du 
beim Initialisieren des Displays mal eine Wartezeit einhalten mußt, 
reicht es aus, eben mal 20 oder 30 ms lang zu warten. Ist ja nur am 
Anfang direkt nach dem Reset. Für später liest du einfach das 
Busy/Ready-Flag des Displays aus und fertig ist die Laube.

W.S.

von jo mei (Gast)


Lesenswert?

W.S. schrieb:
> Für später liest du einfach das
> Busy/Ready-Flag des Displays aus und fertig ist die Laube.

Nein nix ist die Laube fertig!

Denn die Displays brauchen einen Write-Zyklus der in der
Grössenordnung von mindestens ein paar Mikrosekunden ablaufen
muss, dafür arbeiten die STM Controller zu schnell um ohne
Delays auskomen zu können.

von jo mei (Gast)


Lesenswert?

PittyJ schrieb:
> Ich kann da nichts im Mikrosekundenbereich finden.

Siehe meinen Beitrag vorher.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

jo mei schrieb:
> W.S. schrieb:
>> Für später liest du einfach das
>> Busy/Ready-Flag des Displays aus und fertig ist die Laube.
>
> Nein nix ist die Laube fertig!

W.S. will uns nur mal wieder sagen, dass er von nix ne Ahnung hat ;)

von auweia (Gast)


Lesenswert?

W.S. schrieb:
> Für später liest du einfach das
> Busy/Ready-Flag des Displays aus und fertig ist die Laube.

*sitcom-lacher.wav*

von (prx) A. K. (prx)


Lesenswert?

Je komplexer die Prozessoren werden, desto schwieriger wird es, die 
exakte Laufzeit vorherzusagen. Zu viele Einflüsse spielen mit hinein.

Wenn man Delays in einem Zeitrahmen benötigt, bei dem ein Timer nicht 
sinnvoll ist, oder verschwendet wäre, hat man deshalb heute meist 
Systicks oder ähnliche Mechanismen. Ist einem auch das zuwider oder will 
partout mit Delayloops arbeiten, dann sollte man die selbstkalibrierend 
einrichten.

Das bedeutet, dass man exakt eine solche Schleife im Speicher platziert. 
Es muss eine einzige sein, weil verschiedene Alignments und andere 
Schweinereien einem sonst einen Streich spielen können. Und dann 
verwendet man beim Start einmalig einen Timer, um die Laufzeit von z.B. 
1000 Durchläufen dieser Schleife zu messen. Das ergibt dann einen 
Umrechnungsfaktor.

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Alex schrieb:
> Ich dachte allerdings bis dato, dass ein dedizierter Timer für eine LCD
> Initialisierung mit Kanonen auf Spatzen geschossen ist, auch wenn man
> bis zu 17 Timer zu verfügung hat.

Warum sollte man dafür einen dedizierten Timer benötigen. Der Timer wird 
z.B. als 1ms Interrupt konfiguriert und da kann sich jede Task dran 
bedienen. Für dein Display-Delay wartest du einfach eine bestimmte 
Anzahl von diesen Timerinterrupts ab.

von jo mei (Gast)


Lesenswert?

Wolfgang schrieb:
> Der Timer wird
> z.B. als 1ms Interrupt konfiguriert und da kann sich jede Task dran
> bedienen. Für dein Display-Delay wartest du einfach eine bestimmte
> Anzahl von diesen Timerinterrupts ab.

Naja, den Systick als LCD-Buszyklus-Timer zu benutzen ist schon
etwas schräg. Weil er zum einen vergleichweise langsam ist gegen-
über den ca 1-3 usec die man braucht, und weil er, wenn man ihn
deutlich schneller auslegt, allmählich dem Prozessor zuviel
(und unnötige) Interrupt-Last abverlangt.

Der DWT Cycle Count ist sicherlich die beste Lösung für usec
Timings.

Klaus S. schrieb:
> Ich benutze folgende Routinen:

von Bauform B. (bauformb)


Lesenswert?

jo mei schrieb:
> Der DWT Cycle Count ist sicherlich die beste Lösung für usec
> Timings.

Leider auch nicht immer. Wer die MPU einsetzt möchte auf SCB, DWT usw. 
nur privilegierte Zugriffe erlauben und ein syscall für ein us-Delay ist 
ja auch nicht der Hit.

von Wolfgang (Gast)


Lesenswert?

jo mei schrieb:
> Weil er zum einen vergleichweise langsam ist gegen-
> über den ca 1-3 usec die man braucht ...

Wer redet dabei auch von 1-3 µs. Das wäre eher grober Unfug.

Guck mal ins Datenblatt vom HD44780, was da noch so auftaucht:
Bei der Initialisierung werden bspw. Mindestwartezeiten von 15ms, 4.1ms 
oder 40ms gefordert (Fig. 25/26 8-Bit bzw. 4-Bit Interface). Da hätte 
ich jetzt keine Hemmungen, einen 1ms Timerinterrupt zu bemühen.

von jo mei (Gast)


Lesenswert?

Wolfgang schrieb:
> Wer redet dabei auch von 1-3 µs. Das wäre eher grober Unfug.

Du hast es offensichtlich noch nicht kapiert.

Ich rede hier von einem normalen Bus-Zyklus. Und das ist
absolut kein grober Unfug sondern der Normalfall der beim
Schreiben oder Lesen vorkommt.

Wenn dir das nicht klar ist dann musst du wohl durch Datenblastt
lesen noch etwas schlauer werden.

von Nop (Gast)


Lesenswert?

PittyJ schrieb:

> Ich habe ein 44780 vor Jahren mal per FPGA bedient. Und ich kann mich an
> sehr lange Delays erinnern:

Aber nicht z.B. für den Enable-Puls. Der muß mindestens 0.5µs sein, also 
nimmt man 1µs, um auf der sicheren Seite zu sein. Oder 40µs, um ein 
Datenbyte zu verarbeiten, also gibt man 80µs, wenn man das busy-Flag 
nicht abfragt. Kein Problem mit Busy-Wait.

Daß es auch Kommandos gibt, die lange brauchen (speziell CLEAR), steht 
dem nicht entgegen. Die werden aber fast nur für die Initialisierung 
gebraucht, wo es meistens relativ egal ist.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.