Forum: Mikrocontroller und Digitale Elektronik Attiny 45, fällt Timer1 der Optimierung zum Opfer?


von A. F. (elagil)


Angehängte Dateien:

Lesenswert?

Hallo,

ich möchte mithilfe des Timer1 einen Pin ein- und ausschalten, immer 
dann, wenn der Zähler 200 überschreitet.

Ich verwende einen Attiny45 (Fuses: (low)E2 (high)DF (extended)FF)  mit 
der "neuesten" Winavr-Version, avrdude 5.10, und dem angehängten 
makefile.

Dieser Code funktioniert:
1
#include <avr/io.h>
2
3
int main(void)
4
{
5
6
  DDRB |= (1 << PB0)
7
8
  TCCR1 |= (1 << CS10) | (1 << CS11) | (1 << CS13);
9
10
  while(1)
11
  {
12
    asm volatile("NOP");
13
    if(TCNT1 > 200)
14
    {
15
      PORTB ^= (1 << PB0);
16
    TCNT1=0;
17
    }
18
  }
19
}


Bei diesem Code schaltet PB0 nicht! Die if-Klammer wird nie ausgeführt.
1
#include <avr/io.h>
2
3
int main(void)
4
{
5
6
  DDRB |= (1 << PB0);
7
8
  TCCR1 |= (1 << CS10) | (1 << CS11) | (1 << CS13);
9
10
  while(1)
11
  {
12
    if(TCNT1 > 200)
13
    {
14
      PORTB ^= (1 << PB0);
15
    TCNT1=0;
16
    }
17
  }
18
}

woran kann das liegen?

danke im voraus,
adrian

von Helmut (Gast)


Lesenswert?

Hallo Adrian,
es gibt wohl zwei Möglichkeiten:
 1)der compiler erzeugt im zweiten Fall Code bei dem nicht nur das NOP
   fehlt sondern auch die Abfrage anders oder gar wegoptimiert ist.
 2)im zweiten Fall fehlt tatsächlich NUR das nop.
   Dann ist der Unterschied beider Codes nur das Timing der Abfrage
   des Timers.
   Vielleicht ist es nicht erlaubt, das Timerregister so kurz
   hinteinander abzufragen.
   Vielleicht wird aber auch nicht wirklich das Timerregister
   gelesen sondern ein Zwischenregister in das der Prozessor
   bei Gelegenheit den aktuellen Inhalt des Timerregisters
   hineinschreibt.
   Normalerweise kann das immer dann passieren wenn gerade weder
   auf das Timerregister noch auf das Zwischenregister zugegriffen
   wird. Vielleicht passiert hier die Aktualisierung des
   Zwischenregisters nie weil das Programm immer dann zugreift wenn
   sonst aktualisiert worden wäre.
   Steht dazu etwas im Datenblatt?

In jedem Fall musst du dir den jeweils erzeugten Assemblercode ansehen.

Viel Erfolg!

Helmut

von Oliver (Gast)


Lesenswert?

Helmut schrieb:
> Vielleicht...

Nö. Bestimmt nicht.

Helmut schrieb:
> In jedem Fall musst du dir den jeweils erzeugten Assemblercode ansehen.

So ist es.

Oliver

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.