mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PIN rhythmisch toggeln


Autor: Jakob M. (Firma: Student) (jakkob)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thilo M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In welcher Sprache denn?
In C ginge Toggeln z.B. so:
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.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stomper (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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_...

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

Autor: Jakob M. (Firma: Student) (jakkob)
Datum:

Bewertung
0 lesenswert
nicht 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:

//Zeit (in ms) wird in ISR hochgezählt

void Klingelknopf(unsigned char K){
  
  uint32_t Klingelzeit;
  
  if (Klingelflag==0) {Klingelzeit = Zeit; Klingelflag=1;}     
  if ( (K==1) && Klingelflag==1 ) {  
    Klingelflag=2;
    PORTA ^=(1<<PA1);
  }    
  if (K==0) {
        PORTA &= ~(1 << PA1);      // Klingel ausschalten durch "0" auf PA1
        Klingel=0;
        Klingelflag=0;
    }
  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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.