Forum: Mikrocontroller und Digitale Elektronik Tiny13 Niederfrequenz-Zähler und Abschaltverzögerung


von Matthias Z. (zrieschling)


Lesenswert?

Hallo, ich bräucht ein ganz einfaches Programm für nen Tiny13, das
bei einem Signal (5mal in 3 sec also ca. 1,6hz) nen Transistor ansteuert 
und
bei erneuten 1,6 hz signal wieder los lässt.

An nem anderen Eingang soll noch ein Taster ran, der einen Ausgang für 
10 sec ansteuert und dann wieder los lässt. Also quasi ne 
Abschaltverzögerung.

Wollt eigentlich von der Codesammlung was zusammensuchen, aber hab bis 
jetzt
noch keine Ahnung vom Programmieren. (was sich hoffentlich ändern wird)
Die Abschaltverzögerung hab ich jetzt mit nem rc-glied gemacht. es wär 
natürlich interessant für mich wie das im quellcode funktioniert. muss 
ja irgendwie beginnen...

Also wenn jemand 15min über hat und mir ein kleines Programm basteln 
könnte
wär ich ohne Ende dankbar...
Für links zu ähnlichen Codes die ich abändern könnte bin ich natürlich 
auch dankbar...


Gruß
Matthias

von avr (Gast)


Lesenswert?

Hier findest du einige Beispiele, deine Verzögerung ist BSP 4.

http://www.avr-asm-tutorial.net/avr_de/praesentation/index.html

Gehört zu diesem Tutorial:

http://www.avr-asm-tutorial.net/avr_de/index.html

gruß avr

von Zrieschling (Gast)


Lesenswert?

Hallo, danke für die links. Für mich als Anfänger ist assembler wirklich 
nicht
leicht nachzuvollziehen ;-)

hab nun aber schon einiges über Timer fürs AVRStudio gefunden. Das 
sollte ich schon gebacken bekommen...

jetzt bräucht ich nur noch nen Tip mit dem schalten bei Signal >= 1,6 
Hz.
Wo könnte soetwas zur Anwendung kommen um es mir abzugucken ;-)

schönen Feiertag noch

Gruß
Matthias

von gerd (Gast)


Lesenswert?

Hallo.

Ein Programm werde ich Dir nicht schreiben. Das wäre was für Faule, und 
das bist Du ja wahrscheinlich nicht, wenn Du solche Probleme lösen 
willst. Aber vielleicht ein paar Hinweise, wie Du Dich dem Problem 
näherst.

Ich hinterfrage jetzt mal nicht den Sinn Deines Unterfangens.

Wie Du mit einem externen Interrupt auf ein Signal reagierst, musst Du 
als erstes wissen. Dazu muss
1. der Input-Pin Int0 oder Int1 ein Eingang sein, am besten mit einem 
Pull-Up, wenn Du einen Taster benutzt,
2. der betreffende Input mit einem Kondensator auf ca. 50 ms so 
verlangsamt werden, dass Dein Tasterprellen nicht durchkommt,
3. der betreffende externe Int auf eine fallende Flanke eingestellt 
werden,
4. der entsprechende Interrupt eine Service-Routine erhalten, die
5. beim Eintreffen a) des ersten Pulses einen Zähler auf Eins setzt und 
einen Timer startet, bzw. b) den Zähler um eins erhöht.

Nach dem Zählerstart muss der genau 3 Sekunden lang zählen, wenn der 
Zählerstand dann bei genau fünf ist, musst Du umschalten (wenn die 
Folgemimik aus ist, muss sie eingeschaltet werden, wenn sie an ist, dann 
muss sie ausgeschaltet werden).
Dein Problem sind erst mal die ewig langen Zeiten von mehreren Sekunden. 
Bei einem Takt von z.B. 2 MHz, einer Vorteilerrate von 1024 und 8-Bit 
läuft Dein Zähler  Das bedeutet, dass Dein Zähler 7,6 mal pro Sekunde 
überläuft, also 22,9 mal in drei Sekunden. Bei einem 8-Bit-Zähler 
brauchst Du also einen Überlaufzähler. Wenn der bei 23 ist, dann sind 
die drei Sekunden herum.
Hast Du einen 16-Bit-Zähler, dann muss der bis 5859 zählen, dann sind 
auch 3 Sekunden um. Um die zu erkennen, musst Du einen 
Compare-Match-Interrupt programmieren, der den Ablesevorgang vornimmt.

Nun das mit den 10 Sekunden. Wenn Du einen 16-Bit-Zähler hast, lässt Du 
den dann um 19531 weitere Zähltakte weiterlaufen, erkennst diesen 
Zählerstand mit dem anderen Compare-Match (16-Bit-Zähler haben zwei 
Compare-Matches), schaltest Deinen Ausgang ab und stoppst dann den 
Zähler.

Wenn Du einen anderen Takt hast, musst Du natürlich die Zahlen dem 
anpassen.

Am Besten checkst Du erst mal die Timermimik und malst Dir ein 
Ablaufdiagramm, mit allen Zeiten und allen Vorgängen auf. Es treten da 
einige weitere Konflikte auf, wenn z.B. jemand während des 10-Sekunden 
Ablaufs schon wieder mit der Taste herum macht. Das löst man am Besten 
mit Flaggen, die unerwünschte Nebeneffekte blockieren. Oder mit zwei 
unabhängigen Timern (die man aber auch synchronisieren muss).

Im Ganzen ein recht anspruchsvolles Problem für einen Anfänger. Auch für 
ausgefuchste Könner eine Aufgabe, die man nicht in 15 Minuten erledigt.

Und: Dein Problem ist sicher nicht nur Assembler, sondern auch die 
Hardware und ihre Eigenheiten, oder?

Viel Erfolg,
gerd

von Karl H. (kbuchegg)


Lesenswert?

@gerd

So kompliziert würd ich mir das gar nicht machen.
Externen Interrupt ist doch auch nicht notwendig.

Ich würd mir einen einzigen Timer aufsetzen, der mir eine Zeitbasis von 
ein paar Millisekunden gibt. Meinetwegen so um die 10.

In der ISR werden alle 10 Millisekunden die Zeiten ausgewertet, alle 
Eingänge abfragt und deren Veränderungen festgestellt und geeignete 
Aktionen eingeleitet.

So in der Art

   3 Sekunden Timer abgelaufen ?   // Sind 3 Sekunden um
     PulsCounter > 5 ?             // Waren es genug Pulse
       Transistor umschalten
       PulsCounter = 0
   else
     3 Sekunden Timer um 1 erniedrigen

   10 Sekunden Timer abgelaufen ?
     Ja: Ausgang loslassen
   else
     10 Sekunden Timer um 1 erniedrigen

   Tasten Eingang abfragen und mit vorhergehendem Wert vergleichen
   steigende (fallende) Flanke erkannt ?
     10 Sekunden Timer auf 1000 stellen
     Ausgang einschalten

   Puls Eingang abfragen und mit vorhergehendem Wert vergleichen
   steigende Flanke erkannt ?
     ist der 3 Sekunden Timer gleich 0 (also abgelaufen) ?
       3 Sekunden Timer auf 300 stellen
       PulsCounter auf 1 stellen
     else
       PuslCounter um 1 erhöhen

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.