Forum: Mikrocontroller und Digitale Elektronik Wie kann man eine Warteschlage einbauen? waitms() ???


von popi (Gast)


Lesenswert?

Hallo zusammen,

ich will drei Ports nacheinander einschalten, und würde gerne eine
Pause dazwischen machen, also:

PORTB1 an
*pause n_ms
PORTB2 an
*pause n_ms
PORTB3 an


Kann mir bitte jemand sagen, welchen Befehl es für Pausen gibt ?
Und vor allem, wie man die ms korrekt errechnet, also wie stehen die im
Zusammenhang zum Quarz (benutze 1MHz intern).

Danke und Grüße

popi

von Rainer Bonnes (Gast)


Lesenswert?

Ich welcher Programmiersprache bzw. welches Programm benutzt du ?

von Laplace (Gast)


Lesenswert?

Nachdem du warscheinlich keine Erfahrung mit Timern/Interrupts hast
musst du eine Zählschleife benutzen. Der folgende Code stammt aus dem
AVR-Tutorium (LCD-Teil):

;Längere Pause für manche Befehle
delay5ms:                               ;5ms Pause
           ldi  temp1, $21
WGLOOP0:   ldi  temp2, $C9
WGLOOP1:   dec  temp2
           brne WGLOOP1
           dec  temp1
           brne WGLOOP0
           ret                          ;wieder zurück

Warum machst du nicht einfach mal das gesamte Tutorium durch? Da lernst
du solche Sachen.

von popi (Gast)


Lesenswert?

Halo Rainer,

ich "programmiere" (ich versuche es) in C mit AVR-Studio.

Das Programm könnte so aussehen:
#include <avr/io.h>
int main(void)
{
DDRB = 0xff;

PORT_PB1 = 1;
 *warten
PORT_PB1 = 0;
PORT_PB2 = 1;
 *warten
PORT_PB2 = 0;
PORT_PB3 = 1;

while(1);
}

Kann man eigenlich eleganter schreiben, also sowas wie einen rotate
Befehl benutzen, indem ich nur Port B1 high setze und dann 2x nach
links schiebe ?

Danke und Grüße

popi

von Hannes L. (hannes)


Lesenswert?

Warteschlangen gab es vor den Gemüseläden der DDR, wenn man das
Gerücht verstrute, dass es Bananen gibt. Heute gibt es Warteschlangen
meist bei der Arbeitsagentur oder der Arbeitsgemeinschaft
Grundsicherung. ;-) (<-- Das ist ein Smilie!!!)

Warteschleifen sind gut geeignet, kleine Verzögerungen (wenige
Mikrosekunden) in Programmen zu realisieren. Werden die Wartezeiten
größer, dann nimmt man einen Timer. Dabei kann ein Timer durchaus
mehrere Jobs erledigen, ohne dass man den Timerstand selbst
manipulieren muss. Eigentlich kommt kein sinnvolles AVR-Programm ohne
Timer-Interrupt aus.

Beispiele dazu gibt es hier im Forum mehr als genug, einfach mal etwas
zurückblättern und lesen...

...

von popi (Gast)


Lesenswert?

... aber wie auch immer.
Hast ja auch wirklich Recht, habe mich peinlich verschrieben ;o)

Okay, Warteschleife ist natürlich eine Lösung, die ich für mein 2
minütiges Beispiel sicher in stundenlanger Arbeit recherchieren kann
(wegen solchen Aussagen und Engagement gibt es übrigens Warteschlangen
in der Arbeitsagentur)

Wie auch immer, ich dachte es gäbe vielleicht ein Befehl, so was wie
wait(ms) oder ähnliches.
Aber ich werde mal schauen, ob ich etwas im Internet über eine
Wartefunktion finden kann, wenn nicht, komme ich wieder ;o)

Grüße

popi

@LAPLACE: Vielen Dank, aber ich brauche es in C (hatte ich vergessen,
vorher zu erwähnen)

von Fritz G. (fritzg)


Lesenswert?

Wenn du die avr-libc verwendest gibt es dort ein _delay_ms ().
Erklärung siehe Doku.

von popi (Gast)


Lesenswert?

@HanneS

... ganze 3 Ergebnisse für Warteschleifen...
Davon nur eine über C und auch noch unbeantwortet.

Man, das muss ich erst mal alles durcharbeiten...

Gruß

popi

von Rainer Bonnes (Gast)


Lesenswert?

Versuch es doch einfach mal mit BASCOM-AVR das ist die
Programmiersparche Basic und ne Warteschleife kriegst du da mit
einem Befehl (Waitus oder Waitms) hin. Ausserdem gibt es auch eine
Hilfe wo man lesen kann was die befehle machen. Ideal für Anfänger.

von popi (Gast)


Lesenswert?

... ich hoffe, dein Fahrlehrer hatte Dir auch in der ersten Stunde
empfohlen, erst mal mit einem Tretauto anzufangen, anstatt das Fahren
zu erlernen.

Gruß

popi

von Hubert.G (Gast)


Lesenswert?

#include <avr/delay.h>

und im Programm: delay_ms(5000);
für 5 sec warten.
Mal in der GCC-lib nachlesen.
Ich verwende das allerdings nur um bei Programmstart z.B. die
Versionsnummer einzublenden. Im laufenden Programm ist ein Timer sicher
besser.

von popi (Gast)


Lesenswert?

Hallo Hubert,

habe es gerade ausprobiert, aber es ging nicht.
Dann habe ich ein _ (siehe Fritz Ganter weiter ober) davor gesetzt und
jetzt meckert der Compiler nicht mehr.

Darf ich fragen, warum Du das nicht so gerne benutzt ?
Hat _delay_ms() Nachteile ???

Und was bedeutet denn immer dieser Unterstrich _ oder manchmal gar zwei
davon __ ????

danke und Gruß

popi

von Hubert.G (Gast)


Lesenswert?

Den _ habe ich in der Eile übersehen, sorry. Dieser Unterstrich hat sich
als Trennzeichen eingebürgert da der Bindestrich in einigen Programmen
nicht erlaubt ist.
Ich benutze das _delay_ms() normalerweise nicht da der µC dann nichts
tut (ausser Schleifen zählen) und genau das sollte er aber. Wie fragst
du in der Zeit eine Taste ab, machst eine ADC-Messung, usw. Zum nur ein
Licht in einer Lichterkette weiterschalten brauche ich keinen µC.
Also immer ganau überlegen ob nicht doch ein Timer sinnvoller ist, er
ist es fast immer.

Hubert

von popi (Gast)


Lesenswert?

klingt logisch, was Du sagst!

Ich werde versuchen, so eine Timerschleife mal zu erstellen.

Danke und Grüße

popi

von Hannes L. (hannes)


Lesenswert?

> ... ich hoffe, dein Fahrlehrer hatte Dir auch in der ersten Stunde
> empfohlen, erst mal mit einem Tretauto anzufangen, anstatt das
> Fahren zu erlernen.

Nunja, BASCOM ist wirklich nicht die erste Wahl...

Trotzdem solltest du dich etwas mit dem Assembler-Befehlssatz der AVRs
befassen, Dann hast du auch eine Chance, zu verstehen, was dein
C-Compiler aus deinem Code macht. ASM ist auch sehr hilfreich beim
Verstehen der Architektur des AVRs. Wenn du nämlich die Hardware (z.B.
die Timer mit ihren Spezialfunktionen) nicht verstehst, dann kannst du
sie auch nicht effizient nutzen und bist auf solchen Unfug wie
Warteschleifen angewiesen.

Du meinst, du hat hier kaum etwas zum Thema gefunden. Das hat Gründe.
Einerseits werden die Begriffe so oft falsch geschrieben, dass sie
unauffindbar sind, andererseits driften die Themen sehr oft vom Betreff
ab. Ich sprach (schrieb) übrigens auch nicht vom "suchen" (Google),
sondern vom zurückblättern und lesen, also vom Herumstöbern bzw.
manuellem Suchen. Es gibt hier nämlich genügend Programmbeispiele, in
denen frei durchlaufende Timer zum Realisieren von Wartezeiten benutzt
werden.

Da ich aber nicht in C programmiere, sondern in ASM, kann ich dir keine
Codebeispiele schreiben. Schau dich aber einfach mal in der Codesammlung
um, da gibt es viele gute Beispiele (leider auch einige weniger gute).

...

von Hannes L. (hannes)


Lesenswert?

Was ist eine "Timerschleife"???

...

von popi (Gast)


Lesenswert?

...dann sorry!

Ich meinte damit, den Timer für eine Warteschleife zu benuzten, wie
auch immer das gehen soll.
Ich werde zu dem Thema mal googeln oder forum stöbern.

Mit ASM hast Du voll recht.
Unser Technikerprojekt soll aber so komplex werden (zumindenst für
uns), das uns von "Experten" (ich kann es nicht beurteilen, C ans
Herz gelegt wurde.

Aber ich denke mir, das es wichtig ist, die Architektur zu verstehen.
Wenn das doofe Projekt fertig ist (haben bin April 2006 Zeit) werde ich
mich intensiver mit ASM befassen.

Grüße

popi

von Hannes L. (hannes)


Lesenswert?

Mich stört der Begriff "Warteschleife"...

Stell dir vor, du bist Briefträger. Du hast deine feste Runde. Ein
Kunde ist nicht da und du brauchst aber eine Unterschrift. Wartest du
nun, bis der nach Hause kommt, oder trägst du erstmal die restliche
Post aus und schaust auf dem Rückweg nochmal vorbei?

Anders formuliert:
Eine "Warteschleife" bedeutet, dass man (an Ort und Stelle) wartet,
bis die Bedingung erfüllt ist, den nächsten Schritt zu tun. In der Zeit
kann der Controller aber nix Anderes tun.

Stattdessen kann man das Programm so aufbauen, dass es nicht
"wartet", sondern den Programmteil überspringt, solange die Bedingung
nicht erfüllt ist. Man springt also sofort zur Mainloop zurück und
testet die Bedingungen für noch andere zu erledigende Arbeiten.

Richte dir mal einen Timer ein, am einfachsten Timer0 mit
Überlauf-Interrupt. Wie das geht, steht im (Complete-) Datenblatt
deines AVRs (oft sogar mit C-Beispielcode).
In der ISR dieses Timers zählst du eine Variable hoch.
Je nach Zustand dieser Variable verzweigt die Mainloop in die
entsprechenden Routinen.

...

von Frank (Gast)


Lesenswert?

also braucht ein Postbote einen Interrupt um an eine Unterschrift zu
kommen?!?

von popi (Gast)


Lesenswert?

... und macht mich sehr neugierrig.

Denn das Beispiel mit dem Briefträger ist genial ;)

Also, morgen früh werde ich mir gleich das Datenblatt schnappen und
versuchen, deinen Vorschlag zu reallisieren.

(ich muss jetzt was essen, sonst sterbe ich)

Wünsche Dir einen schönen Abend, danke für die guten atschläge und bis
demnächst...

Liebe Grüße

popi

von Hannes L. (hannes)


Lesenswert?

http://www.mikrocontroller.net/forum/read-1-280488.html#283378
http://www.mikrocontroller.net/forum/read-1-113815.html#113815
http://www.mikrocontroller.net/forum/read-1-271826.html#272977
http://www.mikrocontroller.net/forum/read-1-271826.html#274403
http://www.mikrocontroller.net/forum/read-1-262112.html#262226

Diese Links zeigen dir die Verwendung der Timer in ASM. In C umsetzen
musst du es selbst. Das Datenblatt des jeweiligen AVRs wird dir dabei
helfen.

Übrigens kann ein AVR kein C. Er kann nur Maschinencode. Und zu jedem
Maschinencode gibt es exakt einen ASM-Befehl. Daher könnte man (mit
etwas Humor) behaupten, ein AVR könne ASM.
Damit man nun in C programmieren kann, übersetzt der C-Compiler das
Programm in Maschinencode (also in ASM). Solange du diese Übersetzung
(also ASM) nicht verstehst, wirst du nicht hardwarenah programmieren
können. Du wirst also nur an der Oberfläche herumeiern, nix verstehen
und dir mit schlecht formulierten Fragen (weil unverstandene Materie)
die Leute vergraulen. Daher brauchst du dich über die Reaktion in den
anderen Threads nicht zu wundern.

...

von Hannes L. (hannes)


Lesenswert?

> also braucht ein Postbote einen Interrupt um an eine Unterschrift zu
> kommen?!?

Im Prinzip ja...

... Wenn wir die Aufgabe etwas umstellen und meinen, dass der Postbote
vor dem Haus wartet, bis der (sich zu Hause befindende) Kunde zufällig
mal zur Tür raus kommt.

Mit einem Interrupt (Betätigen der Türklingel) kann sich der Postbote
tatsächlich helfen...

;-)

(Zugegeben, so besonders treffend war das Beispiel nicht gerade...)

...

von popi (Gast)


Lesenswert?

... du hast recht.

Ich werde mich parallel mit ASM beschäftigen, oder beschäftigen müssen,
um die Links die du mir empfohlen hast, zu versthen und in C
umzusetzen.

ich weiss das der Compiler den Code übersetzt.
Möglicherweise sollte ich mir den compilierten Code anschauen und
daraus lernen?!

Danke für die Links!!!!

Gruß

popi

"Ich gelobe Besserung in der Fragestellung ;o)"

von Karl H. (kbuchegg)


Lesenswert?

> ... ich hoffe, dein Fahrlehrer hatte Dir auch in der ersten Stunde
> empfohlen, erst mal mit einem Tretauto anzufangen, anstatt das
> Fahren zu erlernen.

Das hat er nicht.
Aber bevor ich das erste mal als Fahrer in ein Auto gestiegen
bin, wurde mir im Lehrsaal mal erklaert, was es mit den einzelnen
Pedalen auf sich hat und was sie im Auto bewirken.

Was Du da zeitweise machst ist equivalent mit: Lass doch mal
den 6-jaehrigen ans Steuer. Er wird schon rauskriegen wozu das
seltsame Rad da vor ihm gut ist.

von Marcus (Gast)


Lesenswert?

addon:

der _ (unterstrich) zeigt nur an, das der befehl ein interrupt, bzw.
ein befehl des präprozessors ist (z.B. _delay, oder __enable_interrupts
oder ähnliches)

von Rahul (Gast)


Lesenswert?

eher wohl eine Makro-Markierung...
Makros werden vom Präprozessor durch den entsprechend vereinbarten Text
ersetzt.

von Karl H. (kbuchegg)


Lesenswert?

Aeh. Nein.

Der fuehrende Unterstrich wird benutzt um anzuzeigen, dass
es sich bei dieser Funktion um eine Nicht-Standard Funktion
des Compilers handelt.

Im C-Standard ist genau definiert welche Funktionen ein
System unterstuetzen muss. Jede dieser Funktionen hat einen
definierten Namen. Nun kommt es natuerlich auch vor, dass
Systeme zusaetzliche Funktionen anbieten. Nur welchen Namen
soll man diesen Funktionen geben ohne in Gefahr zu laufen,
dass ein Anwendungs-Programmierer zufaellig eine Funktion
gleichen Namens benutzt? Genau aus diesem Grund wurde definiert,
dass alle Funktionen, deren Namen mit einem '_' beginnen als fuer
den Compiler reserviert gelten. Damit haben die Implementierer
der mitgelieferten Bibliotheken einen Art 'Namensraum' in dem
sie sich austoben koennen ohne dass es je zu Namenskonflikten
mit Anwendungsprogrammierern kommt. Und manchmal fallen dann halt
auch Funktionen ab, die fuer den Anwendungsprogrammierer interessant
sind.

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.