Forum: Mikrocontroller und Digitale Elektronik Timer1 ( ATMega 32U4 ) zu schnell - Fehler in der Konfiguration?


von Sebastian K. (bastik)


Lesenswert?

Hallo Zusammen, frohe Weinacht noch!

Zurück am heimischen Basteltisch will der Timer nicht so wie ich. Habe 
auch lange nichts mehr gemacht und mache das erstemal mit dem ATMega 
32U4 Bekanntschaft:

Fakten:
ATMega 32U4
Takt 8 MHZ
3,3 Volt

Ziel:
Takt von 0,01 Sekunden

Meine Initalisierung:

 TCCR1B = (1<<WGM12)|(1<<CS11)|(1<<CS10);// CTC Mode, OCRA, Prescaler 64
 OCR1AH = 0x04;//High Byte für den Compare Match A bei 1249
 OCR1AL = 0xE1;//Low Byte für den compare Match A bei 1249
 TIMSK1 = (1<<OCIE1A);// Output Compare Match A Intterupt Enable

Problem:
Timer läuft zu schnell...

Rechnung:
8MHz / 64 = 125kHz
1 / 125 kHz = 0,000 008s
0,000 008s * 1250 = 0,01s

Daraus würde sich meiner Meinung nach für OCR1Ax 16bit Register ein wert 
von 1249 ergeben, da ja bei 0 und nicht bei 1 angefangen wird zu zählen 
im Microkontroller, also minus 1.

Kann jemand einen Fehler erkennen, habe ich irgendwo vergesssen ein Bit 
zu setzen?

Vielen Dank und schönen Samstag!

von Sascha W. (sascha-w)


Lesenswert?

Sebastian Kreuzer schrieb:
> Fakten:
> ATMega 32U4
> Takt 8 MHZ
Quarz extern oder RC intern ?

> Problem:
> Timer läuft zu schnell...
wie viel zu schnell ?

Sascha

von Sebastian K. (bastik)


Lesenswert?

SMD Quarz mit +/- 20ppm

Wie viel kann ich nicht sagen, aber richtig zu schnell, ich würde mal 
schätzen 1/3 bis doppelt so schnell...

Ich habe mich gerade etwas mit den Werten gespielt... Ohne Ergbeniss. Es 
scheint irgendwas komplett abzuweichen.

Ich würde fast meinen, der Timer ist an einer flaschen Taktquelle 
angeschlossen. Finde aber derartiges nicht im Datenblatt...ist doch 
eigentlich ein 0815 ATMega Timer...

Die ISR lautet:

ISR (TIMER1_COMPA_vect){
  ms_temp++;
  Serial.print (ms_temp);
  Serial.print ("\n");
}

von peil (Gast)


Lesenswert?

Sebastian Kreuzer schrieb:
> Wie viel kann ich nicht sagen, aber richtig zu schnell, ich würde mal
> schätzen 1/3 bis doppelt so schnell...

Wow, Takt von 100Hz, den man nicht mal mehr an einer LED sehen könnte zu 
schätzen - Respekt. Ich schätze mal Problem an Pin 42 oder Zeile 42.

von spess53 (Gast)


Lesenswert?

hi

>TCCR1B = (1<<WGM12)|(1<<CS11)|(1<<CS10);// CTC Mode, OCRA, Prescaler 64

WGM12 und WGM11 befinden sich nicht im gleichen Register.

MfG Spess

von Uwe (Gast)


Lesenswert?

Hallo Spess,

Im Datenblatt S.132

14.10.3 Timer/Counter1 Control Register B – TCCR1B
finden wir u.a.
Bit4:0 = WGM13 WGM12 CS12 CS11 CS10

Damit ist die Timer1 CTC Konfiguration korrekt.

von Uwe (Gast)


Lesenswert?

Sebastian,

noch ein Anmerkung das OCR1A Registerpaar zu beschreiben:

Ich mache das immer so:
1
#define T1_TICK 100 // 0,01s
2
#define T1_PRESCALER 64
3
#define T1_PRELOAD (unsigned short)(1.0 * F_CPU /T1_PRESCALER /T1_TICK +.5)
4
OCR1A = T1_PRELOAD-1;

von Sebastian K. (bastik)


Angehängte Dateien:

Lesenswert?

@peil
Doch geht, Zähler mitlaufen lassen...z.b. ein Byte und schon sieht man 
schön 2,5 Sekunden und dann kann man schonmal Daumen benützen. Ich hab 
leider mein Hightech Oszi nicht da, weil Bastelkeller.

@spess53

Danke. Ich hab es im Datenblatt nochmal gecheckt... also mein Code ist 
in diesem Bezug richtig, siehe Auszug im Anhang.

für CTC Mode muss nur WGM12 gesetzt werden, welches sich im TCCR1B 
befindet

von Uwe (de0508)


Lesenswert?

Hallo Sebastian,

da wie so nicht mehr erkennen können, liegt das Problem vors. im 
weiteren Programm. Deshalb poste bitte ALLES.

von Sebastian K. (bastik)


Lesenswert?

Gerne, ich habe mitlerweile alles auskommentiert. Es funktioniert im 
Moment trotzdem nicht. Vielleicht ein paar Stunden vergehen lassen und 
nochmal frisch ans Werk gehen.

Ich benütze...Schande über mich die Arduino IDE in Verbindung mit einem 
Sparkfun ProMicro 3,3V 8 MHz

Das Programm befindet sich gerade im Aufbau und ich bin eben gerade 
dabei erstmal meine Timer usw. zu initaliseiren, also nicht wundern, 
dass es praktisch keinen code gibt:
1
#include <avr/interrupt.h>
2
#include <avr/sleep.h>
3
 
4
 //Sparkfun ProMicro 3,3V 8MHZ
5
 
6
 unsigned long ms = 0;
7
 unsigned char ms_temp = 0;
8
 unsigned long ms_send_storage = 0;
9
 
10
 void setup() {
11
   
12
  //Initalisierung des UARTs
13
  Serial.begin(9600);
14
  
15
  //Initalisierung I/0 Interrupts
16
  //EICRA = (1<<ISC10)|(1<<ISC00); // INT0 und INT1 gesetzt auf Auslösen bei jeder Veränderung
17
  //EIMSK = (1<<INT1)|(1<<INT0); // INT0 und INT1 auf enable gesetzt
18
  
19
  //Initalisierung Timer0, 
20
  //TCCR0A = (1<<WGM01); // CTC Mode Compare Match OCRA
21
  //TCCR0B = (1<<CS01)|(1<<CS00); // Prscaler 64
22
  //OCR0A = 89; // Periodendauer für T=0,00072 , muss immer neu gesetzt werden
23
  //TIMSK0 = (1<<OCIE0A); // Output Compare Match A Interrupt Enable
24
  
25
  //Initalisierung Timer1, Zustaendig für 0,01s 
26
  TCCR1B = (1<<WGM12)|(1<<CS10)|(1<<CS10);// CTC Mode, TCCR1A bleibt auf default fuer CTC Mode, OCRA, Prescaler 64
27
  OCR1A = 1249;
28
  TIMSK1 = (1<<OCIE1A);// Output Compare Match A Intterupt Enable
29
  
30
  //Initalisierung Timer3, Zustaendig für 0,001s 
31
  //TCCR3B = (1<<WGM32)|(1<<CS31)|(1<<CS30);// CTC Mode, TCCR3A bleibt auf default fuer CTC Mode, OCRA, Prescaler 64
32
  //OCR3AH = 0x00;//High Byte für den Compare Match bei 124
33
  //OCR3AL = 0x7C;//Low Byte für den compare Match bei 124
34
  //TIMSK3 = (1<<OCIE3A);// Output Compare Match A Intterupt Enable
35
  
36
  sei();//Global Interrupts erlauben
37
  
38
}
39
40
void loop() {
41
}
42
43
ISR (TIMER0_COMPA_vect){
44
  }
45
46
ISR (TIMER1_COMPA_vect){
47
  ms_temp++;
48
  Serial.print (ms_temp);
49
  Serial.print ("\n");
50
}
51
52
ISR (TIMER3_COMPA_vect){
53
}
54
55
ISR (INTO_vect){
56
}
57
58
ISR (INT1_vect){
59
}

von Sebastian K. (bastik)


Lesenswert?

Habe gerade Timer0 geteste - der macht seine Arbeit anstandslos.

von Karl H. (kbuchegg)


Lesenswert?

2 mal CS10 gesetzt?
Ist das Absicht?
1
TCCR1B = (1<<WGM12)|(1<<CS10)|(1<<CS10);

von Sebastian K. (bastik)


Lesenswert?

Ja, der Fehler ist mir aufgefallen, habe zwischendurch andere Frequenzen 
versucht und den Prescaler geändert, ist wieder geänder auf "11"

War ein fehler beim Testen, das Problam besteht aber weiterhin.

von Karl H. (kbuchegg)


Lesenswert?

Da du in der Arduino Umgebung bist:

Die Arduino Umgebung benutzt auch einen Timer für sich selbst. Hast du 
das berücksichtigt?

Grundsätzlich ist dein Timer Setup korrekt, wenn ich mir mal die Arduino 
Umgebung wegdenke und dein Mega auch wirklich mit 8 Mhz läuft.

von tictactoe (Gast)


Lesenswert?

Ist der Timer1 bei Arduino überhaupt frei verwendbar? Kann man eine 
Arduino-Software denn mit was anderem als 16MHz betreiben?

von Uwe (de0508)


Lesenswert?

Hallo,

ich nutze den atMega32u4 auf dieser Hardwarebasis

# 
http://www.ehajo.de/baus%C3%A4tze/bedrahtete-baus%C3%A4tze/atmega32u4-breakout-board.html?search=atmega32u4

Da gibt's keinen Arduino, es war nur der Atmel Bootloader installiert, 
den ich gegen den Lufa AVR109 ausgetauscht hatte.

Die CPU läuft hier mit 16MHz, man lese sich dazu das Datenblatt bzgl. 
der Nutzung der USB Device durch.

Link
# http://www.fourwalledcubicle.com/LUFA.php

von Uwe (de0508)


Lesenswert?

Hallo Sebastian,

um zu wissen, welche Hardware du nutzt, wäre es schön bestätigt zu 
bekommen,
ob so ein Arduino Leonardo nutzt:

# http://arduino.cc/en/pmwiki.php?n=Main/arduinoBoardLeonardo

Oder ein /Arduino Micro/:

# http://arduino.cc/en/pmwiki.php?n=Main/arduinoBoardMicro

von Sebastian K. (bastik)


Lesenswert?

Danke für die vielen Antworten.

Ich benütze dieses Board:

https://www.sparkfun.com/products/12587

Es ist ein weitverbreiteter LEONARDO Nachbau von Sparkfun, ziehmlich 
groß in US. Haben schöne Breakouts...

...mh Arduino Leo/Micro ... Jetzt bin ich selbst etwas verwirrt - ob es 
nun ein Micro ist oder Leonardo. Ich denke wichtig ist es, dass ich in 
der IDE das richtige Board angewählt habe - Check passt ( Sparkfun Micro 
Pro 3,3 8 MHz )
Und, dass es ein 32U4 ist. Es ist ein wenig rätselhaft, der Timer0 macht 
sein ding ja wie er soll, schön brav.

Ich werde mir die Datenblatt-Passage nochmal ausdrucken. Vll doch etwas 
überlesen.

?!

Also, dass der Arduino Bootloader irgendwelche Hardware nach dem Upload 
der Software occopiert... wäre mir sehr neu. Hab früher auch "normal" 
ohne Bootloader gearbeitet. Diese kleinen Dinger sind aber doch äußert 
praktisch. Ist das erste Mal, dass ich Probleme habe. Habe mir unter 
anderem auch Arduino ausgesucht, weil man da in C direkt programmieren 
kann und nicht auf irgendeine Sprache ausweicht die es vll bald nicht 
mehr gibt.

Also wo wäre das zu lesen, das Timer1 belegt ist von Arduino?

?!

von Uwe (de0508)


Lesenswert?

Hallo Sebastion,

wo man die Frage welcher Timer Aduino nutzt findet ?
Nun im großen Netz über eine Suchmachine.

Gefunden habe ich:

http://arduino-info.wikispaces.com/Timers-Arduino

von isidor (Gast)


Lesenswert?

Sebastian Kreuzer schrieb:
> Also wo wäre das zu lesen, das Timer1 belegt ist von Arduino?

Die Gretchenfrage ist doch ob du nur den Bootloader der Arduino IDE
benutzt oder dein Projekt unter der Arduino IDE compilierst.

Im letzteren Fall bekommst du ja den DAU Code untergejubelt der
dir eine Loop() Funktion zur Verfügung stellt die (höchstwarscheinlich)
über eine ISR und dem dazu notwendigen Timer angesteuert wird.

von Sebastian K. (bastik)


Lesenswert?

Gelöst!

Es ist wohl wirklich eine Kombination, hier eine !Idee! - kein Wissen:

1) Wird der Timer verwendet - Jein

Später nach dem laden des Programm "Sketch" kann der Timer ganz normal 
verwendet werden! Aber scheinbar stehen die Register nicht mehr im 
Default-Mode wie im Datenblatt.

Deshalb ist es nötig !auch! TCCR1A auf "0" zu setzen, obwohl sich dieses 
eigentlich in diesem Zustand befinden sollte.

2) Wie gesagt eine Idee die sich auf Arduino und C bezieht.

3 Der Timer funktioniert nun korrect:
1
//Initalisierung Timer1, Zustaendig für 0,01s 
2
 TCCR1A = 0;
3
 TCCR1B = (1<<WGM12)|(1<<CS11)|(1<<CS10);// CTC Mode, TCCR1A bleibt auf default fuer CTC Mode, OCRA, Prescaler 64
4
 OCR1A = 1249;
5
 TIMSK1 = (1<<OCIE1A);// Output Compare Match A Intterupt Enable

von Sebastian K. (bastik)


Lesenswert?

Vielen Dank an Alle nochmal!

von isidor (Gast)


Lesenswert?

Sebastian Kreuzer schrieb:
> Später nach dem laden des Programm "Sketch" kann der Timer ganz normal
> verwendet werden!

Und woher soll dann die Loop() Funktion ihren Aufruf bekommen?

von Sebastian K. (bastik)


Lesenswert?

@isidor

Schreib mir bitte mal,wo Du das gelesen hast, dass Loop() über den 
Timer1 ausgelöst wird?
Würde das gerne nachlesen...kanns mir gerade nicht Vorstellen.

Ich denke Loop() wir über eine ganz normale Schleife aufgerufen.

Ich kann nur sagen funtkioniert jetzt alles super. Wenn Loop nicht 
aufgerufen werden würde, würde mein Test mit dem Timer nicht 
funktionieren, da ich in der Loop funtkion den Takt zu 100 addiere und 
dann mir jede Sekunde eine Nachricht senden lasse...

Werde das auch später posten -

von chris (Gast)


Lesenswert?

isidor schrieb:
> Und woher soll dann die Loop() Funktion ihren Aufruf bekommen?

loop() wird nicht timergesteuert aufgerufen

Im Hintergrund dürfte das nicht viel anders aussehen als so:
1
int main()
2
{
3
   setup();
4
   
5
   while(1)
6
   {
7
      loop();
8
   }
9
}

von isidor (Gast)


Lesenswert?

Sebastian Kreuzer schrieb:
> Schreib mir bitte mal,wo Du das gelesen hast, dass Loop() über den
> Timer1 ausgelöst wird?

Hab ich mir nur so vogestellt. Ich meinte es müsste über einen
Timer ausgelösst werden (nicht zwingend den Timer1), da ausser
einer ISR im Hintergrund für das Arduino-"Betriebssystem" keine
Möglichkeit besteht kurzzeitig die Kontrolle zu übernehmen und
die Loop() aufzurufen. Sonst hat ja der User die volle Kontrolle
mit seinem Programm.

Sorry für meine "Schätzung" wenn das zu unbefriedigend ist.

von Karl H. (kbuchegg)


Lesenswert?

isidor schrieb:
>
> Hab ich mir nur so vogestellt. Ich meinte es müsste über *einen*
> Timer ausgelösst werden (nicht zwingend den Timer1), da ausser
> einer ISR im Hintergrund für das Arduino-"Betriebssystem" keine
> Möglichkeit besteht kurzzeitig die Kontrolle zu übernehmen und
> die Loop() aufzurufen. Sonst hat ja der User die volle Kontrolle
> mit seinem Programm.

Das Arduino "Betriebssystem" besteht aus nicht viel mehr als einem 
Systemtakt, der die Uhr fuer zb millis() antreibt. Dafuer allerdings 
braucht es einen Timer.

von Sebastian K. (bastik)


Lesenswert?

Ich will mich jetzt nicht zu sehr aus dem Fenster lehnen aber ich bin 
auch der Meinung von Chris ( Gast ).

Soweit ich das richtig verstehe, gibt es die Arduino IDE die die 
Hex-Datei über einen eigenen Bootloader, der in einem speziellen bereich 
des uC hinterlegt ist die HEX-Datei in den vorgesehenen Teil des 
Speichers für das "Programm" des uC.

Auf gar keinen Fall zu vergleichen mit einem Art Betriebssystem, ueber 
den Bootloader wird der Code bloß weiter gereicht zu dem Ort an den er 
soll. Danach hat der Bootloader nichts mehr zu melden bzw. occupiert 
keine Resourcen des uC.

Aber gefährliches Halbwissen eventuell, ich lese das nochmal nach - 
alles lange her seitdem ich mich damit befasst habe.

"
Hallo Sebastion,

wo man die Frage welcher Timer Aduino nutzt findet ?
Nun im großen Netz über eine Suchmachine.

Gefunden habe ich:

http://arduino-info.wikispaces.com/Timers-Arduino

"

Der angegeben Link beschreibt Timer die benötigt werden um z.B. einen 
Servo anzusteuern. Aber wenn man diese Funktion, die von der Arduino 
amgebung bereit gestellt ist nicht aufruft wird der Timer dafür auch 
nicht benötigt und ist "frei".

Lieben Gruß an alle, bin jetzt einfach froh das es funktioniert ;-)

von Joachim B. (jar)


Lesenswert?

Sebastian Kreuzer schrieb:
> Also wo wäre das zu lesen, das Timer1 belegt ist von Arduino?

der war frei wer Servo nicht benutzt, habe ich selber rausgefunden weil 
mein Proggi bei Portierung von AVR Studio 4.18 nach Arduino einfach so 
funktionierte

Sebastian Kreuzer schrieb:
> Der angegeben Link beschreibt Timer die benötigt werden um z.B. einen
> Servo anzusteuern.

der Link war nützlich, nun weiss ich wenigstens warum :-)
Timer 0 war für IRMP leider zu kurz
Stress hatte ich als ich auf den Arduino Clone mit m1284p umstieg und 
dort die im Timer1 auch die PWM liegt (mein Wissen um all diese 
Verknüpfungen sind auch noch begrenzt), aber da der Timer3 beim m1284p 
frei und auch 16 Bit breit ist, war es ein leichtes den zu nehmen.

Sebastian Kreuzer schrieb:
> bin jetzt einfach froh das es funktioniert

was war es nun genau?

von isidor (Gast)


Lesenswert?

Karl Heinz schrieb:
> Das Arduino "Betriebssystem" besteht aus nicht viel mehr als einem
> Systemtakt, der die Uhr fuer zb millis() antreibt. Dafuer allerdings
> braucht es einen Timer.

Aus dem Blink-Minimalbeispiel der Arduino IDE folgerte ich dies.
Denn die Loop() Funktion wird im Beispiel (ich habe nachgesehen)
nicht durch den User aufgerufen, also muss es "aus dem Hintergrund"
passieren.

Ich habe in meinem Beitrag schon ganz bewusst "Betriebssystem"
und nicht Betriebssystem geschrieben.

von isidor (Gast)


Lesenswert?

chris schrieb:
>
> Im Hintergrund dürfte das nicht viel anders aussehen als so:

Das wäre ja dann der "Vordergrund" .....

chris schrieb:

> loop() wird nicht timergesteuert aufgerufen

Im Übrigen: sie einige Zeilen weiter oben.

von Sebastian K. (bastik)


Lesenswert?

@isidor

Also folgern klappt meistens doch nicht... Halte es für nicht richtig, 
da ich in all der Lektüre darüber nie etwas gelesen hat und es auch 
nicht logisch wäre ( für mich ). Siehe meinen Post oben. Also bis auf 
Gegenbeweis...halt ich an meiner These fest ;-)

@Joachim:

Falsch:
1
TCCR1B = (1<<WGM12)|(1<<CS11)|(1<<CS10);// CTC Mode, OCRA, Prescaler 64
2
OCR1A = 1249;// 0,01s
3
TIMSK1 = (1<<OCIE1A);// Output Compare Match A Intterupt Enable
Richtig:
1
TCCR1A = 0;
2
TCCR1B = (1<<WGM12)|(1<<CS11)|(1<<CS10);// CTC Mode, OCRA, Prescaler 64
3
OCR1A = 1249;// 0,01s
4
TIMSK1 = (1<<OCIE1A);// Output Compare Match A Intterupt Enable

Man muss TCCR1A mit 0 beschreiben!

von Sascha W. (sascha-w)


Lesenswert?

wird der Timer vielleicht im Bootloader genutz?

Sascha

von Uwe (de0508)


Lesenswert?

Hallo Joachim

die Frage ist natürlich warum sollte man das machen?
1
TCCR1A = 0;

Was steht im Datenblatt dazu ?
PS ich weis es..

von Ratgeber (Gast)


Lesenswert?

Uwe S. schrieb:
> die Frage ist natürlich warum sollte man das machen?
> TCCR1A = 0;
> Was steht im Datenblatt dazu ?
> PS ich weis es..

Lesen bildet:

Sebastian Kreuzer schrieb:
> Aber scheinbar stehen die Register nicht mehr im
> Default-Mode wie im Datenblatt.
>
> Deshalb ist es nötig !auch! TCCR1A auf "0" zu setzen, obwohl sich dieses
> eigentlich in diesem Zustand befinden sollte.

von Uwe (de0508)


Lesenswert?

Ratgeber schrieb:
> Lesen bildet:
>
> Sebastian Kreuzer schrieb:
>> Aber scheinbar stehen die Register nicht mehr im
>> Default-Mode wie im Datenblatt.
>>
>> Deshalb ist es nötig !auch! TCCR1A auf "0" zu setzen, obwohl sich dieses
>> eigentlich in diesem Zustand befinden sollte.

Danke hatte ich nicht gesehen.

Die Frage bleibt aber, was (be-)schreibt Timer1 und warum?

von tictactoe (Gast)


Lesenswert?

Sebastian Kreuzer schrieb:
> Ich denke Loop() wir über eine ganz normale Schleife aufgerufen.

Leute, ist das wirklich sooo schwierig? Die Anzahl der Dateien des 
Arduino-IDE ist endlich. Da wird sich doch die richtige Datei finden 
lassen.
1
$ cat /usr/share/arduino-1.0.6/hardware/arduino/cores/arduino/main.cpp
2
...
3
int main(void)
4
{
5
        __dummy_to_workaround_binutils_2_22_bug++;
6
        init();
7
8
        initVariant();
9
10
#if defined(USBCON)
11
        USBDevice.attach();
12
#endif
13
14
        setup();
15
    
16
        for (;;) {
17
                loop();
18
                if (serialEventRun) serialEventRun();
19
        }
20
        
21
        return 0;
22
}

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.