Timer1 lässt sich nicht auf 0 stellen

Gast #2539515
Hi,

Ich hab den Atmega32. Ich wollte mir eine/zwei Funktionen schreiben, die 
mir es erlauben die WCET und die BCET einer funktion oder eines 
Codesegments zu bestimmen.

Hier der Code:
1
void ETE_start(void){
2
// set the counter value to 0
3
  TCNT1L = 0; // set the low part to 0
4
  TCNT1H = 0;  // set the high part to 0
5
  USART_Transmit(TCNT1L);
6
  USART_Transmit(TCNT1H);
7
// set the prescaler s. Table 48 Datasheet
8
// 0,5µs= 1/(F_CPU/8)
9
  TCCR1B|=(1<<CS11);
10
}
11

12

13
void ETE_stop(void){
14
  uint16_t temp=0;  //auxiliary variable
15
// combine TCNT1L and TCNT1H
16
  temp=TCNT1L; //save the lower part
17
  temp|=(TCNT1H<<8); // save the higher part to the right place
18
  USART_Transmit_uint16(&temp);
19
// evaluate if it was a BCET or a WCET
20
  if (temp<BCET){
21
    BCET=temp;      // save the new BCET to the global variable
22
  }else if(temp>WCET){
23
    WCET=temp;      // save the new WCET to the global variable
24
  }  
25
  TCCR1B&=~(1<<CS11);
26
}

Leider hab ich festgestellt (mit den USART Ausgaben) das TCNT nicht auf 
0 gesetzt wird, warum ?

kann mir jemand helfen?
Michael D. schrieb:

> Bin mir grad nicht sicher über die Reihenfolge, aber was passiert wenn
> du zuerst H dann L schreibst?


Geht mir genauso. Daher überlasse ich sowas dem Compiler. Der weiß das 
nämlich

Anstelle von ...
1
void ETE_start(void){
2
// set the counter value to 0
3
  TCNT1L = 0; // set the low part to 0
4
  TCNT1H = 0;  // set the high part to 0
5

6
...
7

8
void ETE_stop(void){
9
  uint16_t temp=0;  //auxiliary variable
10
// combine TCNT1L and TCNT1H
11
  temp=TCNT1L; //save the lower part
12
  temp|=(TCNT1H<<8); // save the higher part to the right place
13
...

... dann eben
1
void ETE_start(void){
2
// set the counter value to 0
3
  TCNT1 = 0;
4

5
...
6

7
void ETE_stop(void){
8
  uint16_t temp = TCNT1;
9
...

Hat 2 Vorteile
* zum einen brauch ich mir nicht merken, wie rum es nun korrekt ist
* zum zweiten erspar ich mir das rumhampeln mit Bytes zusammensetzen
  bzw. auseinanderpfriemeln

In C ist eben weniger oft mehr :-)
Lass den Compiler für dich arbeiten!
>   USART_Transmit_uint16(&temp);

Bist du dir da ganz sicher, dass du hier eine Adresse übergeben musst?
Ungewöhnlich, da es an dieser Stelle nichts bringt einen Pointer auf 
einen uint16_t zu übergeben. Da ein Pointer sicher nicht kleiner sein 
wird, als ein uint16_t, verkompliziert das nur die Funktion, weil sie 
über einen Pointer auf den Wert zugreifen muss. Das bringt also weder 
geschwindigkeitsmässig etwas, noch ist es notwendig.
Gast
Karl Heinz Buchegger schrieb:
> Anstelle von ...void ETE_start(void){
> // set the counter value to 0
>   TCNT1L = 0; // set the low part to 0
>   TCNT1H = 0;  // set the high part to 0
>
> ...
>
> void ETE_stop(void){
>   uint16_t temp=0;  //auxiliary variable
> // combine TCNT1L and TCNT1H
>   temp=TCNT1L; //save the lower part
>   temp|=(TCNT1H<<8); // save the higher part to the right place
> ...
>
> ... dann eben
> void ETE_start(void){
> // set the counter value to 0
>   TCNT1 = 0;
>
> ...
>
> void ETE_stop(void){
>   uint16_t temp = TCNT1;
> ...

Danke für die antwort

--> war es aber nicht
Gast
> Leider hab ich festgestellt (mit den USART Ausgaben) das TCNT nicht auf
> 0 gesetzt wird, warum ?

Es kann überhaupt nur in diesen Ausgaben aus ETE_start() festgestellt 
werden:

>  USART_Transmit(TCNT1L);
>  USART_Transmit(TCNT1H);

wenn Timer1 nicht läuft, d.h. wenn z.B. zuvor ETE_stop() gelaufen ist 
und damit der Timertakt abgeschaltet wurde.

Wenn im sonstigen nicht gezeigten Programm der Timertakt angeschaltet 
wurde oder ein anderer Timertakt als CS11 abgeschaltet wurde, ist eine 
Ausgabe von TCNT1 = 0 in ETE_start() Zufall.

In ETE_stop() mit

>   USART_Transmit_uint16(&temp);

ist es Zufall, wenn eine 0 für die Kopie des TCNT1 übermittelt wird.

>   TCCR1B&=~(1<<CS11);

Am Ende von ETE_stop halte ich für eine logischen Unschönheit. Ich würde 
diese Anweisung am Anfang der Funktion machen, um den Timerzähler vor 
der Kopie an temp einzufrieren.

Insgesamt würde ich mehr Debugausgaben einbauen, um zu sehen welche 
Funktion am Ausgeben ist und in welcher Reihenfolge die Funktionen 
aufgerufen werden. Den restlichen Quellcode würde ich auf Einstellungen 
des Timertakts scannen.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.