Hallo Leute, Ich bin ein ziemlicher Anfänger in der µC Programmierung und würde eure Hilfe benötigen. Ich hab hier ein Projekt wo ich einen vorhandenen Code für die Ansteuerung eines DOG-M LCD auf meinen 8051 NXP LPC 954 µC adaptieren möchte. Habe nun im Code diese Wait Funktion: /////////////////////////////////////////////////////// // Wait number of milliseconds without using a timer // Adjust to actual CPU-speed /////////////////////////////////////////////////////// void waitms(unsigned int msec) { data unsigned int i; for (msec; msec!=0; msec--) { for (i=0; i<1320; i++); //1320 for ADUC841, 60 for ADUC831 } } /////////////////////////////////////////////////////// Ich würd jetzt gerne wissen wie er mit der for Schleife auf 1ms kommt. Oszillator Frequenz ist 11 Mhz. In meinem Projekt verwende ich eben wie oben erwähnt einen 8051 NXP LPC 954 welcher mit einer Frequenz von 12 Mhz betrieben wird. Bitte nicht schimpfen, bin wie gesagt noch Anfänger ;-)
Austesten... Einfach nen Pin mit der Wait-Funktion toggelen und mit dem Oszi messen. So was ist eine der ersten Uebungen die man normalerweise an einer Hochschule mit MCUs macht.
Man kann es im Simulator laufen lassen und sich die verbrauchten CPU-Zyklen anzeigen lassen. Und dann anhand der Taktfrequenz in Zeit umrechnen. Peter
Markus Zieserl schrieb: > Ich würd jetzt gerne wissen wie er mit der for Schleife auf 1ms kommt. Das steht im Code: // Adjust to actual CPU-speed Und wenn man grad keinen Simulator und kein Oszi hat: die Funktion 1000mal aufrufen und so einen Wert eintragen, bis die LED etwa im Sekundentakt blinkt. Dann 1 Minute mitzählen und mit einem Dreisatz den nötigen neuen Wert ausrechnen...
...oder im Debugger den erzeugten Assembler-Code anschauen und die benötigten Maschinenzyklen aufaddieren. Ist aber aufwändiger und fehleranfälliger als der Simulator. Oszi ist wiederum etwas Fehleranfällig und ungenau, wenn man bei 1ms Länge die Zeit auf weinige us genau messen will. Bei meinem AT89C5131 (12 Takte/MZ) kommt der C-Code von Raisonance auf 8 MZ pro Durchlauf bei einer Variablen vom Typ unsigned int (bei meinen Controllern mit 12KHz und 12Takten/Mz, kein X2-Mode gibt das genau 1us/MZ und damit 8us/Durchlauf). Bei unsigned char können auch mal nur 2 MZ rauskommen (wird zu einer djnz-Schleife), allerdings optimiert der Compiler leere Schleifen gerne mal weg, daher haben meine uChar-Schleifen 2 Nops (_nop_(); aus intrins.h) drin. Damit erreicht man zuverlässige 4MZ/Schleifendruchlauf bei uChar. tschuessle Bernhard
Da ich grad kein Oszi zu Verfügung hatte, habe ich den Tipp von Lothar Miller versucht und hat gut geklappt denke ich. Habe nun mit dieser for Schleife die LEDs am Port 5 aus und einschalten lassen bis es ca. 1 Sekunde war.
1 | data unsigned int i; |
2 | |
3 | for (i=0; i<200; i++) |
4 | {
|
5 | P5=0xF0; |
6 | waitms(1000); |
7 | P5=0x0F; |
8 | waitms(1000); |
9 | }
|
Bernhard Spitzer schrieb: > Bei meinem AT89C5131 (12 Takte/MZ) Meiner braucht nur 6 Takte / MZ. Steht so im Datenblatt ;-)))
Eine Wait-Funktion, wo wirklich das Hauptprogramm wartet, macht man normalerweise nicht. OK, für ne Bastelei mal. Am besten benutzt man da einen Timer-Interrupt, und eine globale Zählvariable, oder Funktion, damit das Hauptprogramm störungsfrei und ohne Aufenthalte durch läuft. Als Anfänger muß man sich mal an die Interrupts heran tasten. Das ist ja auch nichts schlimmes.
89AT schrieb: > Bernhard Spitzer schrieb: >> Bei meinem AT89C5131 (12 Takte/MZ) > > Meiner braucht nur 6 Takte / MZ. > > Steht so im Datenblatt ;-))) Meiner auch, wenn ich den X2-Modus einschalte. Mit meinen Schülern will ich aber möglichst einfach mit wenigen Einstellungen arbeiten. Da ist der X2-Modus aus mehreren Gründen schlecht: - der Maschinenzyklus dauert dann nicht mehr 1µs, Kopfrechnen von Zeiten wird schwieriger - der Controller ist für unsere Aufgaben eh meist viel zu schnell, die Warteschleifen werden im X2-Modus nur noch länger - der Timer läuft immerhin über 50ms (65,535...) - der Normalmodus ist der Reset-Wert, kann also nicht vergessen werden - ich muss nicht auch noch das PCON-Register behandlen (aus didaktischer Sicht hat der 8051 halt trotzdem noch einige Vorteile gegenüber anderen Controllern...) tschuessle Bernhard
Bernhard Spitzer schrieb: > (aus didaktischer Sicht hat der 8051 halt trotzdem noch einige Vorteile > gegenüber anderen Controllern...) Der 1µs Taktzyklus beim Standard-8051 mit 12MHz Quarz ist einfach unschlagbar, für Taktzyklenrechnereien und didaktische Zwecke. Hatte mal eine Klausur mit 8085, wo es nicht so ist. Man sollte sich mit geeigneten Befehlen selbst die Wartezeiten richtig zusammen stückeln. Jeder Befehl hat andere Zykluszeiten. Später verwendete ich am 8085 den Timer 8253, der mir da exakte Zeiten Timerinterrupts machte.
> Der 1µs Taktzyklus beim Standard-8051 mit 12MHz Quarz ist einfach > unschlagbar, für Taktzyklenrechnereien und didaktische Zwecke. Und immer die Quarzfrequenz angeben... Es gibt durchaus Quellen (im Internet, aber auch in Büchern, die schreiben wirklich, dass der Maschinenzyklus beim 8051 1µs benötigt. Woher wissen die denn, dass ich nicht mit 11,0592MHz arbeite?? > Jeder Befehl hat andere Zykluszeiten. Beim 8051 ist das immerhin etwas logischer und übersichtlicher. Alle Sprungbefehle und Verzweigungen brauchen 2 MZ, alle Befehle bei denen ein Operanden geladen werden muss brauchen 2 MZ, Mul und Div brauchen 4 MZ, die übrigen brauchen 1MZ. Fertig. tschuessle Bernhard Jetzt aber wieder zurück zum Thema...
moin moin,
>>Alle Sprungbefehle und Verzweigungen brauchen 2 MZ,
Vorsicht, ohne Typenangabe stimmt das nicht! Beim 89LP4052 oder beim
C8051F365 ist das so nicht.
Mit Gruß
Pieter
Bernhard Spitzer schrieb: > Woher wissen die denn, dass ich > nicht mit 11,0592MHz arbeite?? Das verwenden beim 8051 ein paar unverbesserliche Spezeln. Man bekommt die Baudraten auch mit 12MHz hin, aber mit geringer Toleranz unter 0,2%. In Literatur und Lernbüchern sah ich diese krumme Frequenz auch nie. OK, ich hatte kürzlich einen Sonderfall, wo ich 115.200BAUD aus dem 80C517A raus holen mußte. Das geht dann eben nur mit dem Quarz 7,3728MHz.
> 115.200BAUD aus dem 80C517A raus holen mußte. Dafür habe ich das erste mal den X2-Mode bei meinem 5131 gebraucht. Ich habe so einen GPS-Empfänger (Jentro SC-GPS-1), der quasi als Verdongelung (wurde als Falk Activepilot bei Siemens-Handys verschenkt und ist auf Ebay oft günstig zu schießen) am Anfang auf 115200 läuft. Dem habe ich per Bitbanging die paar Bytes zur Konfiguration auf 4800Baud reingeprügelt. 8,5µs/Bit und das in C.... Geht aber. > Das geht dann eben nur mit dem Quarz 7,3728MHz. Das ist 2/3 von 11.0592. Also auch ein Baudratenquarz. Interessanterweise geht damit die MIDI-Baudrate von 31250 überhaupt nicht. Bei 12MHz gehen 31250 aber mit 0% Fehler :-) tschuessle Bernhard
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.