Hallo
In einem Programm verwende ich einen Timer1 (16Bit) um 10 ms zu erzeugen
und verwende diese 10ms dann in der ISR:
1
voidtimer1_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
voidtimer0_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
Steffen schrieb:> Wie kann ich das aus den 1ms machen. Es wurde Time Slot vorgeschlagen.> Doch wie kann man das vernünftig machen?
Indem man einen passenden Zähler in Software nutzt und nach X
Durchläufen eine Variable (flag) setzt, welches von einer
Statemachine in der Hauptschleife ausgewertet wird. Siehe
Interrupt.
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?
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.
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
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?
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 ....
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?
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)
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!
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.
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.
beo bachta schrieb:> 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.
Der Code sieht schon sehr nach AVR aus, aber es gehört trotzdem
eigentlich dazu, dass man zumindest mal erwähnt, worauf das nachher
laufen soll.
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?
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.
H.Joachim S. schrieb:> Und bei float ist == auch sehr mit Vorsicht zu geniessen.
Das Wort float ist das erste Mal bei dir zu lesen, sonst
keinerlei Vorkommnisse. Wozu also über ungelegte Eier labern?
Vielleicht noch das Thema double einführen?
Steffen schrieb:> Hallo>> Der 16 Bit Timer ist eigentlich zu schade und brauche ihn für PWM.>
Na hoffentlich weißt Du wie der Timer für PWM zu parametrieren ist 🤔
Denke da wirst Du wieder Hilfe benötigen
beo bachta schrieb:> Das Wort float ist das erste Mal bei dir zu lesen, sonst> keinerlei Vorkommnisse. Wozu also über ungelegte Eier labern?
Dann lies einfach noch mal (falls es dir möglich ist verstehend) was ich
geschrieben habe.
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.
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
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 ;-)
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.
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.
Wolfgang schrieb:> Wer einen Zähler für Interrupts/Timerdurchläufe als Float implementiert,> hat ein ganz grundlegendes Problem ;-)
Frei nach Karl Lagerfeld
Wer einen Zähler mit Float realisiert, hat die Kontrolle über seine ISR
verloren.
;-)
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.
beo bachta schrieb:> Könntest du freundlicherweise wenigstens mal versuchen den> Eröffnungs-Post zu lesen?
Hab ich, aber ich habe dort weder etwas über AVR lesen können, noch bin
ich Sherlock Holmes. Was bleibt, wäre Rätselraten.
W.S.
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.
Norbert schrieb:> 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.
Genauso war es gemeint.
W.S. schrieb:> Hab ich, aber ich habe dort weder etwas über AVR lesen können, noch bin> ich Sherlock Holmes.
Also im Sich-dumm-Stellen bist du gaaanz gross.