Timer/Counter0 Overflow Interrupt kommt nicht

Gast #4300972
Lesenswert?
• ▲
▼
Hallo allerseits! Ich habe eine Frage bzgl des Overflow Interrupts beim 
Timer/Counter0 des ATMega324A. Ich habe den unten aufgeführten Code. Ich 
hab diesen zunächst nur mit Hilfe des Datenblatts erstellt. Dieser 
scheint mir aber korrekt, da in den Threads, die ich hier im Forum 
gefunden hab, es genauso gemacht wurde. Nun mal zur genauen 
Problembeschreibung.

Ich will Timer0 im "Phase correct PWM mode" betreiben. Gemäß des 
Datenblatts wird jedes mal wenn der Timer wieder den BOTTOM-Wert 
erreicht hat das Timer/Counter Overflow Flag gesetzt, wodurch der 
Interrupt ausgelöst werden kann. In der ISR möchte ich dann den Wert des 
OCR von Timer2 ändern. Timer2 wird im CTC Mode betrieben.

Leider passiert nichts. Die Werte ändern sich nicht und bleiben auf den 
Initialisierten Werten. Folglich wird der Overflow Interrupt des Timer0 
nicht aufgerufen. Komischerweise funktioniert aber der Compare Match 
Interrupt, wenn ich ihn für Timer0 implementiere (also TIMSK0 = 
1<<OCIE0A mit entsprechender ISR). Im AVR-Studio habe ich auch darauf 
geachtet, dass das richtige Device ausgewählt ist.

Ich wäre euch sehr denkbar, wenn Ihr mich auf Fehler hinweisen könntet 
bzw wisst, woran es liegen könnte.
1
#ifndef F_CPU
2
#define F_CPU 16000000UL // or whatever may be your frequency
3
#endif
4
 
5
#include <asf.h>
6
#include <avr/io.h>          
7
#include <avr/interrupt.h>
8
#include <stdint.h>
9

10
int main (void) {            
11
  
12
  DDRA  = 0xFF;             
13
  PORTA = 0x00;
14
  DDRB = (1<<PB3) | (1<<PB4);
15
  DDRD = (1<<PD6) | (1<<PD7);
16
  DDRC = 0xFF;
17
  PORTC = 0x00;
18
  PORTC |= (1<<PC1);
19

20

21
        // Timer0: Enable Phase correct PWM(non-inverted), prescaler = 8
22
  TCCR0A =  (1<<WGM02) | (0<<WGM01) | (1<<WGM00) | (1<< COM0A1) | (0<< COM0A0);
23
  TCCR0B = (0<<CS02) | (1<<CS01) | (0<<CS00);
24

25
  TCNT0 = 0;  //Anfangswert 0
26

27
  TIMSK0 |= 1<<TOIE0; // Enable Overflow Interrupt
28
  
29
  //Timer2: Enable CTC Mode, Toggle Compare Output at Compare Match, prescaler = 8
30
  TCCR2A =  (0<<WGM22) | (1<<WGM21) | (0<<WGM20) | (0<< COM2A1) | (1<< COM2A0);
31
  TCCR2B = (0<<CS22) | (1<<CS21) | (0<<CS20);  
32
  TIMSK2 = (1<<OCIE2A); //Enable Compare Match Interrupt
33
  
34
//Init OC-registers
35
  OCR0A = 155;
36
  OCR0B = 0;
37
  OCR2A = 79;
38
  OCR2B = 0;
39
  
40
  sei();
41
           
42
  while(1) 
43
        {  
44

45
  }                         
46
  
47
  return 0;                 
48
}
49

50
ISR (TIMER0_OVF_vect)
51
{
52
  OCR2A+=10;
53
  if(OCR2A >=254)
54
    OCR2A = 0;
55
}
Gast #4301005
Lesenswert?
• ▲
▼
Ich habe jetzt folgendes probiert:

Zur einfachen Signalgebung habe ich vor der while-Schleife einen Pin auf 
High gesetzt. In der Overflow ISR habe ich diesen dann auf Low gesetzt. 
Das funktionierte. Jedoch wird der Wert des OCR2A nicht geändert. Gibt 
es innerhalb des ATMega Zugriffsbeschränkungen, welche nicht erlauben, 
dass in einer ISR eines Timers Werte eines anderen Timers geändert 
werden können?
Gast #4301019
Lesenswert?
• ▲
▼
Wie sieht deine Hardware aus? Ein Schaltplan wäre nützlich.
Im Zweifelsfall auch ein Bild deines Aufbaus.

Kannst du denn mit Sicherheit erkennen dass dein Programm
überhaupt läuft, dass dein Prozessor einen (und den richtigen)
Clock hat?

Interessent schrieb:
> Leider passiert nichts. Die Werte ändern sich nicht und bleiben auf den
> Initialisierten Werten.

Woran erkennst du das?
Gast #4301037
Lesenswert?
• ▲
▼
Mitlesa schrieb:
> Wie sieht deine Hardware aus? Ein Schaltplan wäre nützlich.
> Im Zweifelsfall auch ein Bild deines Aufbaus.
>
> Kannst du denn mit Sicherheit erkennen dass dein Programm
> überhaupt läuft, dass dein Prozessor einen (und den richtigen)
> Clock hat?
>
> Interessent schrieb:
>> Leider passiert nichts. Die Werte ändern sich nicht und bleiben auf den
>> Initialisierten Werten.
>
> Woran erkennst du das?

Der Aufbau ist recht einfach. Ich habe die jeweiligen Pins, die ich 
benutze, an LEDs angeschlossen. Zusätzlich verwende ich ein Oszilloskop.

Dass die Werte sich nicht ändern erkenne ich am Oszilloskop. Wenn ich in 
den ISR nichts mache, bleiben die Werte ohnehin auf den initialisierten 
Werten, was ja auch so gewollt ist. Nehme ich nun in der ISR Änderungen 
der OCRx-Register vor, ändern sich die Werte weiterhin nicht. Das tritt 
allerdings nur bei der Overflow ISR auf! Ändere ich die Werte in der 
Compare Match ISR, treten die gewollten Änderungen auf.
Gast #4301139
Lesenswert?
• ▲
▼
Interessent schrieb:
> Der wird allerdings nicht viel zum lösen
> des Problems beitragen.

Ja, weil ein unvollständiger Schaltplan kein Schaltplan ist.

Und weil ein Aufbau so gestaltet sein kann dass eine
Schaltung nicht funktioniert.

Nach dem gezeigten Schaltplan kann jedenfalls nichts funktionieren.

Minimum ist eine ausreichende Stromversorgung, Abblock Kondensatoren,
und - nach deiner Frequenzinformation zu urteilen - eine Beschaltung
mit Quarz und Last-Kondensatoren.

Da man dir offensichtlich jeden Popel einzeln aus der Nase ziehen
muss bin ich draussen.
Moderator Persönliche Seite #4301149
Lesenswert?
• ▲
▼
Interessent schrieb:
> Jedoch wird der Wert des OCR2A nicht geändert.

Wodurch stellst du das fest?

Dein Timer 0 wird mit 2 MHz getaktet.  Als 8-Bit-Timer läuft er nach
128 µs über und ändert das OCR2A.  Das ist verdammt häufig.  Timer 2
läuft zu allem Überdruss mit konstant versetzter Phase zu Timer 0
über, denn er wird ebenfalls mit 2 MHz getaktet.  Damit ist bekommt er
möglicherweise sowieso nur jede zweite Änderung von OCR2A überhaupt
mit.  OCR2A wird in Zehnerschritten geändert, sodass es nach ca. 25
Änderungen wieder beim alten Wert ist, oder alle 3 Millisekunden.

Wenn du dir die LEDs mit dem Auge betrachtest, dürfte das Auge das
alles zu einer einzigen Helligkeit integrieren.  Ein Oszi wäre sicher
schnell genug, die sich ändernde Modulation zu erfassen …

Davon abgesehen:
1
  if(OCR2A >=254)
2
    OCR2A = 0;

Das wird kaum so funktionieren, wie du dir das vorstellst.  Du startest
mit 79, es werden dann schrittweise 10 addiert, bis du irgendwann bei
249 bist.  Im nächsten Schritt werden wieder 10 addiert, dann bist du
bei 3 (259 - 256), es geht weiter mit 13, 23, …, 253.  Diese
if-Bedingung greift nur sowas von selten, dass du sie genauso gut
komplett weglassen kannst.
Gast #4301192
Lesenswert?
• ▲
▼
Holger L. schrieb:
> Interessent schrieb:
>> // Timer0: Enable Phase correct PWM(non-inverted), prescaler = 8
>>   TCCR0A =  (1<<WGM02) | (0<<WGM01) | (1<<WGM00) | (1<< COM0A1) | (0<<
>> COM0A0);
>
> WGM02 befindet sich nicht in TCCR0A sondern in TCCR0B.
> Bei dem zweiten Timer ist es genau so.

Vielen Dank für den Hinweis!

Jörg W. schrieb:
> Interessent schrieb:
> Davon abgesehen:
>
>
1
>   if(OCR2A >=254)
2
>     OCR2A = 0;
3
>
>
> Das wird kaum so funktionieren, wie du dir das vorstellst.  Du startest
> mit 79, es werden dann schrittweise 10 addiert, bis du irgendwann bei
> 249 bist.  Im nächsten Schritt werden wieder 10 addiert, dann bist du
> bei 3 (259 - 256), es geht weiter mit 13, 23, …, 253.  Diese
> if-Bedingung greift nur sowas von selten, dass du sie genauso gut
> komplett weglassen kannst.

Besten Dank. Das hat mich auf den richtigen Weg gebracht!

Antwort schreiben

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.

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.