Forum: Mikrocontroller und Digitale Elektronik Atmel AVR: Vergangene Zeit messen


von Steffo (Gast)


Lesenswert?

Hi,
ich möchte gerne beim Atmel AVR Atxmega 32A4U messen, wieviel Zeit 
zwischen zwei Punkten vergangen ist.

Mein Ansatz ist folgender:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#include <stdio.h>
5
6
#define F_CPU 2000000UL     
7
8
static volatile uint8_t overflow_counter = 0;
9
static const periode_value = 0xFFFF;
10
11
ISR(TCC0_OVF_vect)
12
{
13
  overflow_counter++;
14
}
15
16
static uint16_t get_system_clock() {
17
  if (CLK.CTRL == CLK_SCLKSEL_RC2M_gc) {
18
    return 2000000;
19
  } else if (CLK.CTRL == CLK_SCLKSEL_RC32M_gc) {
20
    return 32000000;
21
  } else if (CLK.CTRL == CLK_SCLKSEL_RC32K_gc) {
22
    return 32000;
23
  } else {
24
    // Unsupported. Please extend this function...
25
    exit(1);
26
  }
27
}
28
29
static uint16_t get_division_factor_of_TCC0() {
30
  if (TCC0.CTRLA == TC_CLKSEL_DIV1_gc) {
31
    return 1;
32
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV2_gc) {
33
    return 2;
34
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV8_gc) {
35
    return 8;
36
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV64_gc) {
37
    return 64;
38
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV256_gc) {
39
    return 256;
40
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV1024_gc) {
41
    return 1024;
42
  } else {
43
    // Unsupported. Please extend this function...
44
    exit(1);
45
  }
46
}
47
48
static double get_elapsed_time(uint16_t start, uint16_t end) {
49
  if (overflow_counter > 0) {
50
    // An overflow occurred before. Return 0xFFFF, which shall indicate, that it can't be measured how much time has been elapsed.
51
    overflow_counter = 0;
52
    return 0xFFFF;
53
  }
54
  
55
  double time_per_clock_cycle = 1.0 / get_system_clock() / get_division_factor_of_TCC0();
56
  double time_diff = end - start;
57
  double elapsed_time = time_per_clock_cycle * time_diff;
58
  
59
  return elapsed_time;
60
}
61
62
int main(void)
63
{
64
  PMIC_CTRL = PMIC_LOLVLEN_bm; /* LOW LEVEL Interrupt on */
65
  TCC0.CTRLA = TC_CLKSEL_DIV8_gc;
66
  TCC0.INTCTRLA = TC_OVFINTLVL_LO_gc;
67
  TCC0.PER = periode_value;
68
  TCC0.INTFLAGS = TC0_OVFIF_bm;
69
70
  sei();
71
  uint16_t start = TCC0_CNT;
72
  _delay_ms(200);
73
  uint16_t end = TCC0_CNT;
74
  
75
  double ellapsed_time = get_elapsed_time(start, end);
76
77
    while(1)
78
    {
79
        //TODO:: Please write your application code 
80
    }
81
}
Um meine Funktion zu testen, habe ich ein Delay von 200 ms eingebaut. 
Leider kommt beim Debuggen immer 0,09213223 sek raus.
Mache ich irgendetwas falsch?!

Danke im Voraus!

L. G.
Steffo

von Oliver S. (oliverso)


Lesenswert?

Optimierung eingeschaltet?

Oliver

von Steffo (Gast)


Lesenswert?

Ja und der Takt beträgt auch wirklich 2 MHz. :)

von Steffo (Gast)


Lesenswert?

Ist an meiner Berechnung vielleicht irgendetwas falsch?!

von Karl H. (kbuchegg)


Lesenswert?

1
  double time_per_clock_cycle = 1.0 / get_system_clock() / get_division_factor_of_TCC0();

kommt mir jetzt komisch vor.

1/SystemClock ist klar.

Aber warum nochmal durch den Division Factor dividieren?
Wenn der Faktor höher wird, zählt der Timer langsamer. Zählt der Timer 
langsamer, dann wird der Zeitbedarf für einen Zähltick des Timers 
größer.
Bei dir wird er aber durch die Division kleiner.

Schau dir halt mal die Einzelwerte an, schnapp dir Papier und Bleistift 
und kontrollier ob deine Werte plausibel sind. Was nichts bringt: Wenn 
du dieselbe Berechnung auf dem Papier noch mal machst. Du musst dir eine 
alternative Möglichkeit überlegen, wie du dir selbst anschaulich die 
Dinge erklären kannst.

  wenn der Timer mit 2Mhz getaktet wird, dann macht er in 1 Sekunde
  2 Mio Zählvorgänge.
  Hast du einen Vorteiler von 8, dann macht er nicht 2 Mio
  Zählvorgänge sondern nur 2Mio / 8 = 250000

  Bei 250000 Zählvorgängen, dauert dann einer davon 1/250000
  oder eben ausgerechnet 0.000004 Sekunden

Und genau dasselbe muss auch dein Programm für time_per_clock_cycle 
rausbringen. Und das kann man kontrollieren!


Was auch hilfreich sein kann:
Die Umkehrung rechnen. Wenn du den Timer startest, wie weit würde der in 
200ms kommen? Dann siehst du dir den start und den end Wert an und 
vergleichst mal damit.


Was überhaupt nichts bringt: Eine Berechnung über ein paar Stufen 
machen, sich die Ausgangswerte nicht ansehen, sich die Zwischenwerte 
nicht ansehen und nur rufen: Mein Endergebnis stimmt nicht, Hilfe!

Wenn dein Endergebnis nicht stimmt, dann gibt es 3(!) mögliche 
Fehlerquellen:
* das grundsätzliche Verständnis was da physikalisch passiert
  ist schon mal falsch. Eng damit gekoppelt ist der nächste
  Punkt:
* die daraus hergeleiteten Formeln sind falsch
  (wobei es da auch noch die Möglichkeit gibt, dass die Lösungsidee
   grundsätzlich schon richtig ist, und man beim Zusammenstellen
   der Formeln einen mathematischen Fehler gemacht hat.)
* die Ausgangswerte stimmen schon nicht.

Insbesondere den letzten Punkt sollte man nicht unterschätzen. Kommt 
öfter vor als man annehmen sollte.
Und grundsätzlich gilt in der Fehlersuche: Nimm nichts als gegeben an! 
Kontrolliere alles! Und sei es noch so banal. Jede einzelne Berechnung 
gilt erst mal als fehlerhaft, solange bis nahcgewiesen wurde, dass sie 
stimmt. Und zwar sowohl konzeptionell als auch von den Zahlenwerten her 
(soll ja auch Rechenfehler durch Overflows geben)

von Karl H. (kbuchegg)


Lesenswert?

Übrigens.
Ein Overflow Counter von 1 muss noch nicht heißen, dass man das Ergebnis 
mit 16 Bit nicht berechnen kann.

Wenn du den Timer bei 65533 startest und bei 2 stoppst, dann sind da 5 
Timertakte vergangen. Selbst wenn ein Overflow passiert ist. Die 
unsigned Rechnerei end - start macht das dann schon richtig.

Erst dann, wenn der Endstand größer als der Startstand ist UND noch dazu 
ein Overflow passiert ist, erst dann bist du über die 65535 drüber, die 
der Timer einmal zählt um 'rundum' zu kommen.

von Steffo (Gast)


Lesenswert?

Hallo Karl,
danke, für deine Antwort! Tatsächlich habe ich eine Klammer vergessen
Es hätte folgendermaßen heißen sollen:
1
double time_per_clock_cycle = 1.0 / (get_system_clock() / get_division_factor_of_TCC0());

Trotzdem bekam ich einen völlig unsinnigen Wert heraus.
Ich habe anschließend den Code weiter aufgebröselt und bekam bei 
system_clock einen Wert von 33920 heraus. Klar: 2 Mio. passen auch nicht 
in 16 Bit... Die Lösung war also uint32 zu verwenden.
Das Ergebnis ist nun besser, aber immernoch nicht perfekt, denn ich 
bekomme immer eine Abweichung von -100 ms und so kommt in meinem Fall 
0,1000044 sek bei einem delay von 200 ms raus.

Mein geänderter Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#include <stdio.h>
5
6
#define F_CPU 2000000UL     
7
8
static volatile uint8_t overflow_counter = 0;
9
static const periode_value = UINT16_MAX;
10
11
ISR(TCC0_OVF_vect)
12
{
13
  overflow_counter++;
14
}
15
16
static uint32_t get_system_clock() {
17
  if (CLK.CTRL == CLK_SCLKSEL_RC2M_gc) {
18
    return 2000000;
19
  } else if (CLK.CTRL == CLK_SCLKSEL_RC32M_gc) {
20
    return 32000000;
21
  } else if (CLK.CTRL == CLK_SCLKSEL_RC32K_gc) {
22
    return 32000;
23
  } else {
24
    // Unsupported. Please extend this function...
25
    exit(1);
26
  }
27
}
28
29
static uint32_t get_division_factor_of_TCC0() {
30
  if (TCC0.CTRLA == TC_CLKSEL_DIV1_gc) {
31
    return 1;
32
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV2_gc) {
33
    return 2;
34
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV8_gc) {
35
    return 8;
36
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV64_gc) {
37
    return 64;
38
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV256_gc) {
39
    return 256;
40
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV1024_gc) {
41
    return 1024;
42
  } else {
43
    // Unsupported. Please extend this function...
44
    exit(1);
45
  }
46
}
47
48
static double get_elapsed_time(uint16_t start, uint16_t end) {
49
  if (overflow_counter > 0) {
50
    // An overflow occurred before. Return 0xFFFF, which shall indicate, that it can't be measured how much time has been elapsed.
51
    overflow_counter = 0;
52
    return 0xFFFF;
53
  }
54
  uint32_t system_clock = get_system_clock();
55
  uint32_t division_factor = get_division_factor_of_TCC0();
56
  double timer_resolution = (system_clock / division_factor) - 1;
57
  double time_per_clock_cycle = 1.0 / timer_resolution;
58
  double time_diff = end - start;
59
  double elapsed_time = time_per_clock_cycle * time_diff;
60
  
61
  return elapsed_time;
62
}
63
64
int main(void)
65
{
66
  PMIC_CTRL = PMIC_LOLVLEN_bm; /* LOW LEVEL Interrupt on */
67
  TCC0.CTRLA = TC_CLKSEL_DIV8_gc;
68
  TCC0.INTCTRLA = TC_OVFINTLVL_LO_gc;
69
  TCC0.PER = periode_value;
70
  TCC0.INTFLAGS = TC0_OVFIF_bm;
71
72
  sei();
73
  uint16_t start = TCC0_CNT;
74
  _delay_ms(300);
75
  uint16_t end = TCC0_CNT;
76
  
77
  double ellapsed_time = get_elapsed_time(start, end);
78
  printf("Test, %f", ellapsed_time);
79
    while(1)
80
    {
81
        //TODO:: Please write your application code 
82
    }
83
}

Ist da noch ein Rechenfehler drin?

L. G.
Steffo

PS: Dein Absatz mit dem Overflow verstehe ich ehrlich gesagt nicht ganz, 
aber erst mal hat das korrekte Messen Priorität. :)

von Karl H. (kbuchegg)


Lesenswert?

Steffo schrieb:

> Das Ergebnis ist nun besser, aber immernoch nicht perfekt, denn ich
> bekomme immer eine Abweichung von -100 ms und so kommt in meinem Fall
> 0,1000044 sek bei einem delay von 200 ms raus.

Das könnte man auch so auffassen, dass du nicht eine Abweichung von 
-100ms hast, sondern die Hälfte des erwarteten Messergebnisses. Also ein 
Faktor 2.
Was dann die 2Mhz in Bezug zu den per Auslieferungszustand eingestellten 
1Mhz des Mega interessant macht. Auch dort gibt es einen Faktor 2.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:


> Was dann die 2Mhz in Bezug zu den per Auslieferungszustand eingestellten
> 1Mhz des Mega interessant macht. Auch dort gibt es einen Faktor 2.

Ach, das ist ja ein XMega.
Von dem weiß ich nicht, wie sich der Factory Default verhält.

Aber es wär es mir mal wert, die tatsächlich Zeitdauer und Korrektheit 
eines _delay_ms festzustellen.

von Stefano (Gast)


Lesenswert?

Du hast Recht! Bei einem delay von 300 ms, erhalte ich 150 ms und bei 
400 ms, 200 ms.
Das Problem war, dass ich F_CPU unterhalb vom include der delay.h 
definiert habe und delay.h prüft, ob F_CPU definiert wurde und falls das 
nicht der Fall ist, wird standardmäßig 1 MHz eingestellt. :-)
Ich habe das Makro jetzt einfach ganz oben definiert und gut ist.

Danke, du hast mir wirklich weitergeholfen!!! :-)

Wie war das eigentlich mit dem overflow gemeint?

>Wenn du den Timer bei 65533 startest und bei 2 stoppst, dann sind da 5
Timertakte vergangen.

Wie kommst du auf die 5 Timertakte?

L. G.
Steffo

von Karl H. (kbuchegg)


Lesenswert?

Stefano schrieb:

> Das Problem war, dass ich F_CPU unterhalb vom include der delay.h
> definiert habe

Ach Mist. Das hätte ich eigentlich sehen sollen :-)

> Wie war das eigentlich mit dem overflow gemeint?
>
>>Wenn du den Timer bei 65533 startest und bei 2 stoppst, dann sind da 5
> Timertakte vergangen.
>
> Wie kommst du auf die 5 Timertakte?

   65533, 65534, 65535,  0,  1  , 2
       |   |  |   |  |  | | | |   |
       +---+  +---+  +--+ +-+ +---+
         1      2      3   4    5


  2 - 65533   ergibt 5   (16 Bit unsigned gerechnet)

Das heißt aber auch:
Solange du sicher weißt, dass dein Timer nie öfter als 65535 mal tickt, 
brauchst du dir um Overflows keine Gedanken machen. Durch die unsigned 
Rechnerei kommt immer das richtige raus.

von Simon K. (simon) Benutzerseite


Lesenswert?

Stefano schrieb:
> Du hast Recht! Bei einem delay von 300 ms, erhalte ich 150 ms und bei
> 400 ms, 200 ms.
> Das Problem war, dass ich F_CPU unterhalb vom include der delay.h
> definiert habe und delay.h prüft, ob F_CPU definiert wurde und falls das
> nicht der Fall ist, wird standardmäßig 1 MHz eingestellt. :-)
> Ich habe das Makro jetzt einfach ganz oben definiert und gut ist.

F_CPU muss in den Projekteinstellungen definiert werden, NICHT im 
Quelltext!
Das muss so, damit jede kompilierte Datei dieses Makro zur Verfügung 
hat.

von Steffo (Gast)


Lesenswert?

Hallo Karl,

> Solange du sicher weißt, dass dein Timer nie öfter als 65535 mal tickt,
> brauchst du dir um Overflows keine Gedanken machen. Durch die unsigned
> Rechnerei kommt immer das richtige raus.

Ah, jetzt ist mir das klar, aber sicherstellen, kann ich das leider 
nicht! :-)

Hier übrigens der komplette funktionierende Code, falls den mal jemand 
braucht.
1
/**
2
 * CAUTION: 
3
 * Modify this macro, if the CPU Clock is different than defined here!!!
4
 */
5
#define F_CPU 2000000UL
6
7
#include <avr/io.h>
8
#include <avr/interrupt.h>
9
#include <util/delay.h>
10
#include <stdio.h>
11
12
static volatile uint8_t overflow_counter = 0;
13
static const uint16_t periode_value = UINT16_MAX;
14
15
ISR(TCC0_OVF_vect)
16
{
17
  overflow_counter++;
18
}
19
20
static uint32_t get_system_clock() {
21
  if (CLK.CTRL == CLK_SCLKSEL_RC2M_gc) {
22
    return 2000000;
23
  } else if (CLK.CTRL == CLK_SCLKSEL_RC32M_gc) {
24
    return 32000000;
25
  } else if (CLK.CTRL == CLK_SCLKSEL_RC32K_gc) {
26
    return 32000;
27
  } else {
28
    // Unsupported. Please extend this function...
29
    exit(1);
30
  }
31
}
32
33
static uint32_t get_division_factor_of_TCC0() {
34
  if (TCC0.CTRLA == TC_CLKSEL_DIV1_gc) {
35
    return 1;
36
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV2_gc) {
37
    return 2;
38
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV8_gc) {
39
    return 8;
40
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV64_gc) {
41
    return 64;
42
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV256_gc) {
43
    return 256;
44
  } else if (TCC0.CTRLA == TC_CLKSEL_DIV1024_gc) {
45
    return 1024;
46
  } else {
47
    // Unsupported. Please extend this function...
48
    exit(1);
49
  }
50
}
51
52
static double get_elapsed_time(uint16_t start, uint16_t end) {
53
  if (overflow_counter > 0) {
54
    // An overflow occurred before. Return 0xFFFF, which shall indicate, that it can't be measured how much time has been elapsed.
55
    overflow_counter = 0;
56
    return 0xFFFF;
57
  }
58
  uint32_t system_clock = get_system_clock();
59
  uint32_t division_factor = get_division_factor_of_TCC0();
60
  double timer_resolution = (system_clock / division_factor) - 1;
61
  double time_per_clock_cycle = 1.0 / timer_resolution;
62
  double time_diff = end - start;
63
  double elapsed_time = time_per_clock_cycle * time_diff;
64
  
65
  return elapsed_time;
66
}
67
68
int main(void)
69
{
70
  PMIC_CTRL = PMIC_LOLVLEN_bm; /* LOW LEVEL Interrupt on */
71
  TCC0.CTRLA = TC_CLKSEL_DIV64_gc;
72
  TCC0.INTCTRLA = TC_OVFINTLVL_LO_gc;
73
  TCC0.PER = periode_value;
74
  TCC0.INTFLAGS = TC0_OVFIF_bm;
75
76
  sei();
77
  uint16_t start = TCC0_CNT;
78
  _delay_ms(500);
79
  uint16_t end = TCC0_CNT;
80
  
81
  double ellapsed_time = get_elapsed_time(start, end);
82
  printf("Test, %f", ellapsed_time);
83
    while(1)
84
    {
85
        //TODO:: Please write your application code 
86
    }
87
}

Simon K. schrieb:

> F_CPU muss in den Projekteinstellungen definiert werden, NICHT im
> Quelltext!
> Das muss so, damit jede kompilierte Datei dieses Makro zur Verfügung
> hat.

Aber, wenn ich das Makro ganz oben definiere, tuts doch auch, oder 
nicht?
Wenn ich das Projektspezifisch deklariere, sehe ich die Gefahr, dass, 
falls der Code woanders verwendet wird, die Projekteinstellungen nicht 
übernommen werden. Gleiches Problem hat man, wenn der CPU-Takt geändert 
wird. Im Quelltext sieht man sofort, dass das Makro geändert werden 
muss, in den Projekteinstellungen nicht.

L. G.
Steffo

von Simon K. (simon) Benutzerseite


Lesenswert?

Steffo schrieb:
> Aber, wenn ich das Makro ganz oben definiere, tuts doch auch, oder
> nicht?
Nein, tuts nicht. Dann ist F_CPU in der Datei definiert, wo du es 
definiert hast. In allen anderen .c Dateien (Compilation Units) ist es 
nicht definiert.

> Wenn ich das Projektspezifisch deklariere, sehe ich die Gefahr, dass,
> falls der Code woanders verwendet wird, die Projekteinstellungen nicht
> übernommen werden.
Das ist doch auch gut so! Sobald du ein neues Projekt anfängst, solltest 
du ganz zu Anfang die ganzen Einstellungen für die Plattform (damit auch 
die Taktfrequenz) angeben.

> Gleiches Problem hat man, wenn der CPU-Takt geändert
> wird. Im Quelltext sieht man sofort, dass das Makro geändert werden
> muss, in den Projekteinstellungen nicht.
Wenn, dann musst du es aber in jeder Compilation Unit definieren. Und 
dann dreht sich deine Aussage sofort um (Ergo: Man sieht es eben nicht 
sofort).

Was du in deinen Code einbauen kannst ist:

#ifndef F_CPU
#error F_CPU nicht definiert

von amateur (Gast)


Lesenswert?

Du hast einen Zähler vom Typ: uint8_t installiert. Der flippt nach 
kurzer Zeit schon aus (255).

Würdest Du dich nicht besser stehen, wenn Du einen "großen" Zähler 
installierst (z.B. long) und dann deine Messungen nach folgendem Schema 
durchführst:

StartZeit = akt_Zähler();

<<Hau rein Onkel Otto;>>

Dauer = akt_Zähler() - StartZeit;

Ein Zähler, im Format long, bereitet erst nach mehreren Tagen Dauerlauf 
Probleme. Nur den atomaren Zugriff auf den Zähler musst Du 
sicherstellen.

Besser als +/- 2 Takte geht das ganze sowieso nicht. Wird aber immer der 
gleiche Zugriff verwandt, so ist die Ungenauigkeit minimiert.

von Karl H. (kbuchegg)


Lesenswert?

Steffo schrieb:

>> F_CPU muss in den Projekteinstellungen definiert werden, NICHT im
>> Quelltext!
>> Das muss so, damit jede kompilierte Datei dieses Makro zur Verfügung
>> hat.
>
> Aber, wenn ich das Makro ganz oben definiere, tuts doch auch, oder
> nicht?

Jain.

main.c
1
#define F_CPU 2000000UL
2
3
....

lcd.c
1
#define F_CPU 1000000UL
2
....


Jetzt hast du in deinem Projekt 2 C-Dateien, deren F_CPU Einstellung 
immer der Realität entsprechen müssen. Je mehr C-Dateien es werden, 
desto unangenehmer ist es sicherzustellen, dass die
a) alle den gleichen Wert haben
b) dieser Wert auch stimmt

Hast du den Wert in den Projekteinstellungen, so übernimmt ihn der 
Compiler in jede C-Datei die er kompiliert. Es ist als ob JEDE C-Datei 
am Anfang genau dieses #define hätte - d.h. du kannst per Definition 
nicht vergessen eine F_CPU Angabe zu machen. Nur dass es an einer Stelle 
zusammengezogen ist und somit in allen C-Dateien zumindest gleich ist. 
Ob der Wert stimmt ist damit noch nicht gesagt. Aber du kannst dich 
zumindest darauf verlassen, das wen du den Wert in den 
Projekteinstellungen an einer Stelle änderst und alle C-Dateien 
kompilierst, das dann alle C-Dateien die gleicher Vorstellung davon 
haben, wie hoch F_CPU ist.

> Wenn ich das Projektspezifisch deklariere, sehe ich die Gefahr, dass,
> falls der Code woanders verwendet wird, die Projekteinstellungen nicht
> übernommen werden. Gleiches Problem hat man, wenn der CPU-Takt geändert
> wird. Im Quelltext sieht man sofort, dass das Makro geändert werden
> muss, in den Projekteinstellungen nicht.

Der springende Punkt ist, dass man mit ein wenig Erfahrung als ERSTES in 
den Projekteinstellungen nachsieht.
Dort sollte eigentlich der allererste Anlaufpunkt sein. Und erst dann, 
wenn man dort nichts findet, sieht man in den Einzelfiles nach.

von Steffo (Gast)


Lesenswert?

@Karl + Simon: Danke, jetzt ist das klarer! :-)

@amateur: Ich benutze uint8 nur um zu prüfen, ob ein overflow 
stattgefunden hat. Genau genommen reicht mir dafür auch ein einziges 
Bit.

L. G.
Steffo

von Steffo (Gast)


Lesenswert?

Nochmal eine Frage:
Ich habe diesen Code in einem Beispielcode von Atmel eingebaut und 
sowohl über den Code als auch über IO-View während des Debuggens, kann 
ich TCC0.CTRLA (Clock Selection) nicht ändern. D. h., der Timer läuft 
erst gar nicht los und das delay() braucht entsprechend unendlich lange!

Weiß jemand, weshalb ich TCC0.CTRLA nicht manipulieren kann? Wurde das 
irgendwie gelockt?!

Danke im Voraus!

L. G.
Steffo

von Steffo (Gast)


Lesenswert?

sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0);
in <sysclk.h> war die Lösung!

L. G.
Steffo

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.