Forum: Compiler & IDEs Problem mit Timer0 am ATTiny26!


von Bernd E. (edi)


Lesenswert?

Hallo,
ich versuche gerade den Timer0 am ATTiny 26 zum laufen zu bringen, aber 
irgendwo scheint der Wurm drinnen zu sein und ich find den Fehler 
einfach nicht!

Hier Ausschnitte aus meinem Code:


ISR(TIMER0_OVF0_vect)
{
   PORTB |= (1 << PINB6);

   /* reset current timer value */
   TCNT0=0;
}

void init_timer0(void)
{
  /* clear timer if timer value matches compare value. */
  /* CTC Mode in Register TCCR0*/
  /* set clock divider to "1024" at position CS00..02 */
  TCCR0=(1<<CS02) | (1<<CS00);

  /* compare value 0xFF (=255, 4*10^6Hz/(1024*(255+1))=15,25 Hz)*/

  /* enable compare interrupt in the interrupt mask register */
  TIMSK=(1<<TOIE0);

  /* reset current timer value */
  TCNT0=0x00;
}

int main(void)
{
    DDRA = 0xF0;  //PIN 0...3 -> Input, PIN 4...7 -> Output
    PORTA = 0x0E;
    DDRB = 0x48;

    lcd_init(LCD_DISP_ON);
    init_timer0();
    init_timer1();
    lcd_gui_enterkey();
    sei();

    for (;;) {}

von johnny.m (Gast)


Lesenswert?

Das ist ein völliges Durcheinander! Wenn Du den Timer im CTC-Modus 
betreibst, musst Du auch den Compare-Interrupt benutzen und nicht den 
Overflow-Interrupt! Außerdem setzt sich der Timer im CTC-Modus selbst 
zurück (das ist ja die Grundidee dabei...). Das TCNT0 = 0; in der ISR 
ist also völlig überflüssig. Ich fürchte, Du hast da einige Dinge noch 
nicht richtig verstanden. Schau Dir mal die Timer-Beschreibung im 
Datenblatt und auch mal die entsprechenden Abschnitte im 
AVR-GCC-Tutorial an.

von johnny.m (Gast)


Lesenswert?

OK, jetzt sehe ich das ganze Ausmaß der Verwirrnis... Bitte sorge dafür, 
dass der Kommentar auch zum Code passt! Das stimmt alles vorne und 
hinten nicht. Im Kommentar schreibst Du, der Timer liefe im CTC-Modus, 
was er nach der Initialisierung definitiv nicht tut. Außerdem ist der 
Timer auch nach einem Overflow 0, weshalb hier das Nullsetzen von TCNT0 
in der ISR genauso unsinnig ist.

von Bernd E. (edi)


Lesenswert?

Hi,
sorry für die Kommentare, habe sie aus meiner Timer Init vom 128iger 
übernommen und noch nicht fertig angepaßt!

Ich muss beim Tiny26 leider die ISR mit Overflow machen, da es beim 
Timer0 keine TIMER_CMP_vect gibt! Beim TCNT0 war ich mir nicht sicher, 
ob ich das wieder einstellen muss um den Timer neu zu starten, hatte es 
auch schon ohne der Zeile probiert, aber ging eben auch nicht!

von johnny.m (Gast)


Lesenswert?

Ach, und was genau funktioniert jetzt nicht? "Wurm drin" ist nicht 
wirklich ne Aussage. ("...nur wenn er ganz ruhig liegen bleibt, dann ist 
der Wurm drin...")...

Info über Taktfrequenz wäre auch nicht ganz verkehrt...

von Karl H. (kbuchegg)


Lesenswert?

Und schmeiss mal alles Überflüssige raus.

Wenn du ein Problem mit dem Timer hast (oder vermutest),
dann braucht kein Mensch ein LCD oder einen Aufruf der
Funktion lcd_gui_enterkey(). Woher weist du eigentlich
dass der µC nicht in lcd_gui_enter_key() hängen bleibt
und als Folge davon sei() nie ausgeführt wird? Eben.

von Bernd E. (edi)


Lesenswert?

Hi,
das Problem ist, dass die LED nie leuchtet, daher vermute ich mal, dass 
die Timer ISR nicht aufgerufen wird!

Am LCD sollte es nicht liegen, denn wenn ich die LED in der for Schleife 
aktiviere, dann funktioniert sie, also sollten die Funktionen oben schon 
funktionieren, habe sie auch schon bei anderen Programmen verwendet!

von johnny.m (Gast)


Lesenswert?

Aah, interessant. So nach und nach kommen ja mal ein paar 
Informationen... Du hast also eine LED an PORTB.6 hängen. Und wie ist 
die angeschlossen? Low-Side oder High-Side? Und bitte teil uns doch 
ENDLICH mal mit, bei welcher Taktfrequenz der µC läuft! Oder liest Du 
die Postings gar nicht? Ist das denn so schwer?

von Bernd E. (edi)


Lesenswert?

Hi,
die Taktfrequenz steht eigentlich schon in meinem ersten Posting, bei 
der Berechnung, sind 4MHz!

Das die LED an Port B6 hängt sollte eigentlich auch klar sein, steht 
nämlich auch in Quellcode erstes Posting!

Die LED geht gegen Masse.

von johnny.m (Gast)


Lesenswert?

> die Taktfrequenz steht eigentlich schon in meinem ersten Posting, bei
> der Berechnung, sind 4MHz!
Da der Rest Deines Kommentars nichts mit der Realität zu tun hatte, 
warum sollte die Zeile stimmen?

> Das die LED an Port B6 hängt sollte eigentlich auch klar sein, steht
> nämlich auch in Quellcode erstes Posting!
Dreist gelogen! Von einer LED war nirgends die Rede!

Und meine letzte Frage, wie die LED denn nun angeschlossen ist, hast Du 
immer noch nicht beantwortet! Warum muss man Dir alles einzeln aus der 
Nase ziehen?

von Bernd E. (edi)


Lesenswert?

Hi,
sorry war nicht so gemeint, bin nur schon etwas abgenervt weil das Zeug 
nicht funktioniert.

Wegen der LED versteh ich immer noch nicht ganz, was du meinst, ich hab 
sie wie oben schon geschrieben vom uC über einen 150R Widerstand auf 
Masse gelegt, also leuchtet, wenn 5V am Ausgang des uC anliegen, 
ansonsten nicht.

von Karl H. (kbuchegg)


Lesenswert?

OK.
So direkt sehe ich in deinem Program nichts grundsätzlich
falsches.

ISR haben aber die Eigenart, dass der Compiler nicht alle
Fehler in der Deklaration zuverlässig meldet. Also
wird wohl nichts anderes übrig bleiben als dass du ein
komplettes, möglichst einfaches, Programm postest, dass
wir mal compilieren und entweder auf die reale Hardware
oder in den Simulator stecken können.

von Bernd E. (edi)


Lesenswert?

Hab vorhin festgestellt, dass das Problem nicht beim Timer0 sondern beim 
Timer1 liegt, mach ich init_timer1 weg, dann funktioniert der Timer0.

Möchte mit dem Timer 1 ein PWM Signal auf einer LED an PB3 ausgeben.

ISR(TIMER1_CMPB_vect)
{
  OCR1B = adc_wert;
}

void init_timer1(void)
{
  /* COM1A1:0 COM1A0:0 -> beide Null, um den Output auf COM1A zu 
deaktivieren*/
  /* COM1B1:1 COM1B0:0 -> OC1B toggle output line */
  /* FOC1B:1 Force Output Compare Match 1B */
  /* PWM1B:1 -> enables PWM mode based on comparator OCR1B */
  TCCR1A |= (1 << COM1B0) | (1<< FOC1B) | (1 << PWM1B);

  /* CS13:0 CS12:1 CS11:1 CS10:0 -> set Prescaler to 32*/
  TCCR1B |= (1 << CS12) | (1 << CS11);

  /* Compare register */
  OCR1B=0x00;

  /* enable compare interrupt in the interrupt mask register */
  TIMSK = (1 << OCIE1B);

  /* reset current timer value */
  //TCNT1=0x00;
}

von johnny.m (Gast)


Lesenswert?

> ISR(TIMER1_CMPB_vect)
Wenn das in Deinem Source auch so steht, dann dürfte jedes Auftreten des 
Timer 1-Compare-Interrupts zu einem Reset führen. Der Vektor heißt 
TIMER1_COMPB_vect. Bei Dir fehlt ein "O"! Das müsste allerdings eine 
Compiler-Warnung gegeben haben. Nur lesen viele Leute die Warnungen 
einfach nicht. Und wenn Du gleich zu Anfang das komplette Programm 
gepostet hättest, wäre einigen Leuten hier viel Arbeit erspart 
geblieben!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

johnny.m wrote:

>> ISR(TIMER1_CMPB_vect)

> Wenn das in Deinem Source auch so steht, dann dürfte jedes Auftreten des
> Timer 1-Compare-Interrupts zu einem Reset führen. Der Vektor heißt
> TIMER1_COMPB_vect.

Nein, nicht beim ATtiny26.  Beklag dich bei Atmel über die Benennung
(Datenblatt, Tabelle 29 bzw. auch ATtiny26.xml, Pfad
/AVRPRART/INTERRUPT_VECTOR/VECTOR4/SOURCE/).

von johnny.m (Gast)


Lesenswert?

Upps, heißt der echt anders? Naja, ist ja glaub ich nicht der einzige 
Fall von unlogischen Bezeichnungen...

von johnny.m (Gast)


Lesenswert?

@Bernd:
Schick doch bitte mal das komplette Programm! Keine aus dem Kontext 
gerissene Schnipsel. Sonst kann man da wirklich nicht mehr zu sagen. 
Nach dem, was Du bisher hier preisgegeben hast, gibt es für mich keinen 
erkennbaren Grund, warum Timer 0 nicht funktioniert, wenn Timer 1 läuft.

von Uwe N. (ulegan)


Lesenswert?

Da steht also sowas im Programm?

void init_timer0(void)
{
 ...
  /* enable compare interrupt in the interrupt mask register */
  TIMSK=(1<<TOIE0);
 ...
}

void init_timer1(void)
{
 ...
  /* enable compare interrupt in the interrupt mask register */
  TIMSK = (1 << OCIE1B);
 ...
}

Wie sieht den nun der Inhalt von TIMSK nach dem Aufruf von init_timer1() 
aus ? Welche Interrupts sind enabled ?

von Bernd E. (edi)


Lesenswert?

Hi,
dieses Problem hab ich schon behoben, danke!

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.