mikrocontroller.net

Forum: Compiler & IDEs Problem mit Timer0 am ATTiny26!


Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht 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 (;;) {}

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht 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;
}

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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/).

Autor: johnny.m (Gast)
Datum:

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

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Uwe Nagel (ulegan)
Datum:

Bewertung
0 lesenswert
nicht 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 ?

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
dieses Problem hab ich schon behoben, danke!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.