Forum: Mikrocontroller und Digitale Elektronik aus mehrere Timer nur ein Timer aktiv


von Tim (Gast)


Lesenswert?

Hallo,

ich habe folgendes vor:

Ich benutze mehrere Timer für verschiede Ereignisse (zBsp. Tastendruch, 
Lauflicht, externer Interrupt, Ein- und Ausgaben...). Manche Timer 
müssen immer aktiv bleiben und bei Überlauf einen Interrupt auslösen. 
Und hier liegt mein Problem: Ich möchte an bestimmte Programmstellen 
alle Timer stoppen (den Zählerzustand kurz anhalten) bis auf den einen 
Timer, der an der Stelle aktiv sein sollte.
Nachdem die Routine abgearbeitet wurde, sollen alle anderen Timer wieder 
weiterzählen (und zwar von dem Zählerzustand, wo sie stehen geblieben 
waren).

Ich habe keine Idee, wie das gelöst werden kann.

Bin für jede Hilfe sehr dankbar

Gruß
Tim


Ps.:
Ich arbeite mit einem ATMega32-Mikrocontroller


so stelle ich mir das ganze vor
1
init(); //alle Timer gestzt und aktiv
2
3
...
4
...
5
6
//nur Timer1 aktiv, alle anderen stoppen
7
while ( !Timer1_ueberlauf) //Flag wird gesetzt, wenn Timer1 überläuft
8
{
9
  tu_was;
10
  tu_was;
11
  tu_was;
12
}
13
14
//->Ab dieser Stelle wieder alle Timer aktiv (weiterzählen)
15
16
...
17
...

von Andreas B. (bitverdreher)


Lesenswert?

Hi,
Indem Du CSxx auf 0 setzt -> Datenblatt.

Gruß
Andy

von Tim (Gast)


Lesenswert?

was genau meinst Du mit CSxx?

Bin zwar kein Anfänger aber an vielen Stellen fehlt mir noch an 
Erfahrung

von AVRFan (Gast)


Lesenswert?

>Ich benutze mehrere Timer für verschiede Ereignisse

Gehts mit einem permanent laufenden Timer, der z. B. alle 10 ms einen 
Interrupt auslöst, an dem das komplette Programm "aufgehangen" wird, 
nicht?

von Andreas B. (bitverdreher)


Lesenswert?

Tim wrote:
> was genau meinst Du mit CSxx?

CSxx ist das entsprechende Clock Select Register (z.B. CS00, CS01,CS02 
für Timer 0) der Timer. Damit mußt Du aber schon zu tun gehabt haben. 
Wie hast Du sonst die Timer zum Laufen gebracht ?

Gruß
Andy

Genauer(und richtiger): CSxx sind die entsprechenden Clock Select Bits 
im Timer/Counter Control Register.

von Tim (Gast)


Lesenswert?

nein geht leider nicht..

ich brauche mehrere Timer, die für verschiedene Aufgaben gedacht sind.
Wie soll ich zBsp. mit einem Timer es schaffen 5 msec lang mit dem 
AD-Wandler abtasten und dabei alle 15msec schauen ob ein Taster betätigt 
wurde.

Nach 5msec muss signalisiert werden, dass der AD-Wandler mit der 
Abtastung aufhören soll und das Programm zu nächsten Schritt weitergehen 
soll.

von Tim (Gast)


Lesenswert?

>CSxx ist das entsprechende Clock Select Register (z.B. CS00, CS01,CS02
>für Timer 0)

ich dachte, Du meinst vielleicht irgendetas mit Chip Select :-/

von Andreas B. (bitverdreher)


Lesenswert?

?????
Du wolltest wissen, wie Du einzelne Timer abstellen und anschließend mit 
gleichen Zählerstand weiterlaufen lassen kannst.

Wenn das nicht die Frage war, dann denke mal drüber nach und stelle die 
Frage neu.

Gruß
Andy

von Karl H. (kbuchegg)


Lesenswert?

Du klemmst dem Timer den Prescaler ab (mit den CSxx Bits)
und er bleibt stehen. Wie soll er denn zählen, wenn er keinen
Eingangsimpuls bekommt?
Wenn du soweit bist, daß es weitergehen kann, dann hängst
du den Prescaler wieder an.

Ist so einfach wie einem Baby den Schnuller klauen.

von Andreas B. (bitverdreher)


Lesenswert?

Schau doch mal in das Datenbblatt:
Register TCCR0 mit Bit CS00,CS01 und CS02 für Timer 0.

Gruß
Andy

von Andreas B. (bitverdreher)


Lesenswert?

> Ist so einfach wie einem Baby den Schnuller klauen.

Du bist böse.;-)

von Tim (Gast)


Lesenswert?

>Du wolltest wissen, wie Du einzelne Timer abstellen und anschließend mit
>gleichen Zählerstand weiterlaufen lassen kannst.

genau das war meine Frage :-D

>Du klemmst dem Timer den Prescaler ab (mit den CSxx Bits)
>und er bleibt stehen.

und so einfach geht das. Ich dachte schon es wird mich Tage kosten, bis 
ich es raus hab :-)

Vielen Dank

von Peter D. (peda)


Lesenswert?

Tim wrote:
> Wie soll ich zBsp. mit einem Timer es schaffen 5 msec lang mit dem
> AD-Wandler abtasten und dabei alle 15msec schauen ob ein Taster betätigt
> wurde.

Die Lösung sollte einem schon fast ins Auge springen:

5 * 3 = 15

Du nimmst nen 5ms Interrupt und zählst darin ne Variable hoch. Wird sie 
3 setzt Du sie wieder auf 0 und machst das 15ms Ding.

Dem Prinzip sind keinerlei Grenzen gesetzt.
Du kannst 100 verschiedene Zeitaufgaben mit einem Timer erschlagen.

Solche Timer zu stoppen ist auch kein Problem.
Du setzt eine weitere Variable und die Zählvariablen zählen nur hoch, 
wenn diese einen bestimmten Wert enthält.


Peter

von Tim (Gast)


Lesenswert?

danke Peter, das ist eine gute Lösung.

von AVRFan (Gast)


Lesenswert?

>ich brauche mehrere Timer, die für verschiedene Aufgaben gedacht sind.
>Wie soll ich zBsp. mit einem Timer es schaffen 5 msec lang mit dem
>AD-Wandler abtasten und dabei alle 15msec schauen ob ein Taster betätigt
>wurde.

"Software-Timer" heißt das Zauberwort.  Das Prinzip: (1) Du läßt den 
zeitlichen Ablauf jedes Prozesses in Deinem Programm von einem eigenen 
Software-Timer steuern.  (2) Alle Software-Timer werden von nur einem 
Hardware-Timer getaktet.  Das ist alles.

Ein Beispiel in Pseudocode:
1
Reset:
2
    [Hardware-Timer konfigurieren] 
3
4
    Process_ADC_Init
5
    Process_Key_Init
6
    Process_XXX_Init
7
    Process_YYY_Init
8
    Process_ZZZ_Init
9
10
    [Hardware-Timer starten]
11
    [--> Programm in Endlosschleife schicken <--]
12
13
//-----------------------------
14
15
Timer_Tick:      // wird permanent alle 1 ms ausgeführt
16
  {   
17
  Process_ADC_Run
18
  Process_Key_Run
19
  Process_XXX_Run
20
  Process_YYY_Run
21
  Process_ZZZ_Run
22
  }
23
24
//-----------------------------
25
26
Process_ADC_Run: 
27
    {
28
    IF (i>-1)       // i = -1  <--> Prozess 'ADC' inaktiv
29
        {
30
        inc(i)
31
32
        IF (i=5)    // Software-Timer-Prescaler = 5
33
            {
34
            i = 0
35
            [AD-Wandler abtasten]
36
            }
37
        }
38
    }
39
40
//-----------------------------
41
42
Process_Key_Run: 
43
    {
44
    IF (k>-1)        // k = -1  <--> Prozess 'Key' inaktiv
45
        {
46
        inc(k)
47
48
        IF (k=15)    // Software-Timer-Prescaler = 15
49
            {
50
            k = 0
51
            [Status der Tasten abfragen]
52
            }
53
        }
54
    }
55
56
//-----------------------------
57
58
Process_XXX_Run:
59
    {
60
    IF (l>-1)         // l = -1  <--> Prozess 'XXX' inaktiv
61
        {
62
        inc(l)
63
64
        IF (l=100)    // Software-Timer-Prescaler = 100
65
            {
66
            l = 0
67
            
68
            IF (l=0)  [XXX-Event 1 ausführen]
69
            IF (l=20) [XXX-Event 2 ausführen]
70
            IF (l=38) [XXX-Event 3 ausführen]
71
            IF (l=75) [XXX-Event 4 ausführen]
72
            IF (l=76) [XXX-Event 5 ausführen]
73
            }
74
        }
75
    }

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.