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