www.mikrocontroller.net

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


Autor: Johannes Schneider (schneijo)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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
     }

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: B e r n d W. (smiley46)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes Schneider (schneijo)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes Schneider (schneijo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Chip     Cypress CY7C68013A

Taktrate      24MHz

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: B e r n d W. (smiley46)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Johannes Schneider (schneijo)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes Schneider (schneijo)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes Schneider (schneijo)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ralf (Gast)
Datum:

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

Ralf

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
NOP kann man bei Keil auch ohne den Umweg über die SRC so verwenden:
#include <intrins.h>

_nop_();


Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.