Timer1 ( ATMega 32U4 ) zu schnell - Fehler in der Konfiguration?

#3940219
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!
#3940248
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");
}
Gast #3940302
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;
#3940303
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
Angehängte Dateien:
#3940328
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
}
#3940425
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
#3940475
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?

?!
Gast #3940513
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.
#3940520
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
#3940536
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 -
Gast #3940542
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.
#3940741
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.
#3940779
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 ;-)
#3940793
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?
Gast #3940860
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.
#3940882
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!
Gast #3940987
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.
#3940998
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?
Gast #3941053
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
}

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