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
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.
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
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...
...
... 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)
@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
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.
... 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
#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.
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
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
> ... 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).
...
...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
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.
...
... 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
> 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...)
...
... 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)"
> ... 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.
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)
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.