aus mehrere Timer nur ein Timer aktiv

Gast #806170
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
...
Gast #806245
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?
#806260
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.
Gast #806272
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.
#806278
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.
Gast #806288
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
#806304
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
Gast #806348
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
    }

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