PIN rhythmisch toggeln

(Firma: Student) #751996
Lesenswert?

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
Gast #752004
Lesenswert?

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.
Gast #752005
Lesenswert?

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.
Gast #752021
Lesenswert?

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
(Firma: Student) #752051
Lesenswert?

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
#752069
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren