Forum: Mikrocontroller und Digitale Elektronik Timer und Random mit ATMega 8


von Julian P. (greenday)


Lesenswert?

Hallo,

ich stehe gerade mit meinem ATMega 8 vor einem Problem:
In einer "Main-Schleife" werden die Eingänge abgefragt, dem entsprechend 
reagieren die Ausgänge, es wird Etwas im RAM gespeichert und, und, 
und...
Nun möchte ich wenn ein Pin high ist einen Timer starten, der in jedem 
Zyklus der "Main-Schleife" abfrägt, ob 7 min vergangen sind (ob das 
jetzt genau 7 sind oder nicht ist im Prinzip wurscht, also das mit dem 
15,25 durch den Teiler ist zu vernachlässigen), jedoch sollte das keine 
"Sleep"-Funktion sein, nebenher (also während der Timer zählt) sollten 
trotzdem die Eingange abgefragt werden. Es sollte so einfach wie möglich 
sein, reicht wenn nach Ablauf der Zeit ein Register verändert wird. Im 
Tutorial ist ja noch die Ansteuerung einer Anzeige mit drin, ich hätte 
gerne nur den Code für den eigentlichen Timer.
Ich hoffe ihr verteht was ich meine ;-)

Das nächste Problem wäre eine Random Funktion, die entscheidet zwischen 
ja und nein. Mir würde da die billige Version mit der Uhr reichen, nur 
hab ich keine Ahnung wie man sowas realisiert. Hat da jmd. einen Code?

Danke im Voraus!

Mfg greenday

von STK500-Besitzer (Gast)


Lesenswert?

In der Codesammlung findest du mindestens 2 Uhren...

von Karl H. (kbuchegg)


Lesenswert?

Dein Denkansatz ist falsch

> Nun möchte ich wenn ein Pin high ist

Du möchtest sicher nicht jedesmal wenn der Pin high ist, einen Timer 
starten. So ein Pin kann nämlich lange high sein.
Du möchtest sicherlich dann den Timer starten, wenn der Pin high wird. 
D.h. wenn sein Zustand von Low auf High wechselt.

> einen Timer starten, der in jedem
> Zyklus der "Main-Schleife" abfrägt, ob 7 min vergangen sind (ob das
> jetzt genau 7 sind oder nicht ist im Prinzip wurscht, also das mit dem
> 15,25 durch den Teiler ist zu vernachlässigen),

Ein Timer fragt gar nichts ab.
Ein Timer zählt einfach nur vor sich hin. Das ist seine Stärke und das 
kann er. Ansonsten kann so ein Timer nicht allzuviel. Man kann noch eine 
Aktion an bestimmte Zählerstände per Hardware binden, aber das wars dann 
schon.

> jedoch sollte das keine
> "Sleep"-Funktion sein, nebenher (also während der Timer zählt) sollten
> trotzdem die Eingange abgefragt werden.

Der Timer zählt ja sowieso für sich alleine. D.h. du lässt deine 
Hauptschleife weiterlaufen und siehst einfach nur ab und an nach, ob der 
Timer den gewünschten Zählerstand erreicht hat.

Alternativ, und das ist oft die bessere Lösung, kann der Timer auch dein 
Programm benachrichtigen, dass er einen bestimmten Zählerstand erreicht 
hat. Dies erreicht man, indem man den Timer so schnell ticken lässt, 
dass einer der definierten Zählerstände mit einer bestimmten Zeit (oder 
einem Bruchteil davon) übereinstimmt und der Timer eine ISR anstösst.

von Hannes Lux (Gast)


Lesenswert?

Mit Deinem Konzept würde ich auch nicht glücklich werden...

Ich würde so herangehen:

- Timer laufen lassen, der in regelmäßigen Abständen (z.B. 10ms)
  Interrupts auslöst.

- In dessen ISR einen Merker setzen, dass die Mainloop erfährt, dass
  10ms um sind. Dies hält die ISR kurz und schafft "Bewegungsfreiheit"
  für weitere Interrupts, falls das Programm mal komplexer wird.

- In der Mainloop den/die Merker abfragen und bei aktiviertem Merker
  die zugehörige Jobroutine aufrufen, die den Merker löscht und die
  zugehörigen Aufgaben erledigt (Tasten entprellen, Blinkzähler für
  Ausgänge managen, Werte für Berechnungen bereitstellen, usw.).

- Jeder Job springt nach getaner Arbeit (und entwertetem Jobmerker)
  zum Beginn der Mainloop zurück. Die Mainloop prüft also nach jedem
  erledigten Job wieder alle "Aufträge" und fällt in den Sleep (Idle),
  wenn kein Auftrag mehr vorliegt. Der nächste Interrupt weckt die CPU,
  nach Abarbeitung der zugehörigen ISR werden wieder alle Jobs geprüft
  und erledigt. Ohne Interrupt kann während des Sleep kein neuer
  Jobauftrag eintreffen.

- Für einen Zufallswert würde ich an einen ADC-Pin ein Stück Leiterzug
  als "Antenne" vorsehen und mittels ADC dessen Eingangsspannung messen
  und aufaddieren. Wird der Zufallswert gebraucht, nimmt man sich
  einfach eine Kopie des unteren Bytes des aktuellen Standes der Summe.

- Zeitpunkte für weitere Jobs (z.B. Abschalten von Ausgängen nach Ablauf
  einer vorgegebenen Zeit) lassen sich durch Herunterzählen von
  Variablen in einem zeitsynchronisierten Job realisieren. Je nach
  Bedarf kämen dafür Jobaufruf-Intervalle von 100ms, 1s oder mehr in
  Betracht.

Mit so einem Konzept kann ich ein Programm nach und nach erweitern, ohne 
das Timing der bereits bestehenden Komponenten durcheinander zu bringen. 
Brauche ich ein LCD und oder Drehgeber, dann lege ich den Timer-ISR-Takt 
auf 1ms fest und frage in diesem Zeitraster die Drehgeber ab bzw. 
schaufle alle 1ms ein Byte aus dem Bildschirmspeicher (im AVR-SRAM) an 
das LCD. Tasten werden dann jede 16. Runde (also alle 16ms) entprellt.

...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Julian Portik schrieb:

> Das nächste Problem wäre eine Random Funktion, die entscheidet zwischen
> ja und nein. Mir würde da die billige Version mit der Uhr reichen, nur
> hab ich keine Ahnung wie man sowas realisiert. Hat da jmd. einen Code?

In C gibt's nen kleinen, hausbackenen Pseudezufalls-Generator bin
   Beitrag "Miniprojekt: Lagerfeuer-LED (ATtiny25)"

Johann

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.