Time Slot erzeugen - wie am besten

Gast #6781577
Lesenswert?

Hallo
In einem Programm verwende ich einen Timer1 (16Bit) um 10 ms zu erzeugen 
und verwende diese 10ms dann in der ISR:
1
void timer1_init()        // Timer 1, 16 Bit, 8MHz, 10ms
2
  {            // Timer 1 konfigurieren
3
    TCCR1A = (1<<WGM01);      // Auswahl CTC Modus
4
    TCCR1B = (1<<CS01)|(1<<CS00);    // Prescaler auf 64 setzen
5
    OCR1A=1249;        // Wert für 10ms
6
    TIMSK1|=(1<<OCIE1A);      // Interrupt erlauben
7
  }
8
ISR (TIMER1_COMPA_vect)      // Timer 10ms
9
  {  
10
     ...
11
  }
Der 16 Bit Timer ist eigentlich zu schade und brauche ihn für PWM.
Habe dann den 8 Bit Timer0 genommen und mit 1ms laufen lassen. In der 
ISR dann alle 10ms genommen.
1
void timer0_init()          // 8MHz, 8 Bit, 1ms
2
  {              // Timer 0 konfigurieren
3
    TCCR0A = (1<<WGM01);        // Auswahl CTC Modus
4
    TCCR0B = (1<<CS01)|(1<<CS00);      // Prescaler auf 64 setzen
5
    OCR0A=124;          // Wert für 1ms
6
    TIMSK0|=(1<<OCIE0A);        // Interrupt erlauben
7
  }    
8
ISR (TIMER0_COMPA_vect)      // Timer 1ms
9
  {  
10
    millisekunden++;          // Zähler für 10ms
11
    if(millisekunden == 9)
12
      {                  
13
  ……      
14
        
15
  millisekunden = 0;
16
      }
17
  }
Um einen Servo zuschalten brauche ich aber noch andere Zeiten, z.B. 20ms 
und 50ms.
Wie kann ich das aus den 1ms machen. Es wurde Time Slot vorgeschlagen.
Doch wie kann man das vernünftig machen?
LG steffen
Gast #6781608
Lesenswert?

Wenn ich deine Antwort richtig verstehe, muss man einen passenden Zähler 
z.B. für 20ms zusätzlich in der ISR haben der nach Ablauf der 20ms einen 
Flag setzt.
Beeinfliussen sich beide Zähler nicht in der ISR?
Gast #6781654
Lesenswert?

In dem Millisekunden ISR noch eine 32-Bit Variable als 
Millisekundentimer mithochzählen.

Alle anderen Sub-Einheiten können dann diese Variable für ihre Timings 
nehmen.

Mache ich seit Jahren so, funktioniert prima.
#6781661
Lesenswert?

Steffen schrieb:
> Wenn ich deine Antwort richtig verstehe, muss man einen passenden Zähler
> z.B. für 20ms zusätzlich in der ISR haben der nach Ablauf der 20ms einen
> Flag setzt.
> Beeinfliussen sich beide Zähler nicht in der ISR?

wenn Du sie unterschiedlich benennst und dementsprechend zurücksetzt - 
kein Problem:
ein Zaehler für die 10ms "countmilli_10"
ein Zaehler für die 20ms "countmilli_20"

in der ISR machst Du es so wie Du es oben schon beschrieben hast - 
fertig
#6781665
Lesenswert?

PittyJ schrieb:
> In dem Millisekunden ISR noch eine 32-Bit Variable als
> Millisekundentimer mithochzählen.
>
> Alle anderen Sub-Einheiten können dann diese Variable für ihre Timings
> nehmen.

Gruppiere das und du hast übersichtliche Time-Slots....


Steffen schrieb:
> z.B. für 20ms zusätzlich in der ISR haben der nach Ablauf der 20ms einen
> Flag setzt.
Ja
main(){
if (foo_timer_flag) {
foo_timer_flag=0;
....
}

> Beeinfliussen sich beide Zähler nicht in der ISR?

Natürlich nicht. Wie so sollten sie das auch?
Gast #6781712
Lesenswert?

Da komme ich jetzt nicht so schnell mit. Wenn ich so mache

Steffen schrieb:
> ISR (TIMER0_COMPA_vect)      // Timer 1ms
>   {
>     millisekunden++;          // Zähler für 10ms
>     if(millisekunden == 9)
>       {
>   ……
>
>   millisekunden = 0;
>       }
>   }

und dann weiterzähle ... (ist ja blöd gedacht von mir)
Muss es mal ausprobieren. Hab da wohl einen Knoten im Kopf ....
Gast #6782122
Lesenswert?

PittyJ schrieb:
> In dem Millisekunden ISR noch eine 32-Bit Variable als
> Millisekundentimer mithochzählen.
>
> Alle anderen Sub-Einheiten können dann diese Variable für ihre Timings
> nehmen.
>
> Mache ich seit Jahren so, funktioniert prima.

Sorry, da komme ich nicht ganz mit. Habe einiges programmiert, klappt 
aber nicht wie gewünscht. Hab da wohl noch einen dengfehler drin.
1
ISR (TIMER0_COMPA_vect)    // Timer 1ms
2
  {  
3
    millisekunden++;    // Zähler für 10ms
4
    if(millisekunden == 9)            
5
      {                  
6
        ....
7
        millisekunden = 0;
8
      }
9
    if(millisekunden1 == 20)
10
      (    
11
        flag=1;
12
        ....
13
        millisekunden1 = 0;
14
        flag=0;
15
      }
16
  }
Da ist noch ein Denkfehler drin mit millisekunden1.
Wie meinst du das mit der 32 Bit Variablen?
#6782246
Lesenswert?

Du deklarierst  vier Variable (global, volatile)

Int millisecond_10
Int millisecond_20
flag_milli_10
flag_milli_20

In der ISR lässt Du sie zählen:

millisecond_10++
millisecond_20++

Dann fragst Du in der ISR die 10 und die 20ms ab und setzt jeweils ein 
Flag:

If millisecond_10 == 10 flag_milli_10 = 1
If millisecond_20 == 20 flag_milli_20 = 1

In der main() fragst Du diese beiden flags ab und setzt danach die flags 
und die millisecond zurück (in der Main)
Gast #6782276
Lesenswert?

Steffen schrieb:
> Da ist noch ein Denkfehler drin mit millisekunden1.
> Wie meinst du das mit der 32 Bit Variablen?

Flags in der ISR setzen, in der Hauptschleife flagbedingte
Sachen ausführen und Flag löschen!
Flags als volatile deklarieren sonst funktioniert das nicht!
Gast #6782345
Lesenswert?

Steffen schrieb:
> In einem Programm verwende ich einen Timer1 (16Bit) um 10 ms zu erzeugen

Könntest du freundlicherweise wenigstens mal andeuten, was für einen 
Controller du zu verwenden gedenkst? Der Hintergrund ist, daß es bei den 
32 bittigen Controller-Sorten von der Cortex-Art einen Timer genau 
dafür bereits in/an der CPU gibt.

W.S.
Gast #6782373
Lesenswert?

W.S. schrieb:
> Könntest du freundlicherweise wenigstens mal andeuten, was für einen
> Controller du zu verwenden gedenkst?

Könntest du freundlicherweise wenigstens mal versuchen den
Eröffnungs-Post zu lesen? Dort ist unschwer zu erkennen dass
es sich um einen AVR Controller handeln muss.
#6782402
Lesenswert?

ist zwar hier kein Problem, sollte man sich aber nicht unbedingt 
angewöhnen:

    if(millisekunden == 9)
      {
        ....
        millisekunden = 0;
      }
Besser:
    if(millisekunden >= 9)
      {
      }

Deckt den Fall == mit ab, und den Fehlerfall (grösser 9, warum auch 
immer) gleich mit. Und bei float ist == auch sehr mit Vorsicht zu 
geniessen.
Es kostet weder Code noch Zeit.
#6782453
Lesenswert?

H.Joachim S. schrieb:
> Deckt den Fall == mit ab, und den Fehlerfall (grösser 9, warum auch
> immer) gleich mit.

Wobei "deckt" ab in dem Fall heißt: Versteckt einen Fehler. Wenn der 
Wert größer als 9 geworden ist, hat das Programm einen Fehler. Den durch 
>= statt == vertuschen zu wollen, finde ich wenig sinnvoll.

beo bachta schrieb:
> Rolf M. schrieb:
>> aber es gehört trotzdem
>> eigentlich dazu, dass man zumindest mal erwähnt, worauf das nachher
>> laufen soll.
>
> Muss man dir auch sagen dass du zum Bäcker gehen musst wenn
> du Brot kaufen willst?

Nein, aber wenn ich beim Bäcker stehe, mache ich den Mund auf und sage, 
dass ich Brötchen will und warte nicht darauf, dass er das anhand 
irgendwelcher Indizien errät. Das hat auch was mit Höflichkeit zu tun, 
aber das ist dir offenbar fremd.
Gast #6782539
Lesenswert?

Rolf M. schrieb:
> H.Joachim S. schrieb:
>> Deckt den Fall == mit ab, und den Fehlerfall (grösser 9, warum auch
>> immer) gleich mit.
>
> Wobei "deckt" ab in dem Fall heißt: Versteckt einen Fehler. Wenn der
> Wert größer als 9 geworden ist, hat das Programm einen Fehler. Den durch
>>= statt == vertuschen zu wollen, finde ich wenig sinnvoll.

Da vertrete ich seit Jahrzehnten eine andere Auffassung.
Defensive Programmierung. Selbst wenn aufgrund eines physikalischen 
Fehlverhaltens (Strahlung, das böse Auge von Mordor, …) mal ein Bit im 
RAM kippt, läuft das Programm weiter.

Im übrigen
1
millisekunden++;    // Zähler für 10ms
2
if(millisekunden == 9)            
3
{
4
    ...                  
5
    millisekunden = 0;
6
}
zählt der nur neun Millisekunden.
Gast #6782547
Lesenswert?

Wolfgang schrieb:
> H.Joachim S. schrieb:
>> Deckt den Fall == mit ab, und den Fehlerfall (grösser 9, warum auch
>> immer) gleich mit. Und bei float ist == auch sehr mit Vorsicht zu
>> geniessen.
>
> Wer einen Zähler für Interrupts/Timerdurchläufe als Float implementiert,
> hat ein ganz grundlegendes Problem ;-)

Ich kann nicht erkennen das dies impliziert wurde.
Der Satz:
> Und bei float ist == auch sehr mit Vorsicht zu genießen.
ist eine völlig unabhängige/eigenständige Aussage und bezieht sich auf 
Vergleichsoperationen. Außerdem ist die Aussage 100% korrekt.
#6782550
Lesenswert?

Norbert schrieb:
> Ich kann nicht erkennen das dies impliziert wurde.
> Der Satz:
>> Und bei float ist == auch sehr mit Vorsicht zu genießen.
> ist eine völlig unabhängige/eigenständige Aussage und bezieht sich auf
> Vergleichsoperationen. Außerdem ist die Aussage 100% korrekt.

Ja, aber es gibt keinen Sinn, die Aussage dort einzubringen. Weil == bei 
float problematisch sein kann, soll ich es für int nicht verwenden? Ich 
sehe da den Zusammenhang nicht.
Gast #6782567
Lesenswert?

Rolf M. schrieb:
> Norbert schrieb:
>> Ich kann nicht erkennen das dies impliziert wurde.
>> Der Satz:
>>> Und bei float ist == auch sehr mit Vorsicht zu genießen.
>> ist eine völlig unabhängige/eigenständige Aussage und bezieht sich auf
>> Vergleichsoperationen. Außerdem ist die Aussage 100% korrekt.
>
> Ja, aber es gibt keinen Sinn, die Aussage dort einzubringen. Weil == bei
> float problematisch sein kann, soll ich es für int nicht verwenden? Ich
> sehe da den Zusammenhang nicht.

Ich glaube ich sehe worauf du hinaus willst. Ich lese das nur etwas 
entspannter.

So wie ich es gelesen habe steht da das man für diese Vergleiche (besser 
Ende Bedingungen) lieber >= und nicht == nehmen sollte.
Aus der Logik heraus, das ein Zähler von 0…9 niemals  andere Werte 
annehmen sollte. Also ist '0' die natürliche untere Grenze und alles >= 
10 die natürliche obere Grenze. Wenn man == nutzt, könnte (im 
zugegebenermaßen extrem seltenen Sonderfall eines physikalischen 
Problems im RAM) der Zähler eine 11,12, und alles weitere bis zum 
Überlauf einnehmen. Bei acht Bit eventuell verschmerzbar, bei 32 Bit 
dauert's schon sehr lange bis er wieder in seinem angestammten Areal 
ankommt. ;-)

Und nur damit kein falscher Eindruck entsteht, als (ganzzahliger) Zähler 
in einer Interrupt-Routine haben Fließkomma Variablen natürlich nichts 
zu suchen. Ich würde mich sehr anstrengen müssen, dafür einen 
Einsatzzweck zu finden.

Die Aussage, so wie ich sie verstanden hatte, war eher:
Wenn man sich daran gewöhnt diese Vergleiche auf Ende mit == 
durchzuführen und man es irgendwann mal (woanders) mit Fließkomma zu tun 
hat, so kann man böse stolpern.
(Firma: fritzler-avr.de) #6782604
Lesenswert?

Eine Anforderung wurde noch nicht erwähnt:
Wieviel Jitter is denn erlaubt?
Wenn hier ein Servopin gesetzt werden soll, dann müsst der auch in der 
IRQ gesetzt werden, damits wirklich nach 20ms is.
Erst ein Flag setzen und dann in der mainloop checken kann zu Jitetr 
führen und dann zittert der Servo.

W.S. schrieb:
> Hab ich, aber ich habe dort weder etwas über AVR lesen können, noch bin
> ich Sherlock Holmes. Was bleibt, wäre Rätselraten.

Komisch, auf einmal bist du nicht mehr gut in Rätselraten?
Bei meinem ELF Thread haste doch auch munter größten Unsinn 
reininterpretiert aka "Rätselgeraten"
Jetzt bleib doch wenigstens mal konsequent, wenn du sonst schon nur 
Unsinn schreibst.

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