Forum: Mikrocontroller und Digitale Elektronik Arduino Timer0 interrupt nutzen


von R. H. (breezer)


Lesenswert?

Hallo,

ich versuche einen Interrupt von Timer0 auszulösen und dabei eine 
Variable alle 1ms zu inkrementieren. Eigentlich sollte der Interrupt 
alle 1ms aufgerufen werden da so wie ich es verstanden habe auch die 
millis() Funktion von diesem Timer bedient wird.

Ich habe mich an diese Anleitung gehalten:

https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers

Der Interrupt wird auch ausgelöst, nur leider nicht alle 1ms sondern nur 
alle 2ms.

in der Setup Routine habe ich dies eingefügt:
1
  OCR0A = 0xAF;
2
  TIMSK0 |= _BV(OCIE0A);

die ISR:
1
ISR(TIMER0_COMPA_vect) 
2
{
3
  timeout++;
4
  digitalWrite(led, !digitalRead(led));
5
}

Bei dem Arduino handelt es sich um einen Pro Mini 3.3v 8Mhz.

Die delay() Funktion funktioniert und verzögert korrekt.

: Bearbeitet durch User
Beitrag #5369237 wurde von einem Moderator gelöscht.
von spess53 (Gast)


Lesenswert?

Hi

>in der Setup Routine habe ich dies eingefügt:

>  OCR0A = 0xAF;

Wie kommst du auf diesen Wert?

MfG Spess

von R. H. (breezer)


Lesenswert?

ich habe den code aus dem Link übernommmen, ist aber auch egal welcher 
Wert in dem Register steht, es bleibt immer bei 2ms

von Georg M. (g_m)


Lesenswert?

> digitalWrite(led, !digitalRead(led));

Ist "led" Output und Input gleichzeitig?

von R. H. (breezer)


Lesenswert?

led ist als Output deklariert. Das Pin Toggeln mit
1
digitalWrite(led, !digitalRead(led));
 funktioniert aber

von Reiner_Gast (Gast)


Lesenswert?

R. H. schrieb:
> Ich habe mich an diese Anleitung gehalten:
>
> https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers
>
> Der Interrupt wird auch ausgelöst, nur leider nicht alle 1ms sondern nur
> alle 2ms.
>
> in der Setup Routine habe ich dies eingefügt:
>   OCR0A = 0xAF;
>   TIMSK0 |= _BV(OCIE0A);
>
> die ISR:
> ISR(TIMER0_COMPA_vect)
> {
>   timeout++;
>   digitalWrite(led, !digitalRead(led));
> }
>
> Bei dem Arduino handelt es sich um einen Pro Mini 3.3v 8Mhz.

Da weiß man echt nicht, wo man anfangen soll...

1.) Ist das bisschen Schnipsel Code in der Setup() keine ordentliche 
Initialisierung des Timer0. Das funktioniert nur, weil die Arduino 
Umgebung schon vorher irgend ein Init gemacht hat.
2.) Da der Timer0 von der Arduino IDE ebenfalls für millis() verwendet 
ist, weißt du nicht, was "unter" der Haube mit der Timer0 Konfiguration 
geschieht. Bleibt denn der Wert von OCR0A bei 0xAF nach dem setup()? 
Nimm lieber den Timer2. Der wird von der Arduino IDE mW nur für die 
tone() Funktion benutzt.
3.) Der Anleitung geht von einem 16(!) MHz Arduino aus, du hast aber nur 
einen 8(!) MHz Arduino. Evtl. liegt es auch daran: "16MHz zu 8MHz 
verhält sich wie 2ms zu 1 ms"
4.) Die Anleitung ist von 2015... Und damit auf einer vermutlich viel 
älteren Arduino IDE geschrieben. Das muss nicht zwangsläufig bedeuten, 
dass es mit der aktuellen immer noch läuft. Das Problem gibt es auch bei 
einigen Libraries

von spess53 (Gast)


Lesenswert?

Hi

>2.) Da der Timer0 von der Arduino IDE ebenfalls für millis() verwendet
>ist, weißt du nicht, was "unter" der Haube mit der Timer0 Konfiguration
>geschieht.

0xAF ist trotzdem Unsinn. 1ms bekommt man, egal ob 8 oder 16MHz nur mit 
Prescaler 64. Und da sind die OCRA-Werte 0x7C bzw. 0xF9.

MfG spess

von Reiner_Gast (Gast)


Lesenswert?

spess53 schrieb:
> 0xAF ist trotzdem Unsinn. 1ms bekommt man, egal ob 8 oder 16MHz nur mit
> Prescaler 64. Und da sind die OCRA-Werte 0x7C bzw. 0xF9.

Nicht unbedingt... Wenn du dir den Artikel mal genauer anschaust:

"Timer0 is an 8-bit that counts from 0 to 255 and generates an interrupt 
whenever it overflows. It uses a clock divisor of 64 by default to give 
us an interrupt rate of 976.5625 Hz (close enough to a 1KHz for our 
purposes).  We won't mess with the freqency of Timer0, because that 
would break millis()!

Comparison Registers
Arduino timers have a number of configuration registers.  These can be 
read or written to using special symbols defined in the Arduino IDE. 
For comprehensive description of all these registers and their 
functions, see the links in "For further reading" below.

We'll set up a up a comparison register for Timer 0 (this register is 
known as OCR0A) to generate another interrupt somewhere in the middle of 
that count.  On every tick, the timer counter is compared with the 
comparison register and when they are equal an interrupt will be 
generated."

D.h. die Arduino IDE hat den Teiler von 64 eingestellt (reicht wohl von 
der Geneuigkeit ;-)) und der Compare IRQ hängt sich quasi in das Zählen 
rein, ohne den eigentlichen IRQ der Arduino IDE zu stören. D.h. egal 
welchen Wert OCR0A bekommt, der Compare IRQ kommt dann auch alle ca. 1ms 
vor

Wenn du den Timer frei programmierst und exakt alle 1ms den IRQ haben 
willst, dann gebe ich dir recht, dann müssen es die beiden OCR0A Werte 
sein.

von spess53 (Gast)


Lesenswert?

Hi

>Nicht unbedingt... Wenn du dir den Artikel mal genauer anschaust:

>"Timer0 is an 8-bit that counts from 0 to 255 and generates an interrupt
>whenever it overflows. It uses a clock divisor of 64 by default to give
>us an interrupt rate of 976.5625 Hz (close enough to a 1KHz for our
>purposes).

976.5625 Hz ergeben bei 16MHz eine Comparewert von 0xF3. Passt auch 
nicht zu
0xAF. Das ergäbe nämlich 1,41 ms.

Ehrlich gesagt, halte ich die 0xAF für einen Schreib- plus Rechenfehler.

Erstens sollte es 0xFA heissen. In der Formel im Datenblatt steht im 
Nenner ein 2 x N x (1 + OCRnx). Bei der Umstellung der Formel kommt dann 
OCR0A = (..)-1 heraus. Und 0xFA-1 = 0xF9. Genau der Wert den ich für 1ms 
errechnet habe.

>D.h. die Arduino IDE hat den Teiler von 64 eingestellt (reicht wohl von
>der Geneuigkeit ;-)) und der Compare IRQ hängt sich quasi in das Zählen
>rein, ohne den eigentlichen IRQ der Arduino IDE zu stören. D.h. egal
>welchen Wert OCR0A bekommt, der Compare IRQ kommt dann auch alle ca. 1ms
>vor

Muss ich das verstehen?

MfG Spess

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Reiner_Gast schrieb:
> D.h. die Arduino IDE hat den Teiler von 64 eingestellt (reicht wohl von
> der Geneuigkeit ;-)) und der Compare IRQ hängt sich quasi in das Zählen
> rein, ohne den eigentlichen IRQ der Arduino IDE zu stören. D.h. egal
> welchen Wert OCR0A bekommt, der Compare IRQ kommt dann auch alle ca. 1ms
> vor

... das klingt nach esoterik.

timer0 hat zwei compare match units, einen hat arduino belegt und der 
andere ist frei belegbar. die taktfrequenz gibt arduino quasi vor, somit 
sind je nach hw prescaler und osc bereits festgelegt.

dann lässt sich der compare wert wie immer berechnen.

hier wird nichts irgendwo reingehängt sondern ganz normal eine isr auf 
compare macth unit a aufgerufen.


mt

von S. Landolt (Gast)


Lesenswert?

Vielleicht habe ich es auch nicht richtig verstanden, kenne den Arduino 
nicht, aber ich versuche es trotzdem mal: Timer0 läuft durch, Arduino 
nutzt die Overflow-ISR. Wohlgemerkt, kein CTC. Also kann man jetzt 
noch Compare-ISRs aufsetzen, wobei die OCR-Werte nur die Phasenlage 
bestimmen, die Frequenz ist immer die gleiche, nämlich die des Overflow. 
So zumindest verstehe ich Reiner_Gast.

von Reiner_Gast (Gast)


Lesenswert?

spess53 schrieb:
>>"Timer0 is an 8-bit that counts from 0 to 255 and generates an interrupt
>>whenever it overflows. It uses a clock divisor of 64 by default to give
>>us an interrupt rate of 976.5625 Hz (close enough to a 1KHz for our
>>purposes).
>
> 976.5625 Hz ergeben bei 16MHz eine Comparewert von 0xF3. Passt auch
> nicht zu
> 0xAF. Das ergäbe nämlich 1,41 ms.
>
> Ehrlich gesagt, halte ich die 0xAF für einen Schreib- plus Rechenfehler.

Hi,

du hast es nicht verstanden, fürchte ich...

Du musst das ganze im Kontext der Arduino IDE sehen... und die 
initalisiert den Timer0 auf den Modus "Fast PWM" (siehe Funktion init(), 
wiring.c library der aktuellen Arduino IDE), und dieser Modus zählt nun 
mal von 0 bis 255, egal, was in OCR0A/B steht (sagt das Datenblatt zum 
ATMega328, nicht ich ;-))

Demnach wird: 16000000(MHz) / 64 (Prescaler) = 976,5625 Hz

Damit die Arduino IDE trotzdem die 1ms richtig zählt, wird für die 
Differenz ein Counter mitgezählt und dann zu der Anzahl der 
Millisekunden zugefügt, wenn die Abweichung zu groß geworden ist (steht 
etwas weiter oben in der ISR; auch wieder wiring.c lib)

Ich schlage vor, siehe selbst mal dort nach...

von Reiner_Gast (Gast)


Lesenswert?

S. Landolt schrieb:
> Vielleicht habe ich es auch nicht richtig verstanden, kenne den Arduino
> nicht, aber ich versuche es trotzdem mal: Timer0 läuft durch, Arduino
> nutzt die Overflow-ISR. Wohlgemerkt, kein CTC. Also kann man jetzt
> noch Compare-ISRs aufsetzen, wobei die OCR-Werte nur die Phasenlage
> bestimmen, die Frequenz ist immer die gleiche, nämlich die des Overflow.
> So zumindest verstehe ich Reiner_Gast.

Bingo!

von Reiner_Gast (Gast)


Lesenswert?

Apollo M. schrieb:
> timer0 hat zwei compare match units, einen hat arduino belegt und der
> andere ist frei belegbar. die taktfrequenz gibt arduino quasi vor, somit
> sind je nach hw prescaler und osc bereits festgelegt.

Sicher?... Dann schau doch mal selber nach in den Arduino sourcen... 
(siehe meinen vorherigen Post)

Die Taskfrequenz gibt der Quarz vor und nicht der Arduino vor... Die 
Platform heißt nur so...

Der Prescaler und Countermodus wird per Software gesetzt... und damit 
die Aufruffrequenz für die entsprechende ISR

> dann lässt sich der compare wert wie immer berechnen.
>
> hier wird nichts irgendwo reingehängt sondern ganz normal eine isr auf
> compare macth unit a aufgerufen.

Der Compare Match wird in der Frequenz durchgeführt, die die 
Timereinstellung der Arduino IDE vorgibt, und damit hängt die quasi 
"hinten dran"

von R. H. (breezer)


Lesenswert?

Hallo,

danke für die Antworten. So wie es  S. Landolt beschrieben hat habe ich 
es auch verstanden, deswegen ist es egal welcher Wert im Compare 
Register steht.

Leider beantworten alle Kommentare noch nicht warum die ISR nun alle 2ms 
aufgerufen wird und nicht alle 1ms.

Seltsamerweise funktionieren ja alle Funktionen wie millis() und delay() 
korrekt, ich verstehe es nicht....

von Reiner_Gast (Gast)


Lesenswert?

R. H. schrieb:
> Seltsamerweise funktionieren ja alle Funktionen wie millis() und delay()
> korrekt, ich verstehe es nicht....

Schwer zu sagen. Wie hasst du denn gemessen?
Ist die Variable timeout als volatile deklariert?

von S. Landolt (Gast)


Lesenswert?

Ich vermute einen Interpretationsfehler: die ISR wird alle 1 ms 
aufgerufen, wegen des Hin- und Herschaltens wird daraus eine Frequenz 
von 500 Hz.

von spess53 (Gast)


Lesenswert?

Hi

>Demnach wird: 16000000(MHz) / 64 (Prescaler) = 976,5625 Hz

16000000/64 ist bei mir 250000 kHz. Bei dir fehlt noch ein /256. Dann 
stimmt es.

>Damit die Arduino IDE trotzdem die 1ms richtig zählt, wird für die
>Differenz ein Counter mitgezählt und dann zu der Anzahl der
>Millisekunden zugefügt, wenn die Abweichung zu groß geworden ist (steht
>etwas weiter oben in der ISR; auch wieder wiring.c lib)

Ach so, also 'von hinten durch die Brust in Auge'.

>Ich schlage vor, siehe selbst mal dort nach...

Muss nicht sein. Ich programmiere schon seit 20 Jahren erfolgreich AVRs 
(ohne Ardudings). Warum sollte ich mich durch das Arduino-Gedödel davon 
abbringen lassen vernünftig zu programmieren?

MfG Spess

von Reiner_Gast (Gast)


Lesenswert?

Hi

spess53 schrieb:
> Ach so, also 'von hinten durch die Brust in Auge'.

ja, habe mich auch erschrocken, als ich das gesehen habe...

>
>>Ich schlage vor, siehe selbst mal dort nach...
>
> Muss nicht sein. Ich programmiere schon seit 20 Jahren erfolgreich AVRs
> (ohne Ardudings). Warum sollte ich mich durch das Arduino-Gedödel davon
> abbringen lassen vernünftig zu programmieren?

Das stimmt... bin auch davon weg...

Frohes Osterfest :-)

von R. H. (breezer)


Lesenswert?

Reiner_Gast schrieb:
> Schwer zu sagen. Wie hasst du denn gemessen?

Gemessen habe ich mittels Pin toggeln und Oszi, sind ziemlich genau 2 ms
1
digitalWrite(led, !digitalRead(led));

S. Landolt schrieb:
> Ich vermute einen Interpretationsfehler: die ISR wird alle 1 ms
> aufgerufen, wegen des Hin- und Herschaltens wird daraus eine Frequenz
> von 500 Hz.


Unwarscheinlich das das Pin toggeln exakt 1ms dauert oder?


Ich werde mich dann wohl damit abfinden müssen mit den 2 ms zu leben, 
das funktioniert ja...

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Nicht ganz exakt 1ms, das wissen wir ja. Aber nochmal, welche Frequenz 
wird mit dem Oszilloskop gemessen?

von R. H. (breezer)


Lesenswert?

S. Landolt schrieb:
> Nicht ganz exakt 1ms, das wissen wir ja. Aber nochmal, welche Frequenz
> wird mit dem Oszilloskop gemessen?

Bei jedem Aufruf der ISR wird der Pin umgeschaltet...

Gemessen habe ich jeweils die on oder off Zeit, sind 2,02 ms laut Oszi

1
ISR(TIMER0_COMPA_vect) 
2
{
3
  timeout++;
4
  digitalWrite(led, !digitalRead(led));
5
}

: Bearbeitet durch User
von Reiner_Gast (Gast)


Lesenswert?

R. H. schrieb:
> Bei jedem Aufruf der ISR wird der Pin umgeschaltet...

Ja, das ist schon klar...

Aber von wo bis wo sind es auf dem Oszi 2ms?

Von einem Einschalten bis zum nächsten, oder ist das die Dauer für Der 
Ein- bzw. Aus-Phase?

von S. Landolt (Gast)


Lesenswert?

Vielleicht liege ich auch falsch, aber simpel gefragt: auf dem 
Oszilloskop ist ein Rechtecksignal zu sehen, wie lang ist ein Strich 
oben und wie lang unten?

von R. H. (breezer)


Angehängte Dateien:

Lesenswert?

Hier ein Bild vom Oszillogramm

von Reiner_Gast (Gast)


Lesenswert?

Hast du das Board auch als 8 MHz Board vor dem Flashen in der Arduino 
IDE eingestellt?

von R. H. (breezer)


Lesenswert?

Reiner_Gast schrieb:
> Hast du das Board auch als 8 MHz Board vor dem Flashen in der Arduino
> IDE eingestellt?

Ja die IDE ist auf ATmega328p (3.3V, 8MHz) eingestellt.
Wie gesagt funktionieren ja auch die millis() und delay() Funktionen 
korrekt.

von S. Landolt (Gast)


Lesenswert?

Ich würde dieses
>   digitalWrite(led, !digitalRead(led));
versuchsweise ersetzen durch
  PINLED |= (1<<LED);

von S. Landolt (Gast)


Lesenswert?

PS:
mutatis mutandis natürlich, an welchem Pin auch immer die LED sitzt.

von R. H. (breezer)


Lesenswert?

S. Landolt schrieb:
> versuchsweise ersetzen durch
>   PINLED |= (1<<LED);

Pin toggeln mit
1
PINB = PINB | 0b00100000;

ändert nichts, es bleibt bei 2 ms

von Einer K. (Gast)


Lesenswert?

R. H. schrieb:
> PINB = PINB | 0b00100000;
Unnötig und tut sicherlich was anderes, als du erreichen willst.

Aus 2 Gründen:
1: digitalRead() und digitalWrite() ist deutlich schneller als 1 ms
2: PINB = 0b00100000; // wäre korrekt

von S. Landolt (Gast)


Lesenswert?

D.h., das Programm sieht jetzt so aus:
1
void setup()
2
{
3
 pinMode(LED, OUTPUT);
4
 TIMSK0 |= _BV(OCIE0A);
5
}
6
7
void loop()
8
{
9
}
10
11
ISR(TIMER0_COMPA_vect) 
12
{
13
PINB = PINB | 0b00100000;
14
}
Oder?

von R. H. (breezer)


Lesenswert?

S. Landolt schrieb:
> D.h., das Programm sieht jetzt so aus:

ja, plus
1
OCR0A = 0xAF;

in der setup routine

von H. L. (hans_la)


Lesenswert?

Zitat:
"Ich vermute einen Interpretationsfehler: die ISR wird alle 1 ms
aufgerufen, wegen des Hin- und Herschaltens wird daraus eine Frequenz
von 500 Hz."

da steht doch die Lösung, warum geht darauf keiner ein?

Gruß
Hans

von S. Landolt (Gast)


Lesenswert?

Okay, der OCR-Wert spielt ja keine Rolle, kann auch der Reset-Wert sein.
  Tut mir leid, ich gebe auf.

von S. Landolt (Gast)


Lesenswert?

> warum geht darauf keiner ein?
Im Oszillogramm ist doch ein Rechtecksignal mit 2+2 ms zu sehen, oder 
nicht?


Eine Idee hätte ich noch, aber wirklich daran glauben kann ich nicht: es 
mit B versuchen, also:
1
void setup()
2
{
3
 pinMode(LED, OUTPUT);
4
 TIMSK0 |= _BV(OCIE0B);
5
}
6
7
void loop()
8
{
9
}
10
11
ISR(TIMER0_COMPB_vect) 
12
{
13
PINB = PINB | 0b00100000;
14
}

von Einer K. (Gast)


Lesenswert?

S. Landolt schrieb:
> ISR(TIMER0_COMPB_vect)
> {
> PINB = PINB | 0b00100000;
> }

Da wird mir ja (schon fast) schlecht von....

 PINB = 0b00100000;

aber nicht:
 PINB = PINB | 0b00100000;
Denn so lernen die Mitleser doch das Falsche, und denen fällt das dann 
auf die Füße.
Denn die Folgen sind doch sicherlich nicht beabsichtigt, oder?

von S. Landolt (Gast)


Lesenswert?

an ufuf:

Also das
> PORTB = PORTB | 0b00100000;
ist garantiert falsch.

Und wo beim Anderen der Unterschied liegen soll, ist mir unklar.

von Einer K. (Gast)


Lesenswert?

S. Landolt schrieb:
> an ufuf:
>
> Also das
>> PORTB = PORTB | 0b00100000;
> ist garantiert falsch.
>
> Und wo beim Anderen der Unterschied liegen soll, ist mir unklar.

Das zitierte habe ich wieder gelöscht, weil falsch.
Warst nur schneller...

> Und wo beim Anderen der Unterschied liegen soll, ist mir unklar.
Weil andere Pins mittogglen, wenn sie Outputs, und High sind.

Das mag in diesem konkreten Fall egal sein.
Kann einem aber in anderen Anwendungen auf die Füße fallen.

von S. Landolt (Gast)


Lesenswert?

Ah, jetzt dämmert es mir:
"Independent of the setting of Data Direction bit DDxn, the port pin can 
be read through the PINxn Register bit."

von S. Landolt (Gast)


Lesenswert?

Prima, jetzt sitzt ja ein Arduino-Fachmann am Tisch, da wird sich doch 
das Rätsel lösen lassen.

von Einer K. (Gast)


Lesenswert?

Welches Rätsel?
Warum die ISR bei einem 16MHz Arduino alle ca 1ms aufgerufen wird, aber 
bei einem 8MHz Arduino nur alle ca. 2ms?

Dann ist die Antwort doch offensichtlich!
Sie schreit doch!

Der Teiler ist 64.
Was soll der Prescaler/Timer denn sonst machen, als bei halbierter 
Eingangsfrequenz auch die halbierte Ausgangsfrequenz zu liefern?
Würde er das nicht tun, dann wäre er ein Fall für den Müll.

Also, das zu erwartende Verhalten!
Kein Grund sich zu wundern.


--
PS:
S. Landolt schrieb:
> Prima, jetzt sitzt ja ein Arduino-Fachmann am Tisch, da wird sich doch
> das Rätsel lösen lassen.
Danke für die Blumen!

von S. Landolt (Gast)


Lesenswert?

Klingt pausibel. Soll das dann heißen, dass die Funktionen delay und 
millis hier eine Auflösung von 2 ms haben?

von S. Landolt (Gast)


Lesenswert?

> Danke für die Blumen!
Wir kennen uns lange genug, und zumindest ich weiß Sie zu schätzen.

von Einer K. (Gast)


Lesenswert?

S. Landolt schrieb:
> Klingt pausibel. Soll das dann heißen, dass die Funktionen delay
> und
> millis hier eine Auflösung von 2 ms haben?
Schätze mal, dass du mit dieser Annahme den Nagel auf den Kopf triffst.

---
Getestet:
delay(1) ist auch eine ms
Denn delay() verwendet intern  micros();

Beitrag #5370058 wurde von einem Moderator gelöscht.
von S. Landolt (Gast)


Lesenswert?

> Denn delay() verwendet intern  micros();

Nein, ich frage jetzt nicht, wie Arduino micros erzeugt - hier wendet 
sich der (Gast) mit Grausen.

Frohe Feiertage!

von Einer K. (Gast)


Lesenswert?

Grausen ohne Grund, ist nur halbes Grausen!

Hier ein Grund:
1
unsigned long micros() {
2
  unsigned long m;
3
  uint8_t oldSREG = SREG, t;
4
  
5
  cli();
6
  m = timer0_overflow_count;
7
#if defined(TCNT0)
8
  t = TCNT0;
9
#elif defined(TCNT0L)
10
  t = TCNT0L;
11
#else
12
  #error TIMER 0 not defined
13
#endif
14
15
#ifdef TIFR0
16
  if ((TIFR0 & _BV(TOV0)) && (t < 255))
17
    m++;
18
#else
19
  if ((TIFR & _BV(TOV0)) && (t < 255))
20
    m++;
21
#endif
22
23
  SREG = oldSREG;
24
  
25
  return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
26
}

von R. H. (breezer)


Lesenswert?

Also ist es jetzt tatsächlich so, dass die millis() Funktion bei einem 8 
MHz Arduino nur eine Auflösung von 2 ms besitzt?

Ich hätte gedacht, dass die IDE den prescaler entsprechend auf 32 
anpasst oder so...

Dann muss ich wohl mit den 2 ms leben, geht auch, wäre aber schön 
gewesen das irgendwo zu lesen, ich habe da nichts gefunden...

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

>Ich hätte gedacht, dass die IDE den prescaler entsprechend auf 32
>anpasst oder so...

Ein Blick ins Datenblatt hätte dir gezeigt, das es keinen Prescaler 
von 32 gibt.

MfG Spess

von R. H. (breezer)


Lesenswert?

spess53 schrieb:
> Ein Blick ins Datenblatt hätte dir gezeigt, das es keinen Prescaler
> von 32 gibt.

ah ok, ja dann wird ein Schuh draus, dann geht es wohl tatsächlich nicht 
anders.

Leider ist das aber gar nicht dokumentiert auf:

https://www.arduino.cc/reference/en/language/functions/time/millis/

Schade, bei der micros() Funktion steht was zu der Auflösung in 
Abhängigkeit der verwendeten Taktquelle.

von spess53 (Gast)


Lesenswert?

Hi

>Schade, bei der micros() Funktion steht was zu der Auflösung in
>Abhängigkeit der verwendeten Taktquelle.

Kann schon sein, aber ich kenne dieses Arduingeödel nicht. Aber ich 
würde dir raten Programmierung ohne dieses vorgekaute Zeugs zu lernen.

MfG Spess

von R. H. (breezer)


Lesenswert?

spess53 schrieb:
> Kann schon sein, aber ich kenne dieses Arduingeödel nicht. Aber ich
> würde dir raten Programmierung ohne dieses vorgekaute Zeugs zu lernen.
>
> MfG Spess

Sonst nutze ich auch eher STM32, aber Arduino hat auch seinen Charme.

Hier handelt es sich um eine relativ einfache Steuerungsaufgabe mit 
einigen Sensoren, da es für Arduino massig Librarys für diverse 
Sensoren/Boards gibt hat man einfach schnelle Fortschritte.

Für STM32 z.b. gibt es nicht viel und dann fängt man wieder an die 
entsprechenden Arduino Libs anzupassen was viel Zeit kostet.

von Einer K. (Gast)


Lesenswert?

R. H. schrieb:
> Dann muss ich wohl mit den 2 ms leben,

Warum?
Es gibt nicht nur COMPB sondern auch COMPA!
Damit kannst du 2 Schaltschwellen im Abstand von 0x80 definieren.
Damit bekommst du dann deine 2 Interrupts auf 2ms.
Pro 1ms einen.

von Karl (Gast)


Lesenswert?

spess53 schrieb:
> Ein Blick ins Datenblatt hätte dir gezeigt, das es keinen Prescaler
> von 32 gibt.

Ist Dir schon EINMAL ein Arduino-Nutzer begegnet, der einen Blick ins 
Datenblatt des ATmega328 geworfen hätte?

Die meisten sind schon damit überfordert, wenn Du sagst 
"AVR-Controller". Sie haben doch einen Arduino!

von S. Landolt (Gast)


Lesenswert?

>> Dann muss ich wohl mit den 2 ms leben,

> Warum?
> Es gibt nicht nur COMPB sondern auch COMPA!
> Damit kannst du 2 Schaltschwellen im Abstand von 0x80 definieren.

Wie wäre es nur mit der COMPA-ISR, und dort OCRA 'vor sich her 
schieben'? Also einfach OCR0A = OCR0A + 128.

von S. Landolt (Gast)


Lesenswert?

PS:
Das geht allerdings nur, wenn Timer0 im Normal-Modus läuft, nur dann 
(und bei CTC) gilt "Update of OCRx at 'Immediate'". Ob das hier der Fall 
ist, kann unser Arduino-Fanboy beantworten.

von Einer K. (Gast)


Lesenswert?

S. Landolt schrieb:
> Ob das hier der Fall ist, kann
> unser Arduino-Fanboy beantworten.

Könnte ich, aber wie alle anderen Arduino User auch, schau ich nie in 
irgendwelche Datenblätter.
Siehe: Beitrag "Re: Arduino Timer0 interrupt nutzen"
Nicht EINEN gibt es.

Also kann ich euch nur die Werte liefern, die bei einem 16MHz UNO in den 
Registern stehen.
TCCR0A 0x03
TCCR0B 0x03

Außerdem wird das langsam langweilig...
Denn der Arduino Core/Quellcode liegt öffentlich aus.
https://github.com/arduino/Arduino/tree/master/hardware/arduino/avr/cores/arduino
Es kann sich also jeder aus eigener Kraft allumfassend kundig machen.

//----

R. H. schrieb:
> Leider ist das aber gar nicht dokumentiert auf:
>
> https://www.arduino.cc/reference/en/language/functions/time/millis/
Wenn sich in der Arduino Welt Fehler befinden, kann man sie melden, oder 
in vielen Fällen auch selber korrigieren.
Die Arduino Welt ist in der Sache auf externe Helfer angewiesen.
Also bitte nicht auf die Doku schimpfen, sondern helfen sie besser zu 
machen.

von Einer K. (Gast)


Lesenswert?

Übrigens...
Hier wurde es schon geklärt:

Reiner_Gast schrieb:
> und die
> initalisiert den Timer0 auf den Modus "Fast PWM" (siehe Funktion init(),
> wiring.c

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.