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 }
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
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.
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
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
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ß
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
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
> 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
> ??? 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
> blöde Frage ... was ist TRM ...
Technical Reference Manual... Das hast du doch, oder? Das Datenblatt ist
nur die halbe Miete...
Ralf
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.