Hallo, ich habe da mal ein klitzekleine Frage an die etwas geübteren Programmierer: Wie kann ich, möglichst elegant, eine Funktion schreiben, die eine gewisse Zeit einen PIN rhythmisch (schönes Wort, gell?) togglen soll? Beispielsweise also eine Funktion die eine Minute lang das gute alte Telefonklingel imitiert, mit ca. 2sec klineln, und zwei sec Pause. Geht das überhaupt ohne "globale" information, wie flags und dergleichen? danke jakkob
In welcher Sprache denn? In C ginge Toggeln z.B. so:
1 | PORTB ^= (1<<PB0); |
um PORT B Bit 0 umzuschalten (vorher natürlich als Ausgang definieren. Die 'rhytmik' kannst du mit dem Timer-Interrupt auf verschiedenen Wegen machen, Output-Compare oder Overflow - Interrupt.
Du solltest einen Timer des uP nutzen, den z.B. als 1-ms oder 10-ms-Interrupt laufen lassen und über Zähler deine Ereignisse davon ableiten. Für "klingeln" brauchst du eine bestimmte Frequenz, evtl. einen zweiten Timer, dessen Ausgangspin jeweils ein- und ausgeschaltet wird. Es gibt bestimmt ganz viele Lösungsmöglichkeiten, einfachere und umständlichere. Das ist nur ein Vorschlag.
Hi, ich würde den Timer nehmen. Das ist wohl die eleganteste Möglichkeit, da du in den Wartezeiten weiteren Code abarbeiten lassen kannst. Vom Grundschema: Timer auf genau eine Sekunde mit dem Compare Match timen, siehe dazu mal http://www.mikrocontroller.net/articles/AVR_-_Die_genaue_Sekunde_/_RTC Dann den Interrupt für Compare Match A anschalten und den Interruptvektor abfangen und hier eine Funktion laufen lassen. Du kannst ja durch einen Zähler (globale Variable oder so) auch einzelne Sekundenzyklen überspringen und so 2Sek an, 1 Sek aus erzeugen. Wie das toggeln geht wurde dir ja schon beantwortet. Gruß Stomper
hellohello, erstmal danke für die bltzschnellen Antworten. Leider aber helfen die mir nicht weiter. Ich programmiere in C und ich kann mit Timern umgehen und ich weiß wie man das XOR benutzt (meine Schuld, hätte ich dazu sagen müssen). Mein Problem ist, ganz genau , dass das hier:
1 | //Zeit (in ms) wird in ISR hochgezählt
|
2 | |
3 | void Klingelknopf(unsigned char K){ |
4 | |
5 | uint32_t Klingelzeit; |
6 | |
7 | if (Klingelflag==0) {Klingelzeit = Zeit; Klingelflag=1;} |
8 | if ( (K==1) && Klingelflag==1 ) { |
9 | Klingelflag=2; |
10 | PORTA ^=(1<<PA1); |
11 | }
|
12 | if (K==0) { |
13 | PORTA &= ~(1 << PA1); // Klingel ausschalten durch "0" auf PA1 |
14 | Klingel=0; |
15 | Klingelflag=0; |
16 | }
|
17 | if (Klingelzeit+14000<Zeit){Klingelflag=0;} |
zwar geht, aber so unübersichtlich und imho hässlich ist. Ich dachte das man das mit ein wenig mehr Know-How vllt. einfacher und hübscher zugleich machen könnte....Wisst ihr da also vielleicht was besseres? danke Jakkob
Was macht diese Funktion genau? Was ist ihre Aufgabe? So wie das für mich aussieht, hängt da am Port ein Summer oder sowas ähliches. D.h. du musst dich mit deinem Timer nicht um die Signalerzeugung an sich kümmern, sondern musst den Summer nur im richtigen Rhytmus ein bzw. ausschalten. Das sieht in der Tat mächtig kompliziert aus. Warum setzt du dir nicht einen Timer auf, der in konstanten Zeitintervallen, zb. 100 ms einen Interrupt auslöst. In der Interruptroutine zählst du jetzt die Aufrufe mit. Nach jeweils 20 Aufrufen wird der Portausgang in den jeweils anderen Zustand geschaltet. Dazu noch einen 2. ten Zähler, der von 0 bis 600 zählt. Ist 600 erreicht, wird der Timer ausgeschaltet. Zum Starten der Klingelsequenz: beide Zähler auf 0 Timer mit dm Vorteiler einschalten fertig, den Rest erledigt die Timer ISR
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.