Forum: Mikrocontroller und Digitale Elektronik 8051 - einfache Delay Funktion mit Keil µVision


von Johannes S. (schneijo)


Angehängte Dateien:

Lesenswert?

Hallo,

ich versuche mich gerade an einer C Funktion in Keil µVision, die ein 
Delay setzen soll. Alles kein Problem bis auf das Ergebnis ...

Als Test schalte ich eine ganzes Ausgangsbyte high, warte die 
Delay-Funktion ab und schalte das Ausgangsbyte wieder aus. Dann die 
gleiche Delay-Funktion nochmals. Das ganze zwei mal ... man erwartet 
zwei Pulse, die von einer äquidistanten "Auszeit" unterbrochen sind, 
also zwei On-off-cycle.

Wie der Scope-Plot im Anhang zeigt, ist das in Hardware allerdings nicht 
der Fall. Die "Auszeit" ist etwas länger als die Pulse, bei gleichem 
Delay ...

Genauer betrachtet kommt die Pulsbreite, bzw. Offzeit-breite mit der 
Anzahl der Assembler Befehle im In-line-assembly der Delay Funktion auch 
nicht hin. Ich würde eine ca. 4 mal kürzere Delay Zeit erwarten, wie das 
was ich auf dem Scope sehe (Clock zu Arbeits-Cycle verhältnis mit 
eingerechnet, 4 Clock-Zyklen pro einfacher Operation (NOP)).

- Was kann hier das Problem sein?
- An welchen Compiler-Optionen kann man dazu noch was optimieren?
- Wie kann ich mir den Assembler Code bzw. das Compile Ergebnis in 
µVision anzeigen lassen?

VG Johannes


void MainLoop()
  {
   IOB = 0xFF;
   Delay_10();
   IOB = 0x00;
   Delay_10();
   IOB = 0xFF;
   Delay_10();
   IOB = 0x00;
   Delay_10();
  }

void Delay_10()                     // Delay
    {
   #pragma asm       // Assembler Code
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
     NOP
    NOP
   #pragma endasm
     }

von Ralf (Gast)


Lesenswert?

Hi Johannes,

für das Anzeigen der generierten Assembler-Befehle musst du in den 
Eigenschaften der entsprechenden Source-Datei "Generate assembler SRC 
file" und "Assemble SRC file" aktivieren.
Alternativ (wenn's ganz schnell gehen soll), einfach den Debugger 
starten, und das Disassembly-Fenster aktivieren.
Wenn du das hast, poste mal den Inhalt hier. Welche Taktfrequenz und 
welchen Chip verwendest du?

Ralf

von B e r n d W. (smiley46)


Lesenswert?

In welchem Speicherbereich liegt IOB, im XDATA? Falls ja, kommt das als 
Ursache für die Verzögerung in Frage.

Welche CPU verwendest Du genau? Macht die wirklich einen Befehl in 4 
Clock-Zyklen?

IOB = 0x00; Bei Null kann der Clear-Befehl verwendet werden.
IOB = 0xFF; Hier muss erst 0xFF geladen werden, was länger dauert.

Versuchsmal so:
IOB = 0x00;
Delay_10();
IOB++;
Delay_10();
IOB--;
...

Beim Compiler bzw. Assembler kann man List-Files einschalten. Da gehören 
dann auch das Assembler Listing mit dazu.

Mfg.

von Johannes S. (schneijo)


Lesenswert?

Hallo,

kleines Update ...

Die Compiler Optionen zum einstellen des Optimierungsmechanismus habe 
ich gefunden ...
Wenn man in Keil µVision die Einstellung "Code Optimization -> 6:Loop 
rotation" nimmt sind zumindest das Puls-Pausenverhältnis in obigem 
Beispiel gleich. Das heißt mehrmaliger Aufruf der gleichen Funktion 
führt auch zu gleichem Delay-Ergebnis.

Ok, eine Frage bleibt aber immer noch ... Ich habe die Funktion 
"Delay_10()" jetzt so getrimmt, dass sie genau 10µs in Hardware läuft 
(jetzt mit 19 NOP Befehlen). Nur das passt irgendwie nicht mit meinem 
Takt von 24 MHz zusammen.
In 10µs sollte der Controller ca. 60 one cycle Operationen durchführen 
können und nicht nur 19 ...
Der im Cypress CY7C68013A verwendete Kern ist ein 8051-Befehlssatz 
kompatibler Kern, welcher für eine NOP Operation 4 Takt-Zyklen benötigt.

Was kann zu dieser großen Differenz von operation cycles führen?

VG Johannes

von Johannes S. (schneijo)


Lesenswert?

Chip     Cypress CY7C68013A

Taktrate      24MHz

von Ralf (Gast)


Lesenswert?

Sag mal, der Core-Speed etc. ist alles richtig konfiguriert? Nicht dass 
wir da im Nebel rumstochern... Das würde die Differenz evtl. erklären, 
wenn der Core falsch konfiguriert ist und langsamer läuft... Oder, was 
auch sein kann, dass die Ports nicht so schnell hinterher kommen. Hast 
du das geprüft?

Was hat das Assembler Source-File ausgespuckt?

Ralf

von B e r n d W. (smiley46)


Lesenswert?

Funktionsaufrufe sind je nach Speichermodell nicht zu vernachlässigen, 
probiers mal mit einer leeren Delay Funktion. Dann müsste pro NOP der 
Zeitbedarf nach Deiner Berechnung zunehmen.

Wird da ein Teil der Peripherie als XDATA angesprochen?

Gruß

von Johannes S. (schneijo)


Angehängte Dateien:

Lesenswert?

Hallo Ralf,

erst mal vielen Dank für die schnelle Reaktion ...
Nach den Einstellungen des Core-Speed, Vorteiler oder so was Ähnlichem 
habe ich auch schon gesucht. Leider ohne Erfolg.

Im Anhang ist das zugehörige SRC-file mit dem Assembler code ...

vielen Dank schon mal ... die Diskussion hat mir bis hier hin schon sehr 
weiter geholfen.

Leider steht mir der Debugger nicht zur Verfügung. Ich kann also damit 
nicht arbeiten.

VG Johannes

von Johannes S. (schneijo)


Lesenswert?

Hallo Bernd,

IOB ist eine Synoym für das SFR (Ausgangsbyte) des IO-Ports B.
Hat also soweit ich weiß nichts mit XDATA-Zugriffen zu tun.
Mit IOB spreche ich also direkt die Pins an ...

Wenn ich weitere NOPs in die Funktion einfüge wird natürlich die Zeit 
auch länger. Das habe ich mit 5 verschiedenen Anzahlen von NOPs in der 
DELAY-Funktion getestet.

VG Johannes

von Ralf (Gast)


Lesenswert?

> Nach den Einstellungen des Core-Speed, Vorteiler oder so was Ähnlichem
> habe ich auch schon gesucht. Leider ohne Erfolg.
??? Kapitel 15.5.1 im TRM, so als Beispiel? :)
Das steht was von 12MHz als Einstellung nach Reset...

Ralf

von Johannes S. (schneijo)


Lesenswert?

> ??? Kapitel 15.5.1 im TRM, so als Beispiel? :)
> Das steht was von 12MHz als Einstellung nach Reset...

blöde Frage ... was ist TRM ...

Ich verwende einen externen Quarz mit 24 MHz.

mfg Johannes

von Ralf (Gast)


Lesenswert?

> blöde Frage ... was ist TRM ...
Technical Reference Manual... Das hast du doch, oder? Das Datenblatt ist 
nur die halbe Miete...

Ralf

von Matthias (Gast)


Lesenswert?

NOP kann man bei Keil auch ohne den Umweg über die SRC so verwenden:
1
#include <intrins.h>
2
3
_nop_();

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.