mikrocontroller.net

Forum: Compiler & IDEs 16 Bit Timer läuft nicht an


Autor: Gizmo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Ich möchte den 16 Bit Timer des ATMEGA32 zum laufen bekommen, aber 
irgendwie springt das ding nicht an.

Der Timer soll im CTC Mode mit Prescaler 1024 arbeiten.

Hier ist mal meine Initialisierungs Routine:


void initTimer1(void)
{
  /*Prescaler 1024*/
//  TCCR1B |= (1<<CS12) | (1<<CS10);

  TCCR1A = 0x00;
  TCCR1B |= (1<<CS12); // CTC-Mode Prescale 1024 (15625)
  OCR1AH = ( (15625/5) >> 8 );
  OCR1AL = ( (15625/5) & 0x00FF );
  TIMSK |= (1<<OCIE1B);


}

Hier die Interrupt Routine:



ISR (SIG_OUTPUT_COMPARE1A)
{


  unsigned char counter;
  for(counter = 0; counter < (sizeof(time_counter_)/sizeof(unsigned 
int)); counter++)
  {
    if(time_counter_[counter] > 1) time_counter_[counter]--;
  }


  //  sprintf(led_blink_buffer, "%s\n\r" ,led_blink);
  //  usartPuts(led_blink_buffer);
  return;
}

Es wäre sehr nett, wenn ihr mir helfen könntet.


Gruß Gizmo

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gizmo wrote:
> Hier ist mal meine Initialisierungs Routine:
> [...]
>   TIMSK |= (1<<OCIE1B);
> [...]
>
> Hier die Interrupt Routine:
>
> ISR (SIG_OUTPUT_COMPARE1A)
Fällt Dir da nichts auf?

Abgesehen davon sollte man die "neuen" Vektornamen verwenden.

Und den Einzelzugriff auf die H- und L-Register mit dem ganzen 
Bitgeschiebe macht man in C auch nicht, dafür gibt es die 
16-Bit-Zugriffe, bei denen der Compiler einem auch noch die Sache mit 
der korrekten Zugriffsreihenfolge abnimmt (die bei Dir aber [zufällig?] 
korrekt ist).

Also:
OCR1A = 15625/5;

Laufen wird der Timer wohl schon, nur merkst Du nichts davon. Ich gehe 
auch mal davon aus, dass die globale Interrupt-Freigabe irgendwo anders 
gemacht wird...

Autor: Gizmo (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi Johannes

erst mal danke für die schnelle Antwort.

die globalen Interrupts werden bei mir vor der Hauptschleife
per sei() aktiviert.

ich habe mir eine Testroutine für den Timer geschrieben in der das TOV1 
Flag im TIFR Register abfrage.

Hier mal die Test Routine:

void timer1test(void)
{
/*  char timer1_overflow_buffer[50];
  char timer1_overflow_flag_set[10] = "1";
  char timer1_overflow_flag_not_set[10] = "0";*/

  if(TIFR & (1<<TOV1))
  {
    PORTB |= (1<<PORTB4);

    //sprintf(timer1_overflow_buffer, "TOV1 = %s\n\r" 
,timer1_overflow_flag_set);
    //usartPuts(timer1_overflow_buffer);
  }
  else
  {
    PORTB &= ~(1<<PORTB4);

    //sprintf(timer1_overflow_buffer, "TOV1 = %s\n\r" 
,timer1_overflow_flag_not_set);
    //usartPuts(timer1_overflow_buffer);
  }
}

diese Routine wird in der Hauptschleife aufgerufen, wird aber nie 
aufgerufen, dass heißst der Timer läuft nicht.

Wie meinst du das mit den 16-Bit Zugriffen ? Ich kenne dass nur über 
Bitschieberei. Hast da vielleicht n stück Code für mich ? das ich mir 
mal anschauen kann, wie du das machst ?

Ich hänge auch mal mein ganzes c File an.1

Autor: Werner B. (werner-b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1. Du gibt den OCIE1B Interrupt frei, aber deine ISR ist für den OCIE1A

2. Wenn der Timer im CTC Modus läuft, läuft er nie über, sondern wird 
beim Match auf 0 zurückgesetzt. Darum kann nie das TOV Flag

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Werner B. wrote:
> 1. Du gibt den OCIE1B Interrupt frei, aber deine ISR ist für den OCIE1A
Tja, eigentlich hatte ich gehofft, dass Gizmo den Hinweis in meinem 
ersten Posting versteht... War doch eigentlich ein Wink mit dem 
Zaunpfahl.

> 2. Wenn der Timer im CTC Modus läuft, läuft er nie über, sondern wird
> beim Match auf 0 zurückgesetzt. Darum kann nie das TOV Flag
Doch, schau mal in den betreffenden Tabellen im Datenblatt nach. Das TOV 
wird auch im CTC-Betrieb gesetzt.

EDIT:
Sorry, hab noch mal zur Sicherheit nachgesehen: In den CTC-Betriebsarten 
wird das TOV tatsächlich nicht gesetzt, wenn OCRnx nicht gleich MAX 
ist (nur in den PWM-Betriebsarten sieht das z.T. anders aus). Allerdings 
gebietet eigentlich allein die Logik, das Compare-Flag abzufragen...

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. wrote:

>> 2. Wenn der Timer im CTC Modus läuft, läuft er nie über, sondern wird
>> beim Match auf 0 zurückgesetzt. Darum kann nie das TOV Flag
> Doch, schau mal in den betreffenden Tabellen im Datenblatt nach. Das TOV
> wird auch im CTC-Betrieb gesetzt.

Jein. TOV wird bei MAX gesetzt, aber MAX wird gar nicht erreicht, außer 
du manipulierst den Zählerstand "von Hand". Lässt du den Zähler "in 
Ruhe" im CTC-Modus laufen, wird TOV nicht gesetzt.

Nur so nebenbei: der OP lässt den Zähler gar nicht im CTC-Modus laufen, 
auch wenn es im Kommentar steht.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst wrote:
> Jein. TOV wird bei MAX gesetzt, aber MAX wird gar nicht erreicht, außer
> du manipulierst den Zählerstand "von Hand". Lässt du den Zähler "in
> Ruhe" im CTC-Modus laufen, wird TOV nicht gesetzt.
Jupp, siehe EDIT oben...

Autor: Gizmo (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ich habe jetzt mal die sachen die euch aufgefallen sind entsprechend 
abgeändert, aber der Timer läuft immer noch nicht. Ich hänge noch einmal 
den auktuelen code an.
Was vielleicht wichtig ist der ATMEGA32 läuft mit internem Oszilator mit 
8 Mhz.

Ich danke euch

gruß Gizmo

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie soll er auch laufen, wenn du initTimer1 nicht aufrufst.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gizmo wrote:
> ich habe jetzt mal die sachen die euch aufgefallen sind entsprechend
> abgeändert,
Nö, hast Du nicht!
  OCR1AH = ( (15625/5) >> 8 );
  OCR1AL = ( (15625/5) & 0x00FF );
ist immer noch so umständlich wie vorher. Und den alten Vektornamen hast 
Du auch noch drin
ISR (SIG_OUTPUT_COMPARE1A)

Und wenn Du glaubst, die 1000 Leerzeilen in Deinem Code wecken in mir 
große Lust, mir das Programm mal genauer anzusehen, dann liegst Du 
leider falsch... Ich bin kein Masochist.

EDIT:
OK, ich sehe, Stefan hat sich tatsächlich die Mühe gemacht...

Autor: Gizmo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so der Timer läuft jetzt.
Der Fehler lag an folgender Programmzeile:

TCCR1B |= (1<<CS12) | (1<<CS10) | (1<<WGM12); // CTC-Mode Prescale
1024(15625)

man darf aber nich verodern.

so ist es richtig:
TCCR1B = (1<<CS12) | (1<<CS10) | (1<<WGM12); // CTC-Mode Prescale 1024 
(15625) richtig

der laufende Code ist im Anhang enthalten.

Das Shiften finde ich persöhnlich besser da es allgemein gehalten ist

Gruß Gizmo

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gizmo wrote:
> TCCR1B |= (1<<CS12) | (1<<CS10) | (1<<WGM12); // CTC-Mode Prescale
> 1024(15625)
>
> so ist es richtig:
> TCCR1B = (1<<CS12) | (1<<CS10) | (1<<WGM12); // CTC-Mode Prescale 1024
> (15625) richtig
Wenn das Register vorher jungfräulich ist (Reset-Zustand), dann macht 
das keinen Unterschied.

> Das Shiften finde ich persöhnlich besser da es allgemein gehalten ist
Hä??? Muss ich nicht verstehen, oder?

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.