Forum: Mikrocontroller und Digitale Elektronik wait funktion, 8051 mit keil


von Markus Zieserl (Gast)


Lesenswert?

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 ;-)

von Bananen Joe (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

Man kann es im Simulator laufen lassen und sich die verbrauchten 
CPU-Zyklen anzeigen lassen. Und dann anhand der Taktfrequenz in Zeit 
umrechnen.


Peter

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von Bernhard S. (b_spitzer)


Lesenswert?

...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

von Markus Zieserl (Gast)


Lesenswert?

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
  }

von 89AT (Gast)


Lesenswert?

Bernhard Spitzer schrieb:
> Bei meinem AT89C5131 (12 Takte/MZ)

Meiner braucht nur 6 Takte / MZ.

Steht so im Datenblatt ;-)))

von Wilhelm F. (Gast)


Lesenswert?

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.

von Bernhard S. (b_spitzer)


Lesenswert?

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

von Wilhelm F. (Gast)


Lesenswert?

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.

von Bernhard S. (b_spitzer)


Lesenswert?

> 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...

von Pieter (Gast)


Lesenswert?

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

von Wilhelm F. (Gast)


Lesenswert?

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.

von Bernhard S. (b_spitzer)


Lesenswert?

> 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
Noch kein Account? Hier anmelden.